小程序開(kāi)發(fā)經(jīng)驗(yàn)總結(jié)
五、小程序開(kāi)發(fā)經(jīng)驗(yàn)
1、小程序存在的問(wèn)題
小程序仍然使用WebView渲染,并非原生渲染
需要獨(dú)立開(kāi)發(fā),不能在非微信環(huán)境運(yùn)行 。
開(kāi)發(fā)者不可以擴(kuò)展新組件。
依賴瀏覽器環(huán)境的js庫(kù)不能使用,因?yàn)槭荍SCore執(zhí)行的,沒(méi)有window、document對(duì)象。
WXSS中無(wú)法使用本地(圖片、字體等)。
WXSS轉(zhuǎn)化成js 而不是css。
WXSS不支持級(jí)聯(lián)選擇器。
小程序無(wú)法打開(kāi)頁(yè)面,無(wú)法拉起APP。
2、小程序的優(yōu)點(diǎn)
提前新建WebView,準(zhǔn)備新頁(yè)面渲染。
View層和邏輯層分離,通過(guò)數(shù)據(jù)驅(qū)動(dòng),不直接操作DOM。
使用Virtual DOM,進(jìn)行局部更新。
全部使用https,確保傳輸中安全。
加入rpx單位,隔離設(shè)備尺寸,方便開(kāi)發(fā)。
rpx(responsive pixel): 可以根據(jù)屏幕寬度進(jìn)行自適應(yīng)。規(guī)定屏幕寬為750rpx。 如在 iPhone6 上,屏幕寬度為375px,共有750個(gè)物理像素,則750rpx = 375px = 750物理像素, 1rpx = 0.5px = 1物理像素。 設(shè)備 rpx換算px (屏幕寬度/750) px換算rpx (750/屏幕寬度) iPhone5 1rpx = 0.42px 1px = 2.34rpx iPhone6 1rpx = 0.5px 1px = 2rpx iPhone6Plus 1rpx = 0.552px 1px = 1.81rpx
七、代碼運(yùn)行
運(yùn)行時(shí),外面包裹define,代碼作為回到,當(dāng)調(diào)用回調(diào)時(shí),只傳入前面三個(gè)值,由于后面的變量都是局部定義的變量,就屏蔽了(window,document等這些變量.
其中O就是上面define('app.js',callback),的回調(diào),回調(diào)值傳入了三個(gè)參數(shù),屏蔽了其他屬性
八、優(yōu)化建議(官方建議)
setData 工作原理
小程序的視圖層目前使用 WebView 作為渲染載體,而邏輯層是由獨(dú)立的 JavascriptCore 作為運(yùn)行環(huán)境。在架構(gòu)上,WebView 和 JavascriptCore 都是獨(dú)立的模塊,并不具備數(shù)據(jù)直接共享的通道。當(dāng)前,視圖層和邏輯層的數(shù)據(jù)傳輸,實(shí)際上通過(guò)兩邊提供的 evaluateJavascript 所實(shí)現(xiàn)。即用戶傳輸?shù)臄?shù)據(jù),需要將其轉(zhuǎn)換為字符串形式傳遞,同時(shí)把轉(zhuǎn)換后的數(shù)據(jù)內(nèi)容拼接成一份 JS 腳本,再通過(guò)執(zhí)行 JS 腳本的形式傳遞到兩邊獨(dú)立環(huán)境。
而 evaluateJavascript 的執(zhí)行會(huì)受很多方面的影響,數(shù)據(jù)到達(dá)視圖層并不是實(shí)時(shí)的。
常見(jiàn)的 setData 操作錯(cuò)誤
1. 頻繁的去 setData
在我們分析過(guò)的一些案例里,部分小程序會(huì)非常頻繁(毫秒級(jí))的去 setData ,其導(dǎo)致了兩個(gè)后果:
- Android 下用戶在滑動(dòng)時(shí)會(huì)感覺(jué)到卡頓,操作反饋延遲嚴(yán)重,因?yàn)?JS 線程一直在編譯執(zhí)行渲染,未能及時(shí)將用戶操作事件傳遞到邏輯層,邏輯層亦無(wú)法及時(shí)將操作處理結(jié)果及時(shí)傳遞到視圖層;
- 渲染有出現(xiàn)延時(shí),由于 WebView 的 JS 線程一直處于忙碌狀態(tài),邏輯層到頁(yè)面層的通信耗時(shí)上升,視圖層收到的數(shù)據(jù)消息時(shí)距離發(fā)出時(shí)間已經(jīng)過(guò)去了幾百毫秒,渲染的結(jié)果并不實(shí)時(shí);
2. 每次 setData 都傳遞大量新數(shù)據(jù)
由 setData 的底層實(shí)現(xiàn)可知,我們的數(shù)據(jù)傳輸實(shí)際是一次 evaluateJavascript 腳本過(guò)程,當(dāng)數(shù)據(jù)量過(guò)大時(shí)會(huì)增加腳本的編譯執(zhí)行時(shí)間,占用 WebView JS 線程,
3. 后臺(tái)態(tài)頁(yè)面進(jìn)行 setData
當(dāng)頁(yè)面進(jìn)入后臺(tái)態(tài)(用戶不可見(jiàn)),不應(yīng)該繼續(xù)去進(jìn)行 setData ,后臺(tái)態(tài)頁(yè)面的渲染用戶是無(wú)法感受的,另外后臺(tái)態(tài)頁(yè)面去 setData 也會(huì)搶占前臺(tái)頁(yè)面的執(zhí)行。
圖片資源
- 目前圖片資源的主要性能問(wèn)題在于大圖片和長(zhǎng)列表圖片上,這兩種情況都有可能導(dǎo)致 iOS 客戶端內(nèi)存占用上升,從而觸發(fā)系統(tǒng)回收小程序頁(yè)面。
- 在 iOS 上,小程序的頁(yè)面是由多個(gè) WKWebView 組成的,在系統(tǒng)內(nèi)存緊張時(shí),會(huì)回收掉一部分 WKWebView。從過(guò)去我們分析的案例來(lái)看,大圖片和長(zhǎng)列表圖片的使用會(huì)引起 WKWebView 的回收。
代碼包大小的優(yōu)化
開(kāi)發(fā)者在實(shí)現(xiàn)業(yè)務(wù)邏輯同時(shí)也有必要盡量減少代碼包的大小,因?yàn)榇a包大小直接影響到下載速度,從而影響用戶的首次打開(kāi)體驗(yàn)。除了代碼自身的重構(gòu)優(yōu)化外,還可以從這兩方面著手優(yōu)化代碼大?。?/p>
-
分包加載
對(duì)小程序進(jìn)行分包,可以優(yōu)化小程序首次啟動(dòng)的下載時(shí)間 - 清理沒(méi)有使用到的代碼和資源
目前小程序打包是會(huì)將工程下所有文件都打入代碼包內(nèi),也就是說(shuō),這些沒(méi)有被實(shí)際使用到的庫(kù)文件和資源也會(huì)被打入到代碼包里,從而影響到整體代碼包的大小。
預(yù)先加載數(shù)據(jù)
原理
小程序在啟動(dòng)時(shí),會(huì)直接加載所有頁(yè)面邏輯代碼進(jìn)內(nèi)存,即便 page2 可能都不會(huì)被使用。在 page1 跳轉(zhuǎn)至 page2 時(shí),page1 的邏輯代碼 Javascript 數(shù)據(jù)也不會(huì)從內(nèi)存中消失。page2 甚至可以直接訪問(wèn) page1 中的數(shù)據(jù)。
小程序的這種機(jī)制差異正好可以更好的實(shí)現(xiàn)預(yù)加載。通常情況下,我們習(xí)慣將數(shù)據(jù)拉取寫(xiě)在 onLoad 事件中。但是小程序的 page1 跳轉(zhuǎn)到 page2,到 page2 的 onLoad 是存在一個(gè) 300ms ~ 400ms 的延時(shí)的。
渲染view線程和AppServcie是相互獨(dú)立的,對(duì)于AppServcie中js運(yùn)行不會(huì)阻塞view的渲染
官方的示例也是采用這種方式: 先App中請(qǐng)求數(shù)據(jù),在index.js使用數(shù)據(jù)
第二部分:如何開(kāi)通一個(gè)小商店