首頁  >  文章  >  微信小程式  >  手把手帶你看看小程式如何優化? (實務總結)

手把手帶你看看小程式如何優化? (實務總結)

青灯夜游
青灯夜游轉載
2021-12-30 10:28:405757瀏覽

小程式如何最佳化?這篇文章跟大家總結小程式優化實踐,看看小程式優化項,希望對大家有幫助!

手把手帶你看看小程式如何優化? (實務總結)

小程式運行過程

我們先來梳理一下小程式的運作原理,磨刀不會誤砍柴功。

一圖勝千言:

手把手帶你看看小程式如何優化? (實務總結)

建議大家認真去理解圖中的內容,對於小程式開發以及優化方向都有較有力的理論支持。

優化項目

1. 合理的使用分包

微信小程式的主要特點是啟動快速,為了這一特性,官方因此限制了包的大小,上限為2M。

分包是小程式優化的第一要務,能有效提升小程式啟動速度,以及頁面開啟速度。

包分為【主包】【普通分包】【獨立分包】。

【主套件】應該只放置啟動頁或TabBar頁面。

【普通分包】放置非TabBar頁面的其他頁面,建議依照頁面數量或模組劃分多個分包,減少分包的大小,當使用者進入對應分包頁面的時候才會去下載這個包,這也實現了包的按需加載,避免了資源浪費。當小程式從普通分包中的某個頁面的時候啟動時,需要先下載主包,然後在下載分包。

【獨立分包】放置一些獨立性較高的頁面,當小程式從獨立分包中的頁面啟動時,只會下載獨立分包,從而大大提高小程式啟動速度,當用戶進入TabBar頁面或其他普通分包頁面才回去下載對應的套件。

獨立分包中不能有任何全域的東西,包括元件,登入等,引入任何其他套件中的資源都會出錯。

作者建議梳理好頁面和功能再分包,分包的界限並不是包的大小超過了2M,而是要靈活的根據業務和功能來進行劃分。在現今正常網路情況下,2M 的分包和500KB 的分包的下載可能用戶感知差距不會特別大,但是如果是在弱網環境下,這兩者會造成用戶白屏的時間上就有很大的差距(親身經歷,可以說是掏心了)。

例如,我會將那些可以由TabBar頁面直接進入且頻率較高的二級頁面放入一個分包,然後其他更深層的頁面或者那些不是那麼重要的頁面分成一個包,又或者將整個訂單業務模組的頁面分成一個包。

包分好了,自然不能少了【分包預下載】。可以依照官網的規則進行配置,當使用者進入某個頁面時,提前下載套件。

2. 按需注入

小程式下載完套件之後,會開啟頁面所在套件的全部JS合併注入,一些未訪問的頁面以及未用到的自訂元件也會被注入到運行環境當中。影響注入耗時和記憶體佔用。我們希望的是當套件下載完成後,只注入我們即將打開的頁面的程式碼就行。

這也是小程式啟動或跳轉進入分包頁面影響白螢幕時間的一點。

{
    "lazyCodeLoading" : "requiredComponents"
}

3. 明確<span style="font-size: 18px;">setData</span> 的幾個呼叫原則

小程式是以微信客戶端為宿主運行的,即wxmlwxswxss都是運行在客戶端的,運行環境又分成了兩個線程,一個渲染線程,一個邏輯線程。渲染層使用 WebView 進行渲染, 邏輯層使用JSCore執行JS程式碼。 wxmlwxss工作在渲染線程,而wxs工作在邏輯線程。那兩個執行緒之間怎麼通訊呢?

  • 透過客戶端作為中繼站進行通訊

渲染層觸發事件回應到客戶端,邏輯層透過setData傳送資料到客戶端,兩邊的資料都會轉換成字串之後進行傳輸,客戶端再分別做出回應,並且回應並非即時的。意味著在邏輯層觸發setData頁面並不會馬上更新,會有一些延遲渲染層才會更新。

模型如圖:

手把手帶你看看小程式如何優化? (實務總結)

Native即是客戶端。

回到问题,setData在逻辑层调用,让渲染层快速响应取决于逻辑层到客户端的数据传输效率,而这个传输效率又取决于你传输数据的大小,所以在调用setData的时候应该尽可能减少数据传输大小。

Native会将wxml转换成 js对象,然后和setData传进来的对象做差异化对比,将差异化渲染到视图上。

综上原理,我们调用setData应该遵循几个原则:

  • 尽可能减小需要 setData 数据的大小,JSON.stringify后不超过 256KB
  • 避免将不需要渲染的数据(不在wxml中绑定的数据)传入setData,减少差异对比耗时。
  • 避免过于频繁调用setData,会导致逻辑层业务繁忙,一直在处理setData的传输队列,而导致抽不开身去处理渲染层的响应,从而导致渲染阻塞,页面出现卡顿,甚至setData无效。如果可以的话,可以采用节流等方式进行优化。
  • 尽可能将多个需要更新的数据合并为一次setData,减少通信过程。
  • 避免后台页面触发setData,也会占用Js线程,有可能会造成阻塞,导致真正需要setData的数据没有响应

减小setData的数据大小通常在列表场景中,通常只更新需要更新的下标:

const needRefresh = `list[${index}]`
// 写法一
setData({
    [needRefresh]: &#39;新值&#39;
})

// 写法二
setData({
    [`list[${index}]`]: &#39;新值&#39;
})

// 写法三
setData({
    &#39;list[0]&#39;: &#39;新值&#39;
})

// 写法四
const needRefresh = `list[${index}].disabled`
setData({
    [needRefresh]: &#39;新值&#39;
})

// 写法5 更新对象
setData({
    &#39;personal.name&#39;:&#39;xxx&#39;
})

如果有变量,就需要放在[]内。

4. 控制图片大小比例

图片太大会增加下载时间和内存的消耗,并且为了用户体验,应该控制图片的高宽比例,防止图片变形或者被裁切(这个问题可以根据imagemode属性进行调整)。

一个合格的图片应该满足以下两点:

  • 图片宽高乘积 。

  • 显示的高/宽与原图的高/宽不超过 15%

由于这些图片都出自 UI,所以在这一条优化上你需要做的是:拿着这两条指标去跟 UI battle。

good lucky ~ 

以上第一条就是和设备的【dpr】相关,移动端开发一定要理解【dpr】,这里就不多赘述了

我们应该合理的采用图片资源,例如在【dpr】为 2 的设备上,一个 60x60 的元素区域显示的图片为了兼顾清晰度与资源大小,图片大小不应该超过 120x120, 同理,【dpr】为 3 设备,图片应该不超过 180x180。

我们小程序的资源都放在cdn上,可以利用cdn的图片云处理功能对资源请求进行控制,我司用的七牛云和又拍云,如下:

// 七牛云
`${_src}?imageMogr2/thumbnail/!${scaleRatio}p`

// 又拍云
`${_src}!/scale/${scaleRatio}`

更多云处理功能可以挪步官网:七牛云(https://developer.qiniu.com/dora/8255/the-zoom)  和又拍云(https://help.upyun.com/knowledge-base/image/)

我们在小程序内自定义了图片组件 cus-image , 该组件会根据【dpr】对图片进行云处理。并提供了 ratio 属性灵活调整图片大小(因为运营方上传的图片可能在不同尺寸的元素区域内引用,所以需要开发人员灵活控制)。

5. 避免短时间内发起太多请求

小程序中wx.requestwx.uploadFilewx.downloadFile的发起的网络请求短时间内最大并发限制是 10 个,超过 10 个就会导致请求阻塞。而图片请求的并发最大数量为6

短时间怎么去界定呢?

  • 【网络请求】耗时超过 300ms 的请求并发数不超过 10 个(一般不会出现这个问题,如果有这个问题那可能该考虑拆分页面、拆分业务或者合并接口了。)
  • 【图片请求】同域名耗时超过 100ms 的图片请求并发数不超过 6 个

例如:300ms内发送了12个请求,其中10个请求在300ms内就请求完成了,只有2个请求超过300ms,这样是没有问题的。

【解决方案】

  • 在接口请求上我们应该尽可能的减少请求数量。
  • 图片可以设置懒加载lazy-load
  • 图标可以使用雪碧图。
  • 将图片资源拆分在多个域名下。
  • 自定义一个分片处理函数,将请求拆分成数个阶段发出。
function interelTasks(task,wait){
    this.data.timer = setInterval(()=>{
        task()
    }, wait)
}

async function task(promiseList = []){
    const result = await promise.all(promiseList)
    // do something
}

叨扰一句:有些时候在请求数量限制范围内,我们应该对没有先后顺序的接口进行并发处理,提高接口处理效率。

6. 请求耗时优化

这一点主要体现在两个方面——【接口】和【静态资源】。

【接口】基本上不应该超过1000ms,哪怕是几百毫秒也可能需要做一些优化了,基本上正常速度在10-200ms,个别接口几百也正常,大部分都应该不超过500ms(后端大佬请消消气)。

【静态资源】首先从资源的大小考虑出发,大部分资源是图片,可以参考上面的图片大小标准。其次考虑资源缓存,对于小程序而言,静态资源基本上是存放在cdn上的,设置缓存可以有效的提高客户端表现性能。

这边给大家分享一个图片压缩网站:https://tinypng.com/

7. 避免使用过大的 WXML 节点数目

建议一个页面使用少于 1000 个 WXML 节点,节点树深度少于 30 层,子节点数不大于 60 个。一个太大的 WXML 节点树会增加内存的使用,样式重排时间也会更长,影响体验。

页面的节点数包含所有子节点数,需要注意的是子节点数,若一个子节点数大于60的时候,或许你就该考虑对组件或者页面进行重新划分了。

基本功!

8. 使用骨架屏

骨架屏相信大家都不陌生,如果我们的优化手段都用尽了,页面需要加载的资源本身就比较多,那骨架屏也是我们退而求其次的最佳方案了,也算是“曲线救国“了。

实现骨架屏的方式有多种,你可以自己写一个骨架组件,也可以用一些生成骨架屏的插件。除此之外,小程序还提供了白嫖方案,开发者工具提供了自动生成骨架屏代码的能力。

详情请访问 https://developers.weixin.qq.com/miniprogram/dev/devtools/skeleton.html

9. 合理的进行组件拆分并减小<span style="font-size: 18px;">data</span>的大小

微信小程序的更新是基于组件的,自定义组件的更新只会在组件内部,这能减少差异比较带来的耗时。

控制data的大小主要是为了减少内存消耗,比如在data中定义一些图片路径的变量,如果可以,我更推荐通过background的方式去加载一些图片。

10. 滚动区域设置惯性滚动

惯性滚动会使滚动比较顺畅,在安卓下默认有惯性滚动,而在 iOS 下需要额外设置 -webkit-overflow-scrolling: touch 的样式。

11. 扩大点击元素的可点击区域

微信规定最小可点击区域应该不小于 20x20 像素。这种样式问题不多赘述了,八仙过海,各显神通。

最后

性能优化不是一个技术债务,而是需要我们在平时的迭代版本中去不断的优化或重构,团队中的成员都应该明确这一点。

性能优化不仅仅是前端的事情,是需要团队中各个不同的职责相互配合才能做好的事情,所以,如果你发现接口慢,图片大,请勇敢的提出来,并和你的同事沟通解决。事无巨细,都很重要。

还有一些更细节的优化点可以参考官网地址:

  • https://developers.weixin.qq.com/miniprogram/dev/framework/audits/audits.html

如果有什么问题欢迎留言指正。

【相关学习推荐:小程序开发教程

以上是手把手帶你看看小程式如何優化? (實務總結)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除