由于微(wei)(wei)信小(xiao)程序(xu)誕生于vue.js和react.js之后(hou),所以他們在當初(chu)設計代碼架(jia)構的時候(hou)也是(shi)借(jie)鑒了(le)vue.js和react.js的想法,也遵循(xun)的組件化(hua)的方式,延用了(le)setData的機制(zhi)去把視(shi)圖(tu)層(ceng)和邏輯層(ceng)做一(yi)個“中轉站”兩邊連接起來。但(dan)是(shi)這種機制(zhi)一(yi)直存在性(xing)能上的問題,微(wei)(wei)信小(xiao)程序(xu)也不例外(wai)。先看(kan)一(yi)張圖(tu):

這張圖大體描(miao)述了一下(xia)(xia)setData的工(gong)作原(yuan)理,當程序(xu)開始觸發setData操作的時候,先把數(shu)(shu)據做成(cheng)字(zi)符串形(xing)式(shi)(shi)傳遞,同時把轉換后的數(shu)(shu)據拼接成(cheng)js腳本形(xing)式(shi)(shi),接下(xia)(xia)來(lai)這個(ge)js腳本都被(bei)2邊提(ti)供的evaluateJavascript所實現,那為什么要分webview和javascriptCore去執行呢(ni)?先說一下(xia)(xia)這2個(ge)是干嘛的
在微信打開(kai)小程序的(de)時候,會先起了2個線(xian)程一(yi)(yi)個是(shi)(shi)view Thread,一(yi)(yi)個是(shi)(shi)AppService Thread, 通(tong)俗(su)講前者(zhe)(zhe)是(shi)(shi)視圖層(ceng),后者(zhe)(zhe)是(shi)(shi)邏(luo)輯層(ceng)。它們是(shi)(shi)獨立的(de),各自(zi)職能不一(yi)(yi)樣(yang),但(dan)它們是(shi)(shi)并行操作(zuo)的(de),小程序的(de)頁面展示都(dou)是(shi)(shi)嵌套在webview里面的(de),
在小程序入(ru)口文(wen)件app.js里面(mian)有一個pages配置項,例如:
pages: [
'pages/indexBar',
'pages/friends/friends'
]
這里配置了多少個(ge)頁(ye)面(mian)(mian),小程序都會預先加載(zai)(zai)多少個(ge)頁(ye)面(mian)(mian)對應的(de)webview,這是view Thread所(suo)做的(de)操(cao)作(zuo),同時AppService Thread也(ye)是對應的(de)頁(ye)面(mian)(mian)做了邏輯層面(mian)(mian)的(de)加載(zai)(zai)操(cao)作(zuo),會根據(ju)小程序的(de)生命周期依次(ci)做邏輯操(cao)作(zuo),這里也(ye)會和(he)view Thread有(you)數據(ju)傳輸交互(hu),下面(mian)(mian)一張圖可(ke)以很詳(xiang)細的(de)描述view Thread和(he)AppService Thread同時加載(zai)(zai)一個(ge)頁(ye)面(mian)(mian)的(de)所(suo)有(you)過程

在(zai)架構上,WebView 和 JavascriptCore 都是獨立(li)的模塊,數據(ju)是不能直接共享的,為了(le)讓數據(ju)共享,WebView和JavascriptCore都提供了(le)evaluateJavascript來(lai)實現,(在(zai)安卓(zhuo)機上老早以前(qian)提供的不是evaluateJavascript來(lai)調用js操作的,到(dao)sdk19以上采用evaluateJavascript方(fang)法(fa))
由于有了(le)以上的機制(zhi),造成了(le)setData存(cun)在一些性能上的問(wen)題,如果頻(pin)繁地調用(yong),WebView和JavascriptCore執行并發多了(le)就會造成用(yong)戶體驗(yan)卡頓的現象,為(wei)了(le)減少性能開銷,建議盡量對(dui)setData進行合并操作:
|
1 |
this.setData({ one: '1' }) |
修改成:
this.setData({
one: '1',
two: '2',
three: '3',
})
這樣就(jiu)減少了拼接js腳本的次數,從(cong)而提升了性能。
在Taro小程序框架里面更新數(shu)據時調用的(de) setState 為異(yi)步方法,自動對同一個事(shi)件循(xun)環多(duo)次setState調用,然后進行合并(bing)處(chu)理(li),還會對數(shu)據進行diff優化,自動剔除那(nei)些未(wei)改變的(de)數(shu)據。