?? ????? ????? ??? ?????? ?? ?? ?? ???? ??? ??? ???? ?? ???? ??? ??? ???? ?? ???? ??? ?? ??????!
?? ????? ?? ??
?? ??? ? ??? ??? ?? ? ??? ?? ????? ?? ??? ??? ?????.
? ?? ??? ??? ?????:
??? ???? ?? ? ??? ??? ?? ??? ??? ???? ?? ??? ??? ?? ?? ???? ?? ????.
??? ??
1. ?? ???? ???? ??
?? ???? ?? ??? ?? ?????. ? ??? ?? ????? ??? ??? ??????. 2M ??.
???? ?? ???? ???? ??? ???, ?? ????? ?? ??? ??? ?? ??? ????? ???? ? ????.
???? [?? ???] [?? ???]? [?? ???]?? ?????.
[?? ???]? ?? ??? ?? TabBar ???? ???? ???.
[?? ?? ???] TabBar ???? ?? ?? ???? ?????. ?? ???? ??? ??? ?? ??? ?? ?? ?? ?? ?? ?? ???? ??? ?? ????. ?? ?? ??? ???? ??? ? ? ???? ?????? ??? ?? ???? ??? ? ?? ??? ??? ?? ? ????. ?? ????? ?? ?? ???? ????? ???? ?? ?? ???? ????? ? ?? ???? ?????? ???.
[?? ?? ???] ???? ?? ?? ???? ?????. ?? ?? ???? ????? ?? ????? ???? ?? ?? ???? ??????? ??? ?? ??? ?? ?????. ???? ?? ???? ?????? ?? ???? ?? TabBar ??? ?? ?? ?? ?? ??? ???? ??? ?.
?? ??, ??? ?? ???? ?? ?? ????? ?? ??? ?? ? ????. ?? ???? ???? ???? ??? ?????.
??? ????? ?? ???? ??? ??? ?? ?????. ???? ??? ??? ??? 2M? ???? ?? ??? ?? ? ??? ?? ???? ???? ??? ????. ???? ???? ???? ????? 2M ?? ???? 500KB ?? ???? ??? ????? ??? ?? ???? ?? ? ???, ?? ???? ????? ?? ?? ????? ?? ??? ?????. ??? ???? ?? ??? ??(?? ??? ?? ???? ? ? ??).
?? ?? TabBar ????? ?? ???? ? ?? ??? ?? ?? ???? ???? ?? ?? ?? ? ?? ???? ??? ???? ?? ???? ???? ????. ?? ?? ?? ???? ?? ???? ??? ???? ?????.
?? ???? ?????? [??? ?? ????]? ??? ?? ? ?????. ?? ????? ??? ?? ??? ? ????. ???? ?? ???? ???? ???? ?? ???????.
2. ??? ??
???? ???? ????? ? ???? ?? ???? ?? JS
, ?? ???? ?? ??? ? ???? ?? ??? ???? ?????. ??? ?? ?? ?? ?? ??? ??? ??? ?????. ?? ??? ??? ???? ??? ???. ??? ??? ?? ??? ????? ???? ??? ?? ???? ?? ??? ???? ????. JS
合并注入,一些未訪問的頁(yè)面以及未用到的自定義組件也會(huì)被注入到運(yùn)行環(huán)境當(dāng)中。影響注入耗時(shí)和內(nèi)存占用。我們希望的是當(dāng)包下載完成后,只注入我們即將打開的頁(yè)面的代碼就行。
這也是小程序啟動(dòng)或跳轉(zhuǎn)進(jìn)入分包頁(yè)面影響白屏?xí)r間的一點(diǎn)。
{ "lazyCodeLoading" : "requiredComponents" }
3. 明確 <span style="font-size: 18px;">setData</span>
的幾個(gè)調(diào)用原則
小程序是以微信客戶端為宿主運(yùn)行的,即wxml
、wxs
、wxss
都是運(yùn)行在客戶端的,運(yùn)行環(huán)境又分成了兩個(gè)線程,一個(gè)渲染線程,一個(gè)邏輯線程。渲染層使用 WebView
進(jìn)行渲染, 邏輯層使用JSCore
運(yùn)行JS
代碼。wxml
和wxss
工作在渲染線程,而wxs
工作在邏輯線程。那兩個(gè)線程之間怎么通信呢?
通過客戶端作為中轉(zhuǎn)站進(jìn)行通信
渲染層觸發(fā)事件響應(yīng)到客戶端,邏輯層通過setData傳送數(shù)據(jù)到客戶端,兩邊的數(shù)據(jù)都會(huì)被轉(zhuǎn)換成字符串之后進(jìn)行傳輸,客戶端再分別做出響應(yīng),并且響應(yīng)并非實(shí)時(shí)的。意味著在邏輯層觸發(fā)setData
頁(yè)面并不會(huì)馬上更新,會(huì)有一些延遲渲染層才會(huì)更新。
模型如圖:
Native
const needRefresh = `list[${index}]` // 寫法一 setData({ [needRefresh]: '新值' }) // 寫法二 setData({ [`list[${index}]`]: '新值' }) // 寫法三 setData({ 'list[0]': '新值' }) // 寫法四 const needRefresh = `list[${index}].disabled` setData({ [needRefresh]: '新值' }) // 寫法5 更新對(duì)象 setData({ 'personal.name':'xxx' })??????3. ??
??setData??
?????????????? WeChat ?????? ???? ???? ?????. ?, wxml</ code >, <code>wxs
? wxss
? ?? ??????? ?????. ?? ??? ??? ??? ??? ?? ??? ??, ? ?? ???? ????. ??? ??? ???? ?? WebView
? ????, ?? ??? JSCore
? ???? JS
??? ?????. wxml
? wxss
? ??? ????? ???? ?? wxs
? ?? ????? ?????. ? ??? ?? ???? ??? ?????? ??- ?????????? ?? ?????? ?? ??????
setData
? ????? ???? ?? ?????? ??? ??? ???? ?????? ?? ??? ??? ??? ?????. ??????? ??? ????: ????
????
? ????????. ??回到問題,setData
在邏輯層調(diào)用,讓渲染層快速響應(yīng)取決于邏輯層到客戶端的數(shù)據(jù)傳輸效率,而這個(gè)傳輸效率又取決于你傳輸數(shù)據(jù)的大小,所以在調(diào)用setData
的時(shí)候應(yīng)該盡可能減少數(shù)據(jù)傳輸大小。
Native
會(huì)將wxml
轉(zhuǎn)換成 js對(duì)象,然后和setData
傳進(jìn)來的對(duì)象做差異化對(duì)比,將差異化渲染到視圖上。
綜上原理,我們調(diào)用setData
應(yīng)該遵循幾個(gè)原則:
- 盡可能減小需要 setData 數(shù)據(jù)的大小,
JSON.stringify
后不超過 256KB。 - 避免將不需要渲染的數(shù)據(jù)(不在
wxml
中綁定的數(shù)據(jù))傳入setData
,減少差異對(duì)比耗時(shí)。 - 避免過于頻繁調(diào)用
setData
,會(huì)導(dǎo)致邏輯層業(yè)務(wù)繁忙,一直在處理setData
的傳輸隊(duì)列,而導(dǎo)致抽不開身去處理渲染層的響應(yīng),從而導(dǎo)致渲染阻塞,頁(yè)面出現(xiàn)卡頓,甚至setData
無效。如果可以的話,可以采用節(jié)流等方式進(jìn)行優(yōu)化。 - 盡可能將多個(gè)需要更新的數(shù)據(jù)合并為一次
setData
,減少通信過程。 - 避免后臺(tái)頁(yè)面觸發(fā)
setData
,也會(huì)占用Js線程,有可能會(huì)造成阻塞,導(dǎo)致真正需要setData
的數(shù)據(jù)沒有響應(yīng)
減小setData
的數(shù)據(jù)大小通常在列表場(chǎng)景中,通常只更新需要更新的下標(biāo):
const needRefresh = `list[${index}]` // 寫法一 setData({ [needRefresh]: '新值' }) // 寫法二 setData({ [`list[${index}]`]: '新值' }) // 寫法三 setData({ 'list[0]': '新值' }) // 寫法四 const needRefresh = `list[${index}].disabled` setData({ [needRefresh]: '新值' }) // 寫法5 更新對(duì)象 setData({ 'personal.name':'xxx' })
如果有變量,就需要放在
[]
內(nèi)。
4. 控制圖片大小比例
圖片太大會(huì)增加下載時(shí)間和內(nèi)存的消耗,并且為了用戶體驗(yàn),應(yīng)該控制圖片的高寬比例,防止圖片變形或者被裁切(這個(gè)問題可以根據(jù)
image
的mode
屬性進(jìn)行調(diào)整)。
一個(gè)合格的圖片應(yīng)該滿足以下兩點(diǎn):
圖片寬高乘積 <= 實(shí)際顯示寬高乘積 * (設(shè)備像素比 ^ 2)。
顯示的高/寬與原圖的高/寬不超過 15%。
由于這些圖片都出自 UI,所以在這一條優(yōu)化上你需要做的是:拿著這兩條指標(biāo)去跟 UI battle。
good lucky ~
以上第一條就是和設(shè)備的【dpr】相關(guān),移動(dòng)端開發(fā)一定要理解【dpr】,這里就不多贅述了。
我們應(yīng)該合理的采用圖片資源,例如在【dpr】為 2 的設(shè)備上,一個(gè) 60x60 的元素區(qū)域顯示的圖片為了兼顧清晰度與資源大小,圖片大小不應(yīng)該超過 120x120, 同理,【dpr】為 3 設(shè)備,圖片應(yīng)該不超過 180x180。
我們小程序的資源都放在cdn上,可以利用cdn的圖片云處理功能對(duì)資源請(qǐng)求進(jìn)行控制,我司用的七牛云和又拍云,如下:
// 七牛云 `${_src}?imageMogr2/thumbnail/!${scaleRatio}p` // 又拍云 `${_src}!/scale/${scaleRatio}`
更多云處理功能可以挪步官網(wǎng):七牛云(https://developer.qiniu.com/dora/8255/the-zoom) 和又拍云(https://help.upyun.com/knowledge-base/image/)
我們?cè)谛〕绦騼?nèi)自定義了圖片組件 cus-image
, 該組件會(huì)根據(jù)【dpr】對(duì)圖片進(jìn)行云處理。并提供了 ratio
屬性靈活調(diào)整圖片大?。ㄒ?yàn)檫\(yùn)營(yíng)方上傳的圖片可能在不同尺寸的元素區(qū)域內(nèi)引用,所以需要開發(fā)人員靈活控制)。
5. 避免短時(shí)間內(nèi)發(fā)起太多請(qǐng)求
小程序中wx.request
、wx.uploadFile
、wx.downloadFile
的發(fā)起的網(wǎng)絡(luò)請(qǐng)求短時(shí)間內(nèi)最大并發(fā)限制是 10 個(gè),超過 10 個(gè)就會(huì)導(dǎo)致請(qǐng)求阻塞。而圖片請(qǐng)求的并發(fā)最大數(shù)量為6。
那短時(shí)間怎么去界定呢?
- 【網(wǎng)絡(luò)請(qǐng)求】耗時(shí)超過 300ms 的請(qǐng)求并發(fā)數(shù)不超過 10 個(gè)(一般不會(huì)出現(xiàn)這個(gè)問題,如果有這個(gè)問題那可能該考慮拆分頁(yè)面、拆分業(yè)務(wù)或者合并接口了。)
- 【圖片請(qǐng)求】同域名耗時(shí)超過 100ms 的圖片請(qǐng)求并發(fā)數(shù)不超過 6 個(gè)
例如:300ms內(nèi)發(fā)送了12個(gè)請(qǐng)求,其中10個(gè)請(qǐng)求在300ms內(nèi)就請(qǐng)求完成了,只有2個(gè)請(qǐng)求超過300ms,這樣是沒有問題的。
【解決方案】
- 在接口請(qǐng)求上我們應(yīng)該盡可能的減少請(qǐng)求數(shù)量。
- 圖片可以設(shè)置懶加載
lazy-load
。 - 圖標(biāo)可以使用雪碧圖。
- 將圖片資源拆分在多個(gè)域名下。
- 自定義一個(gè)分片處理函數(shù),將請(qǐng)求拆分成數(shù)個(gè)階段發(fā)出。
function interelTasks(task,wait){ this.data.timer = setInterval(()=>{ task() }, wait) } async function task(promiseList = []){ const result = await promise.all(promiseList) // do something }
叨擾一句:有些時(shí)候在請(qǐng)求數(shù)量限制范圍內(nèi),我們應(yīng)該對(duì)沒有先后順序的接口進(jìn)行并發(fā)處理,提高接口處理效率。
6. 請(qǐng)求耗時(shí)優(yōu)化
這一點(diǎn)主要體現(xiàn)在兩個(gè)方面——【接口】和【靜態(tài)資源】。
【接口】基本上不應(yīng)該超過1000ms,哪怕是幾百毫秒也可能需要做一些優(yōu)化了,基本上正常速度在10-200ms,個(gè)別接口幾百也正常,大部分都應(yīng)該不超過500ms(后端大佬請(qǐng)消消氣)。
【靜態(tài)資源】首先從資源的大小考慮出發(fā),大部分資源是圖片,可以參考上面的圖片大小標(biāo)準(zhǔn)。其次考慮資源緩存,對(duì)于小程序而言,靜態(tài)資源基本上是存放在cdn上的,設(shè)置緩存可以有效的提高客戶端表現(xiàn)性能。
這邊給大家分享一個(gè)圖片壓縮網(wǎng)站:https://tinypng.com/
7. 避免使用過大的 WXML 節(jié)點(diǎn)數(shù)目
建議一個(gè)頁(yè)面使用少于 1000 個(gè) WXML 節(jié)點(diǎn),節(jié)點(diǎn)樹深度少于 30 層,子節(jié)點(diǎn)數(shù)不大于 60 個(gè)。一個(gè)太大的 WXML 節(jié)點(diǎn)樹會(huì)增加內(nèi)存的使用,樣式重排時(shí)間也會(huì)更長(zhǎng),影響體驗(yàn)。
頁(yè)面的節(jié)點(diǎn)數(shù)包含所有子節(jié)點(diǎn)數(shù),需要注意的是子節(jié)點(diǎn)數(shù),若一個(gè)子節(jié)點(diǎn)數(shù)大于60的時(shí)候,或許你就該考慮對(duì)組件或者頁(yè)面進(jìn)行重新劃分了。
基本功!
8. 使用骨架屏
骨架屏相信大家都不陌生,如果我們的優(yōu)化手段都用盡了,頁(yè)面需要加載的資源本身就比較多,那骨架屏也是我們退而求其次的最佳方案了,也算是“曲線救國(guó)“了。
實(shí)現(xiàn)骨架屏的方式有多種,你可以自己寫一個(gè)骨架組件,也可以用一些生成骨架屏的插件。除此之外,小程序還提供了白嫖方案,開發(fā)者工具提供了自動(dòng)生成骨架屏代碼的能力。
詳情請(qǐng)?jiān)L問 https://developers.weixin.qq.com/miniprogram/dev/devtools/skeleton.html
9. 合理的進(jìn)行組件拆分并減小<span style="font-size: 18px;">data</span>
的大小
微信小程序的更新是基于組件的,自定義組件的更新只會(huì)在組件內(nèi)部,這能減少差異比較帶來的耗時(shí)。
控制data
的大小主要是為了減少內(nèi)存消耗,比如在data
中定義一些圖片路徑的變量,如果可以,我更推薦通過background
的方式去加載一些圖片。
10. 滾動(dòng)區(qū)域設(shè)置慣性滾動(dòng)
慣性滾動(dòng)會(huì)使?jié)L動(dòng)比較順暢,在安卓下默認(rèn)有慣性滾動(dòng),而在 iOS 下需要額外設(shè)置 -webkit-overflow-scrolling: touch
的樣式。
11. 擴(kuò)大點(diǎn)擊元素的可點(diǎn)擊區(qū)域
微信規(guī)定最小可點(diǎn)擊區(qū)域應(yīng)該不小于 20x20 像素。這種樣式問題不多贅述了,八仙過海,各顯神通。
最后
性能優(yōu)化不是一個(gè)技術(shù)債務(wù),而是需要我們?cè)谄綍r(shí)的迭代版本中去不斷的優(yōu)化或重構(gòu),團(tuán)隊(duì)中的成員都應(yīng)該明確這一點(diǎn)。
性能優(yōu)化不僅僅是前端的事情,是需要團(tuán)隊(duì)中各個(gè)不同的職責(zé)相互配合才能做好的事情,所以,如果你發(fā)現(xiàn)接口慢,圖片大,請(qǐng)勇敢的提出來,并和你的同事溝通解決。事無巨細(xì),都很重要。
還有一些更細(xì)節(jié)的優(yōu)化點(diǎn)可以參考官網(wǎng)地址:
- https://developers.weixin.qq.com/miniprogram/dev/framework/audits/audits.html
如果有什么問題歡迎留言指正。
【相關(guān)學(xué)習(xí)推薦:小程序開發(fā)教程】
? ??? ?? ????? ????? ??? ???? ????????. (?? ??)? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? AI ??

Undress AI Tool
??? ???? ??

Undresser.AI Undress
???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover
???? ?? ???? ??? AI ?????.

Clothoff.io
AI ? ???

Video Face Swap
??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

?? ??

??? ??

???++7.3.1
???? ?? ?? ?? ???

SublimeText3 ??? ??
??? ??, ???? ?? ????.

???? 13.0.1 ???
??? PHP ?? ?? ??

???? CS6
??? ? ?? ??

SublimeText3 Mac ??
? ??? ?? ?? ?????(SublimeText3)