uni-app 2.2發佈,大幅優化H5端性能體驗

uni-app發佈以來,已經服務了幾十萬開發者。讓咱們意外,或者說驚喜的是,有大量開發者用uni-app只編寫H5版,並無多端發佈(可參考案例)。javascript

這其實也符合uni-app的初衷,uni-app的定位並非須要多端發佈時才用uni-appuni-app是一個使用vue.js開發全部前端應用的統一框架。對於一個前端工程師來講,使用uni-app作多端效率更高,作單一端也沒問題,並在各端有很多出彩的地方。php

過去的版本迭代中,uni-app已經成爲了更好的小程序開發框架,比使用原生微信開發更有優點。(見評測css

uni-app2.2的新版中,咱們大幅優化了H5版的性能,讓使用uni-app開發的H5,性能體驗和直接使用vue.js開發H5拉齊。前端

可能很多開發者有某種誤解:多端框架要適配多端,因此性能確定不如原生。咱們想糾正一下:vue

  1. 切忌想固然,多看數據評測。還不信就本身動手實驗
  2. 請問使用vue.js開發的web性能好,仍是使用原生js開發web性能好?答案是:使用vue.js框架。爲何?由於它在底層會自動優化數據同步、虛擬dom,比大多數開發手動寫的代碼要更高效。一樣的,使用uni-app也如此,框架底層的優化處理比大多數開發者手動寫setdata或dom操做更高效。
  3. 多端適配不少是在編譯時作的,並不影響運行時的性能

優化難點

想優化H5端的性能,並非一件容易的事。java

「功能全面」和「小巧極速」,這是一對最難調和的冤家。nginx

爲了保障多端的一致性,uni-app實現了一套小程序的H5版Runtime,支持各類小程序的組件、API、配置。因此uni-app的H5版擁有比其餘框架更好的跨端一致性。git

但這也形成了老版的uni-app,輸出H5端時,包體積過大(框架未壓縮前有500k,部署gzip後162k)。es6

這確實是一個很是大的runtime,包含了幾十個內置組件,數百個API。並且這些API仍然在快速增長中。github

不能像其餘框架同樣由於功能少,因此體積小。咱們不會用功能換性能,咱們須要更好的方案。

優化方法

uni-app包含幾十個內置組件、數百個API,是個「大而全」的框架;但開發者在開發具體應用時,未必能使用到全部的組件及API。若能根據項目具體狀況,刪掉沒用到的組件及API,保留對項目有用的組件及API,即可精簡框架、減小體積,這便是「搖樹優化」的思路。

搖樹優化(Tree-Shaking),顧名思義,搖晃樹幹,將枯死無用的枝條搖掉,僅保留有用的樹枝。對應到框架層面理解,就是一個框架的衆多組件和API,能夠按需使用,把未引用的框架部分裁剪掉。Tree-Shaking 最先由 Rollup 提出,屬於死碼刪除的一種形式。

常見的前端框架搖樹,通常是基於明確的import引用關係。好比引用某UI庫時,在A頁面使用該UI庫的search組件,此時須要寫js代碼import這個search組件,那麼搖樹分析就很容易。

uni-app和小程序同樣,內置組件和API是不須要import的,這提高了開發的易用性,但此時卻加大了搖樹的難度,依靠簡單的import分析沒法實現搖樹了。

幸虧對DCloud團隊而言,AST語法分析是看家本事,多年來HBuilder以js和vue語法提示著稱。經過AST分析,uni-app新版能夠精準斷定這個項目使用了哪些組件和API。

不過這還不夠,分析工程源碼使用了什麼組件和API以後,還得考慮框架各組件和API之間可能存在依賴和耦合關係,這須要進一步的計算和關係梳理,具體而言:

  • 組件:經過vue-template-compiler分析出來的AST,映射生成項目中使用到的組件清單,而後再基於Webpack插件將使用到的組件打包構建
  • API:編譯器維護一個 api 依賴關係的 json 文件,該 json 文件描述每一個 api 可能依賴的文件,而後 babel 查找到對應的 api 後,根據api 的依賴關係自動導入,從新編譯

在工程師持續的加班奮戰後,uni-app終於推出了全新的2.2版本,解決了這些難題,大幅下降了發行包體積,gzip後的框架體積,從162k下降到92k,僅至關於你在工程中引用了vue.jsvue-router、以及部分es6 polyfill庫。(後續有詳細比較)

除了大幅下降發行包體積,新版還調整了預載策略,能夠進一步加快頁面的渲染速度。

優化結果

搭建環境

咱們使用vue-cli建立uni-app默認模板

vue create -p dcloudio/uni-preset-vue my-project

項目建立後,編譯生成H5端的發行目錄

npm run build:h5

而後配置nginx服務器,指定root目錄並啓用gzip壓縮,示例以下:

server {
    ...
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_comp_level 4;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    ...
}

runtime 動態裁剪

而後經過 Chrome DevTools 的 Network 面板,查看優化前的首頁網絡請求包大小,結果以下:

而後啓用H5平臺的優化開關,從新查看首頁的網絡請求包大小,結果以下:

能夠看到框架主庫(chunk-vendors.js)從162k變爲92.8k,體積壓縮43%!

實際上,框架主庫主要分爲三個部分:

  • vue/vue-router基礎庫
  • es6 polyfill庫
  • uni-app runtime(組件&API實現)

若是對這三個部分再拆開對比,咱們會看到uni-app組件庫優化比例更高:

vue/vue-router es6 polyfill庫 uni-app runtime 累計
優化前 38k 43k 81k 162k
優化後 38k 26k 28.8k 92.8k

Tips:

  • uni-app runtime從81k瘦身爲28.8k,裁剪比例達到64%
  • 新編譯器對es6的使用也作了動態掃描,項目中用到的es6語法(包括uni-app runtime用到的es6語法),纔會打包對應的polyfill實現,故es6 polyfill庫從43k瘦身爲26k

腳本執行時間

而後,咱們再經過Chrome DevTools 的 Performance 面板,查看優化先後的性能數據,對比結果以下:

能夠看出,最耗時的腳本執行時間,從227ms提高爲154ms,時間提高達到32%。

如何使用

雖然內部實現比較複雜,但uni-app對外暴漏了簡單的配置,開發者只需在配置文件中打開一個開關便可。具體在 manifest.json 中h5節點配置以下選項:

"h5" : {
    "optimization":{
        "treeShaking":{
            "enable":true //啓用搖樹優化
        }
    }
}

2.2版的其餘優化

uni-app2.2版中,還開放了package.jsonvue-config.js的自定義,開發者能夠自由的配置編譯策略。

如今能夠自定義支持全部小程序平臺,包括釘釘小程序、高德小程序、抖音小程序...等。這樣除了標準的8大平臺(iOS、Android、H五、微信小程序、支付寶小程序、百度小程序、頭條小程序、QQ小程序),這些生態的子生態也能夠分版本條件編譯。

一樣,也支持對H5端進行多子端編譯,好比微信裏的內嵌的H五、App裏內嵌的H5...均可以分開條件編譯。

如此靈活的條件編譯,對於一套工程的多端發佈、共享複用、同步升級,有莫大的好處。即使是僅開發H5版,uni-app的多端條件編譯也提供了更靈活和強大的工程化能力。

2.2版本還能夠設置各類靜態資源、js、小程序自定義組件的編譯和拷貝策略。若是你以前的h5項目或小程序項目想轉換至uni-app下,又不想挪動某些目錄結構,那麼在vue-config.js裏配置策略便可。

使用uni-app開發H5和直接開發H5相比的優點

在與直接開發h5拉齊性能的基礎之上,uni-app給開發者提供了更多優點:

  1. 開發效率
    uni-app提供了大量適合手機頁面的基礎組件(其實就是小程序組件)。還提供了擴展組件uni ui。插件市場更有600多款插件。

不管開發者想找一個電商的模板,仍是找一個圖表組件,均可以手到擒來。開發效率更勝以往。

  1. 多端編譯
    咱們開發H5時,常常須要給瀏覽器輸出一份、給微信等超級App輸出一份、給自家的App輸出一份。甚至不一樣地域、不一樣用戶畫像,都會輸出不一樣版本。之前,開發者只能對js部分進行條件編譯,甚至不得不建多個倉庫進行多版維護。

uni-app解決了這些煩惱,它的條件編譯很是靈活強大:

  • 不論是組件、js仍是css,均可以按平臺編譯輸出
  • 還能夠多個平臺進行「與和或」的運算編譯
  • 除了文件中的代碼,整個文件、甚至整個目錄,均可以條件編譯

例如微信、QQ等在支持x5內核的內置瀏覽器中,使用x5的視頻同層渲染;或者在微信服務號中調用微信卡劵,這段代碼只有build到 dist/h5-weixin 這個目錄下的版本纔會被編譯進去,其餘平臺不會有這段代碼

// #ifdef H5-WEIXIN
wx.openCard({
    cardList: [{
        cardId: '',
        code: ''
    }]// 須要打開的卡券列表
});
// #endif

後續計劃

接下來,uni-app在H5端將提供服務端渲染機制(SSR)和PC寬屏界面適配優化,在追求性能極致和大一統的道路上繼續前進!

相關代碼所有託管在 github,歡迎你們 star 或提交 pr!

相關文章
相關標籤/搜索