背景
日常需求中能遇见需要用户保存海报,然后分享海报到微信的场景
此时我们的背景是:利用一个v-for。循环出N个div,一个div就是一张海报。
最初的做法是,串行执行转换,用一个for循环,挨个去转换每一个div,总共要执行n次。我们测试都是五张海报,大概需要九秒。
后续去做优化:
很明显的能想到:第一个优化的方法是。并行执行,大概需要5秒
但是还是不够满足要求:
后续去看了很多文章+HTML2Canvas的官网,想到:其实最耗费时间的事情,是转换,我们转换的次数太多了。为何不合并在一起呢,这样的话,只需要一次转换,后续切割就可以了
然后我去做了优化,把五张海报上下合并在一起,然后一次性转换一个很长的海报,然后很长的海报拿到后,进行切割,因为每张海报都是等长的,所以只用根据高度来切割就行,然后大概需要2.7秒。在五张海报的情况下优化了6.3秒
转换代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 
 | const allPosterBox = ref<HTMLDivElement>(null as unknown as HTMLDivElement)async function save() {
 if (saveLocked) return
 showLoading('保存中')
 
 const arr: string[] = []
 const canvas = await html2canvas(allPosterBox.value, { useCORS: true })
 
 const context = canvas.getContext('2d')!
 
 const imgHeight = canvas.width * 644 / 375
 for (let i = 0; i < selectedInfoList.value.length; i++) {
 const imageData = context.getImageData(0, i * imgHeight, canvas.width, imgHeight)
 const newImageData = context.createImageData(imageData.width, imageData.height)
 newImageData.data.set(imageData.data)
 const newCanvas = document.createElement('canvas')
 
 const newCtx = newCanvas.getContext('2d')!
 newCanvas.width = imageData.width
 newCanvas.height = imageData.height
 newCtx.putImageData(newImageData, 0, 0)
 const base64Image = newCanvas.toDataURL('image/jpeg', 0.6)
 arr.push(base64Image.split(';base64,')[1])
 }
 
 const list: Promise<{ url: string }>[] = []
 for (let i = 0; i < arr.length; i++) {
 list.push(uploadImg({ content: arr[i] }))
 }
 
 Promise.all(list).then(async res => {
 for (let i = 0; i < res.length; i++) {
 await new Promise((resolve) => {
 bridge.saveImage({
 type: 1,
 data: res[i].url
 }, (res) => {
 if (Number(res.errno) === 0) {
 resolve(true)
 } else {
 throw new Error()
 }
 })
 })
 }
 step.value = 'create'
 saveLocked = false
 hideToast()
 showToast('保存成功', 'correct')
 }).catch((err) => {
 saveLocked = false
 console.log(err)
 showToast('保存全部失败')
 })
 }
 
 | 
成长
对于这块,我的收获是:做性能优化的时候,最关键的是找到哪里才是最耗费性能的,例如我最初以为是串行占了并行时间,其实最后发现是转换占了时间