这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
业务场景:
产品有个功能是设置主题。类似手机自动切换壁纸,以及其他功能颜色,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 倍有余!!!, 你还能想到其他优化方式吗?继续往后看