uni-app 效能最佳化建議
執行原理
邏輯層和檢視層分離,且非H5端通訊有折損
uni-app 在非H5端執行時,從架構上分為邏輯層和檢視層兩個部分。邏輯層負責執行業務邏輯,也就是執行js程式碼,檢視層負責頁面渲染。
雖然開發者在一個vue頁面裡寫js和css,但其實,編譯時就已經將它們拆分了。
邏輯層詳解
邏輯層是執行在一個獨立的jscore裡的,它不依賴於本機的webview,所以一方面它沒有瀏覽器相容問題,可以在Android4.4上跑es6程式碼,另一方面,它無法執行window、document、navigator、localstorage等瀏覽器專用的js API。
jscore就是一個標準js引擎,標準js是可以正常執行的,比如if、for、各種字串、日期處理等。js和瀏覽器的區別要注意區分開來。
- 所謂瀏覽器的js引擎,就是jscore或v8的基礎上新增了一批瀏覽器專用API,比如dom;
- node.js引擎,則是v8基礎上補充一些電腦專用API,比如本地io;
-
那麼uni-app的App端和小程式端的js引擎,其實是在jscore上補充了一批手機端常用的JS API,比如掃碼。
檢視層詳解
h5和小程式平臺,以及app-vue,檢視層是webview。而app-nvue的檢視層是基於weex改造的原生檢視。
在iOS上,所有人都只能使用iOS提供的webview。它有一定的瀏覽器相容問題,iOS版本不同,它的表現有細微差異。
Android上小程式大多自帶了一個幾十M的chromium webview,而App端沒辦法帶這麼大體積的三方包,所以App端使用了Android system webview,而系統webview跟隨手機不同而有差異。
所以uni-app的js基本沒有不同手機的相容問題(因為js引擎自帶了),而檢視層的css,在app-vue上會有手機瀏覽器的css相容問題。所以在app-vue的場景中儘量不要使用太新的css語法,除非你不打算支援低端機。
邏輯層和檢視層分離的利與弊
邏輯層和檢視層分離,好處是js運算不卡渲染,最簡單直接的感受就是:窗體動畫穩。
如果開發者使用過App,應該有概念,webview新窗體一邊做進入動畫,一邊自身渲染,很容易卡動畫。而uni-app則無需寫預載程式碼,新窗體渲染快且動畫穩定。
但是兩層分離也帶來一個壞處,這兩層互相通訊,其實是有損耗的。
iOS還好,但Android低端機上,每次通訊都要耗時幾十毫秒。平時看不出來影響,但有幾個場景表現明顯。
- 連續高幀率繪製canvas動畫,會發現還不如webview內部繪製流程
- 檢視層滾動、跟手操作,不停反饋給邏輯層,js再處理邏輯並通知檢視層做對應更新。此時會發現互動不跟手或卡
不管app-vue/小程式,還是app-nvue,都有相同的問題。
解決這類問題,在webview渲染和原生渲染引用了不同的做法。
- webview渲染的檢視層
在app-vue和微信小程式上,提供了一種執行於檢視層的專屬js,微信叫做wxs,uni-app也沿用了這個名稱。
微信裡對wxs限制較多,只能實現有限的功能,app端(尤其是v3編譯器下)則沒有限制。
wxs中可以監聽手勢,以uni ui的swiperAction元件為例,手指拖動,側邊的列表選單項要跟手滑出,此時就需要使用wxs才能實現流暢效果。
至於canvas動畫,微信的canvas是原生的,無法運用wxs操作,且一樣有通訊折損,所以繪製動畫的效能不佳。而uni-app的app-vue的canvas是webview的,並且支援wxs操作,開發者可以在普通js中傳遞資料和指令給wxs,在wxs裡繪製動畫,將不再有通訊折損,實現更流暢的效果(app端需v3編譯器)
- 原生渲染的檢視層
在app-nvue裡,折損一樣存在。包括react native也有這個問題。weex發明了一套bindingx機制,可以在js裡傳一個表示式給原生,由原生解析後根據指令操作檢視層,這個技術在uni-app裡也可以使用。
bindingx作為一種表示式,它的功能不及js強大,但基本的手勢監聽、動畫還是可以實現的,比如uni ui的swiperAction元件在app-nvue下執行時會自動啟用bindingx,以實現流暢跟手。
app-vue和小程式的資料更新,分頁面級和元件級
對於複雜頁面,更新某個區域的資料時,需要把這個區域做成元件,這樣更新資料時就只更新這個元件,否則會整個頁面的資料更新,造成點選延遲卡頓。 這就是自定義元件編譯模式的特點。
比如微博長列表頁面,點選一個點贊圖示,贊數要立即+1,此時這個點贊按鈕一定要做成元件。否則這個+1會引發頁面級所有資料的更新。
app-nvue和h5不存在此問題。造成差異的原因是小程式目前只提供了元件差量更新的機制,不能自動計算所有頁面差量。
最佳化建議
使用自定義元件模式
使用自定義元件模式,在manifest中配置自定義元件模式(HBuilderX1.9起新建專案預設即為自定義元件模式)。
在複雜頁面中,頁面中巢狀大量元件,如果是非自定義元件模式,更新一個元件會導致整個頁面資料更新。而自定義元件模式則可以單獨更新一個元件的資料。
在App端,除了上述好處,自定義元件模式還新增了一個獨立的js引擎,加快啟動速度、減少js阻塞。
之前的非自定義元件模式已經不再推薦,如果你的應用還是非自定義組模式,請儘快升級。
避免使用大圖
頁面中若大量使用大圖資源,會造成頁面切換的卡頓,導致系統記憶體升高,甚至白屏崩潰。
尤其是不要把多張大圖縮小後顯示在一個螢幕內,比如上傳圖片前選了數張幾M體積的照片,然後縮小在一個螢幕中展示多張幾M的大圖,非常容易白屏崩潰。
最佳化資料更新
在 uni-app 中,定義在 data 裡面的資料每次變化時都會通知檢視層重新渲染頁面。 所以如果不是檢視所需要的變數,可以不定義在 data 中,可在外部定義變數或直接掛載在vue例項上,以避免造成資源浪費。
長列表
- 長列表中如果每個item有一個點贊按鈕,點選後點贊數字+1,此時點贊元件必須是一個單獨引用的元件,才能做到差量資料更新。否則會造成整個列表資料過載。(要求自定義元件模式)
- 長列表中每個item並不一定需要做成元件,取決於你的業務中是否需要差量更新某一行item的資料,如沒有此類需求則不應該引入大量元件。(點選item後背景變色,屬於css調整,沒有更新data資料和渲染,不涉及這個問題)
- app端nvue的長列表應該使用list元件,有自動的渲染資源回收機制。vue頁面使用頁面滾動的效能,好於使用scroll-view的區域滾動。uni ui封裝了uList元件,強烈推薦開發者使用,避免自己寫的不好產生效能問題。
- 如需要左右滑動的長列表,請在HBuilderX新建uni-app專案選新聞模板,那是一個標杆實現。自己用swiper和scroll-view做很容易引發效能問題。
減少一次性渲染的節點數量
頁面初始化時,邏輯層如果一次性向檢視層傳遞很大的資料,使檢視層一次性渲染大量節點,可能造成通訊變慢、頁面切換卡頓,所以建議以區域性更新頁面的方式渲染頁面。如:服務端返回100條資料,可進行分批載入,一次載入50條,500ms 後進行下一次載入。
減少節點巢狀層級
深層巢狀的節點在頁面初始化構建時往往需要更多的記憶體佔用,並且在遍歷節點時也會更慢些,所以建議減少深層的節點巢狀。
避免檢視層和邏輯層頻繁進行通訊
- 減少 scroll-view 元件的 scroll 事件監聽,當監聽 scroll-view 的滾動事件時,檢視層會頻繁的向邏輯層傳送資料;
- 監聽 scroll-view 元件的滾動事件時,不要實時的改變 scroll-top/scroll-left 屬性,因為監聽滾動時,檢視層向邏輯層通訊,改變 scroll-top/scroll-left 時,邏輯層又向檢視層通訊,這樣就可能造成通話卡頓。
- 注意 onPageScroll 的使用,onPageScroll 進行監聽時,檢視層會頻繁的向邏輯層傳送資料;
- 多使用css動畫,而不是透過js的定時器操作介面做動畫
- 如果是canvas裡做跟手操作,建議使用web-view元件。web-view裡的頁面沒有邏輯層和檢視層分離的概念,自然也不會有通訊折損。
最佳化頁面切換動畫
- 頁面初始化時若存在大量圖片或原生元件渲染和大量資料通訊,會發生新頁面渲染和窗體進入動畫搶資源,造成頁面切換卡頓、掉幀。建議延時100ms~300ms渲染圖片或複雜原生元件,分批進行資料通訊,以減少一次性渲染的節點數量。
- App端動畫效果可以自定義。popin/popout的雙窗體聯動擠壓動畫效果對資源的消耗更大,如果動畫期間頁面裡在執行耗時的js,可能會造成動畫掉幀。此時可以使用消耗資源更小的動畫效果,比如slide-in-right/slide-out-right。
最佳化背景色閃白
- 如果頁面背景是深色,在vue頁面中可能會發生新窗體剛開始動畫時是灰白色背景,動畫結束時才變為深色背景,造成閃屏。這是因為webview的背景生效太慢的問題。此時需將樣式寫在 App.vue 裡,可以加速頁面樣式渲染速度。App.vue 裡面的樣式是全域性樣式,每次新開頁面會優先載入 App.vue 裡面的樣式,然後載入普通 vue 頁面的樣式。
- 還可以在pages.json的globalStyle->style->app-plus->background下配置全域性背景色"style": { "app-plus": { "background":"#000000" } }
- 另外nvue頁面不存在此問題,也可以更改為nvue頁面。
使用nvue代替vue
在 App 端 uni-app 的 nvue 頁面可是基於 weex 定製的原生渲染引擎,實現了頁面原生渲染能力、提高了頁面流暢性。若對頁面效能要求較高可以使用此方式開發,詳見:nvue。
最佳化啟動速度
- 工程程式碼越多,包括背景圖和本地字型檔案越大,對App的啟動速度有影響,應注意控制體積。元件引用的前景圖不影響效能。
- App端的 splash 關閉有白屏檢測機制,如果首頁一直白屏或首頁本身就是一個空的中轉頁面,可能會造成 splash 10秒才關閉,可參考此文解決
- App端使用自定義元件模式時啟動速度更快,首頁為nvue頁面時啟動速度更快
- App設定為純nvue專案(manifest裡設定app-plus下的renderer:"native"),這種專案的啟動速度更快,2秒即可完成啟動。因為它整個應用都使用原生渲染,不載入基於webview的那套框架。
最佳化包體積
- uni-app發行到小程式時,自帶引擎只有幾十K,主要是一個定製過的vue.js核心庫。如果使用了es6轉es5、css對齊的功能,可能會增大程式碼體積,可以配置這些編譯功能是否開啟。
- uni-app的H5端,自帶了vue.js、vue-router及部分es6 polyfill庫,這部分的體積gzip後只有92k,和web開發使用vue基本一致。而內建元件ui庫(如picker、switch等)、小程式的對齊js api等,相當於一個完善的大型ui庫。但大多數應用不會用到所有內建元件和API。由此uni-app提供了搖樹最佳化機制,未搖樹最佳化前的uni-app整體包體積約500k,伺服器部署gzip後162k。開啟搖樹最佳化需在manifest配置,詳情。
- uni-app的App端,因為自帶了一個獨立v8引擎和小程式框架,所以比HTML5Plus或mui等普通hybrid的App引擎體積要大。Android基礎引擎約15M。App還提供了擴充套件模組,比如地圖、藍芽等,打包時如不需要這些模組,可以裁剪掉,以縮小發行包體積。在 manifest.json-App模組許可權 裡可以選擇。
- App端支援如果選擇純nvue專案(manifest裡設定app-plus下的renderer:"native"),包體積可以進一步減少2M左右。
- uni-app的App端預設包含arm32和x86兩個cpu的支援so庫。這會增大包體積。如果你在意體積控制,可以在manifest裡去掉x86 cpu的支援(manifest視覺化介面-App其他設定裡選擇cpu),這可以減少包體積到9M。但代價是不支援intel的cpu了。一般手機都是arm的,僅個別少見的Android pad使用x86 cpu。另外as的模擬器裡如果選擇x86時也無法執行這種apk。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70018483/viewspace-2901074/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 9大效能最佳化經驗總結,強烈建議收藏!
- MySQL效能最佳化之Open_Table配置引數的合理配置建議MySql
- MySQL的最佳化建議和策略MySql
- 網站建設中最佳化五個建議網站
- 針對SQL Server的最佳化建議SQLServer
- oracle 效能優化建議小結Oracle優化
- 優化 Webpack 構建效能的幾點建議優化Web
- 優化Webpack構建效能的幾點建議優化Web
- SSL證書安裝配置最佳化建議
- UITableView效能優化的幾點建議UIView優化
- MySQL 高效能優化規範建議MySql優化
- Oracle 記憶體使用建議效能檢視Oracle記憶體
- MapReduce: 提高MapReduce效能的七點建議[譯]
- Python效能優化的20條建議Python優化
- 使用 HTTP/2 提升效能的7個建議HTTP
- 使用HTTP/2提升效能的7個建議HTTP
- 使用 HTTP/2 提升效能的 7 個建議HTTP
- MySql資料庫最佳化的幾條核心建議MySql資料庫
- (1) Mysql高效能優化規範建議MySql優化
- CSS 寫作建議和效能優化小結CSS優化
- ORACLE SQL 效能優化的一些建議OracleSQL優化
- .NET程式的效能要領和優化建議優化
- 構建高效能 ASP.NET 應用的幾點建議ASP.NET
- 構建高效能 ASP.NET 應用的 12 點建議ASP.NET
- 構建高效能ASP.NET應用的幾點建議ASP.NET
- 部落格構建效能最佳化筆記 | 提速 3 倍筆記
- 8條關於Web前端效能的優化建議Web前端優化
- Web 應用效能提升 10 倍的 10 個建議Web
- 編寫高效能Javascript程式碼的若干建議JavaScript
- Oracle資料庫效能調整 - 建議器 ADVICEOracle資料庫
- ABAP程式碼執行時間最佳化的幾點建議
- 【效能最佳化】ORACLE資料庫效能最佳化概述Oracle資料庫
- Java中提升效能對程式碼作的建議(轉Mark)Java
- 來自工程師的8項Web效能提升建議工程師Web
- 對AngularJS進行效能調優的7個建議AngularJS
- [需求建議]外掛建議:建議出一個時間軸外掛
- 構建Spring Boot應用的效能監控與最佳化Spring Boot
- Unity效能最佳化CPU最佳化Unity