面試題:前端文件上傳
一:基本回答
前端使用type為file的input的纳胧,以及formData司顿,將文件通過ajax傳給后端秀撇。
二:進階之文件切片
將文件分為若干個小塊脐恩,然后依次上傳抡秆,后端接受完所有文件后再合并奕巍。
相較于上面的優(yōu)點是可以斷點續(xù)傳和秒傳,切片后每個小塊通過md5計算其唯一的hash值儒士,上傳時都問后端校驗下的止,是否存在該塊,不存在才上傳着撩,如果整個文件都存在的話那就是秒傳了诅福。
三:進階之優(yōu)化計算hash
切片后每個小塊計算hash較耗費時間匾委,此時頁面就會卡住,影響用戶體驗氓润,解決方法有:
- webworker赂乐,開一個子進程去計算hash,主線程只需要等待其完成的通知即可咖气,計算量沒有減少挨措,但主線程不卡頓;優(yōu)點是邏輯簡單采章,缺點是增加了網(wǎng)絡請求运嗜;
- time-slice,時間切片悯舟,利用瀏覽器空閑時間去計算hash担租,不影響延遲瀏覽器的關鍵事件,如動畫和輸入響應等抵怎,原理是瀏覽器的requestIdleCallback方法奋救;優(yōu)點是效率比webworker的高,更細膩反惕,缺點是requestIdlecallback該api有兼容問題尝艘,自己實現(xiàn)較為復雜,可參考react的fiber架構(gòu) 姿染;
- 抽樣hash背亥,也就是不把小塊的全部文件去做全量hash,而是抽取其前中后兩個字節(jié)悬赏,共6個字節(jié)去計算hash(大概思路狡汉,細節(jié)還要更復雜);犧牲一些命中率闽颇,換取時間盾戴;可以結(jié)合上面兩種方法使用;
三:進階之優(yōu)化大量請求
切片后增加了上傳文件的請求數(shù)量兵多,需要控制請求的并發(fā)數(shù)以及失敗重試尖啡;
至于判斷每個小塊是否存在的請求,可以只需要一個剩膘,后端返回已經(jīng)存在的文件hash的數(shù)組衅斩,之后的判斷無需一個個請求;
四:進階之慢啟動策略
解決的是分片到底分多大的問題怠褐,不能寫死為1m或是200kb矛渴,需要根據(jù)當前網(wǎng)絡情況,動態(tài)調(diào)整切片大小數(shù)惫搏,參考TCP的慢啟動策略具温;
具體為,假設理想是每30s上傳一個區(qū)塊筐赔,區(qū)塊初始大小為1m铣猩,如果上傳只用了10s,則下一個區(qū)塊大小為3m茴丰;如果花了60s达皿,則下一個區(qū)塊變成500kb;以此類推贿肩,由于網(wǎng)速波動峦椰,區(qū)塊大小需要一直判斷;
更多優(yōu)化點
- 碎片清理汰规,定期清理服務器過期的碎片文件
- requestIdleCallback兼容性汤功,如何自己實現(xiàn)一個
- 并發(fā)+慢啟動配合
- 抽樣hash+全量量哈希+時間切片配合
- 慢啟動的變化應該更更平滑,比如使用三?角函數(shù)溜哮,把變化率平滑的限制在0.5~1.5之間
- websocket推送進度
- 文件碎片分機器?存儲
- 文件碎片備份
- 體驗優(yōu)化滔金,如上傳的進度條、離開頁面的提醒茂嗓、拖拽上傳餐茵、粘貼上傳等
......
【自己的感悟之 學習的慢啟動】
從小的任務開始,能夠順利地完成述吸,再加大任務忿族,不要一開始就搞個大的任務,高的期望反而卡住了蝌矛,那就一點都沒有完成道批。
后續(xù)還需要自己用代碼全部實踐一遍,以及運用的項目中
整理于 開課吧-大圣老師的2020.2.7號直播
ps:晚上看到煎蛋站長 染新冠肺炎發(fā)文交代后事--諸君朴读,我可能感染了新冠肺炎 屹徘,后檢查發(fā)現(xiàn)不是,替他感到高興衅金,白嫖黨第一次打賞十塊噪伊,有5000+的人打賞,如此近距離的直面死亡氮唯,又回到人間鉴吹,會有一些什么樣的感悟呢?