這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 業務場景: 產品有個功能是設置主題。類似手機自動切換壁紙,以及其他功能顏色,icon,字體等。 管理員需要在後端管理系統多次下載不同主題,(至於要幹啥就不說了...),主題中可能有 30 ~ 100個高清壁紙, icon 等。現在每次下載 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
業務場景:
產品有個功能是設置主題。類似手機自動切換壁紙,以及其他功能顏色,icon,字體等。
管理員需要在後端管理系統多次下載不同主題,(至於要幹啥就不說了...),主題中可能有 30 ~ 100個高清壁紙, icon 等。現在每次下載主題(31張高清圖片)至少需要 10s。有什麼方法能夠優化下。
因為代碼不具備可復用性,因此部分代碼直接省略,思路為主
原始邏輯
public async getZip(themeId: string, res: any) { const theme = await this.model.findById(themeId); // 從資料庫 // 這裡需要借用一個伺服器上的主題模板文件夾 template/, /* theme = { wallpapers: [ { url: 'https://亞馬遜雲.com/1.jpg', ... }, ... ] } */ // for 迴圈遍歷 theme.wallpapers , 並通過 fetch 請求 url,將其寫進 template/static/wallpapers 文件夾中 theme.wallpapers.map((item) => { const response = await fetch(item.url); const buffer = new Uint8Array(await response.arrayBuffer()); await fs.writeFile(`template/wallpapers/${fileName}`, buffer); }) // ... 還有其他一些處理 // 將 template 壓縮成 zip 文件,發送給前端 }
思考 ing ...
1 利用圖片可以被瀏覽器緩存
當一次下載主題從請求亞馬遜雲的圖片數據,這步沒有問題。 但是當重覆下載的時候,之前下載過的圖片又會再次下載,操作人員每次都需要等個十幾秒,這就不太友好了。這部分時間花費還是挺多的。
可以利用下瀏覽器能夠將圖片緩存到 disk cache
中的特點,將這部分的代碼邏輯放到前端完成,因為還需要對壓縮包中的文件做一些處理,因此需要藉助下 jszip
這個庫。
看下改後的代碼
onDownload () { // 請求拿到 theme 數據 const theme = api.getTheme() const template = api.getTemplate() // Blob const zip = new JSZip() await zip.loadAsync(getTmplResp) // 讀取 template.zip 文件數據 console.time('handle images') const wallpaperList = theme.wallpapers for (const wallpaper of wallpaperList) { const response = await fetch(wallpaper.url) // 請求圖片數據 const buffer = new Uint8Array(await response.arrayBuffer()) const fileName = wallpaper.url.split('/').pop() zip.file(`static/wallpapers/${fileName}`, buffer, { binary: true }) // 寫進壓縮包 } console.timeEnd('handle images') // 統計用時 // 還需要讀取 template.zip 中的 config.json, 然後修改,重新保存到 template.zip 中 ... // 導出 template.zip zip.generateAsync({ type: 'base64' }).then( (base64) => { const link = document.createElement('a') link.href = 'data:application/zip;base64,' + base64 link.download = 'template.zip' link.target = '_blank' link.style.display = 'none' document.body.appendChild(link) link.click() document.body.removeChild(link) }, (err) => { console.log('打包失敗', err) } ) }
優化完成
當第一次下載時,handle images
步驟耗時 20 - 21 s,流程和後端差不多。
當第二次下載時,handle images
步驟耗時 0.35s - 0.45 s。會直接讀取 disk cache
中的圖片數據,50 ms 內就完成了。
速度快了 57 倍有餘!!!, 你還能想到其他優化方式嗎?繼續往後看