使用uni-app快速將Vue專案輸出到小程式、H5

CHB發表於2018-12-21
  1. 跨端徹底,直接發行,無需二次開發;
  2. 通過Tree-Shaking搖出最小化內建元件等優化策略,提升效能

這應該是uni-app在H5平臺的相對其他小程式框架更友好的地方

背景

隨著微信小程式的火爆及百度、頭條小程式的持續推進,跨端開發的需求愈發迫切,業界隨之出現了一系列的跨端框架,但對於H5平臺跨端支援的都不太徹底:

  • Vue技術棧的小程式框架:對於H5平臺支援普遍較弱
  • 部分React技術棧的小程式框架:雖支援生成可在H5端執行的程式碼,但僅僅是程式碼可執行,離專案直接發行上線的目標還存在一定差距。

鑑於客觀需求及現狀,DCloud前端團隊響應開發者徹底跨端的呼聲,經過連續奮戰,uni-app 1.2版本支援發行到H5平臺,完整模擬小程式生命週期、事件處理、元件規範等,真正實現“一套程式碼、多端發行”的目標。

使用uni-app快速將Vue專案輸出到小程式、H5

本文主要分享,我們在實現uni-app發行到H5平臺時,在引擎實現、差異抹平、效能優化方面都做了哪些工作。

完整模擬小程式引擎

uni-app設計的開發標準是:Vue.js的語法 + 小程式的API + 條件編譯擴充套件平臺個性化能力。其中:

  • Vue.js 的語法在微信小程式端,uni-app是在mpvue的基礎上增強實現的,在H5端則預設支援;
  • 而小程式的API,其實包括三個部分:框架 + 元件(UI)+ 介面(API),這三部分在微信小程式端是內建支援的,而uni-app若要釋出到H5平臺,則需完整模擬實現小程式執行時環境。

如下是一個簡易的小程式執行時框架,核心是一個響應的資料繫結系統。

使用uni-app快速將Vue專案輸出到小程式、H5

為實現小程式、H5兩端的完整跨端,uni-app在H5平臺完整模擬實現了小程式的邏輯層和檢視層,相比業界其它跨端框架,uni-app在H5平臺有如下幾點實現更完善。

頁面配置

小程式中的導航條、選項卡是通過配置檔案生成的,配置後由原生元件進行渲染,uni-app在H5平臺同樣相容這些配置,不過會降級通過div控制元件模擬實現,因此開發者無需單獨為H5平臺新增導航條或選項卡。

生命週期

uni-app在H5平臺實現了完整的小程式生命週期,為此填了很多坑。舉一個詳情頁互跳的栗子:

詳情A 開啟 詳情B,在通常的 web 端 SPA 方案中,會在詳情A頁面獲取B詳情的資料,僅會觸發詳情頁A的updated生命週期,不會觸發onHide;但在小程式中,則會開啟一個新的webview並載入詳情B,此時會觸發詳情A的onHide生命週期,也會觸發詳情B的onShow生命週期;uni-app完整模擬了小程式的生命週期,詳情頁之間互相切換時,會觸發onHideonShow等生命週期;這樣的實現,即保證了兩端相容性,同時在詳情B返回詳情A時,詳情A已被快取,無需再次聯網載入,也會有更高的效能。

方法 作用
onLoad 監聽頁面載入
onShow 監聽頁面顯示
onReady 監聽頁面初次渲染完成
onHide 監聽頁面隱藏
onUnload 監聽頁面解除安裝

事件處理

uni-app對於頁面事件處理函式支援更為全面,下拉重新整理、上拉觸底等常用函式均可在H5平臺正常複用,無需二次開發。

方法 作用
onPullDownRefresh 頁面相關事件處理函式--監聽使用者下拉動作
onReachBottom 頁面上拉觸底事件的處理函式
onPageScroll 頁面滾動觸發事件的處理函式
onTabItemTap 當前是 tab 頁時,點選 tab 時觸發

元件規範

uni-appH5平臺的元件實現,有兩個特點:

  • 相容的元件數量更多:比如navigator等元件在H5平臺可正常跳轉
  • 元件屬性、巢狀實現更接近小程式實現

抹平引擎差異

fixed元素遮擋

微信小程式是一種 native + web 混合渲染的機制,比如小程式的導航條(navigationBar)、選項卡(tabBar)為原生元件,但H5平臺為純 web 渲染,導航條、選項卡均為 web 實現,這可能引發頁面 fixed 元素 和導航條/選項卡位置發生互相遮擋的問題,如下一段 fixed 定位的程式碼:

.fixed{
	position: fixed;
	z-index: 9999;
	bottom: 0px;//底部距離為0
	background-color:peru;
}
複製程式碼

在不同平臺上執行效果不同,如下圖所示:

使用uni-app快速將Vue專案輸出到小程式、H5

uni-app通過引入css變數解決這類問題,在編譯到不同平臺時,給css變數設定對應的值。

CSS變數 描述 小程式 H5
--window-top 內容區域距離頂部的距離 0 若有導航條則為導航條 的高度,否則為0
--window-bottom 內容區域距離底部的距離 0 若有TabBar則為TabBar 的高度,否則為0

有了css變數,開發者若需處理 fixed 定位的元素,只需像如下方式編寫即可:

.fixed{
    bottom:var(--window-bottom)
}
複製程式碼

css作用域

uni-app在開發時遵循 Vue 單檔案元件 (SFC) 規範,編譯到微信小程式時會生成對應的 wxml 檔案,最終執行時由 webview 渲染,iOS 平臺由 WKWebView 渲染,Android 平臺由 XWeb 引擎基於 Mobile Chrome 53 核心渲染;uni-app中的不同.vue頁面檔案( 編譯後的.wxml 檔案),在小程式端會由不同的 webview 渲染,故 .vue頁面檔案中的 css 作用域是天然隔離的,開發者無需在<style> 標籤上增加scoped 屬性。但H5平臺是一套SPA框架,無scoped就會變成全域性樣式,影響其他頁面。uni-app在H5平臺做了智慧處理,自動增加了scoped

平臺效能優化

效能一直是 web app 首要關注的焦點,uni-app發行到H5平臺時也做了很多效能優化。

內建元件按需打包(Tree-Shaking)

uni-app有8大類、幾十個內建元件,但開發者實際開發時僅會使用其中的一部分元件,比如很多App不會用到mapcanvas等元件,若打包時將uni-app整個元件類庫都打包進去,則會造成極大的資源浪費,延遲首頁渲染速度。

uni-app發行到H5平臺時採用了搖樹優化(Tree-Shaking)策略,將開發者專案中沒用到的元件從整個框架中“搖”掉,保證編譯後的 JS 檔案最小化。具體來說,uni-app編譯到H5平臺時分為預編譯、再編譯兩個階段,預編譯階段通過vue-template-compiler分析出來的AST,對映生成專案中使用到的元件清單,然後再基於Webpack外掛將使用到的元件編譯生成一個最小化的uni-app框架檔案。

我們以uni-app的兩個開源專案模板登入模板看圖模板為例,測試 Tree-Shaking 前後元件框架的大小,效果喜人,資料如下:

專案 優化前 Shaking優化後
登入模板 148k 64k
看圖模板 148k 53k

路由元件按需載入(Lazy-Loading)

當打包構建 SPA 應用時,Javascript 包會變得非常大,影響頁面載入。雖然開發者基於Vue非同步元件Webpackcode-splitting 功能,可以實現路由元件的懶載入,但開發者需調整.vue原始碼及Webpack配置,有一定的學習門檻,且比較繁瑣。

uni-app在H5平臺實現了自動按需載入路由元件,開發者無需調整元件開發方式,僅需關心業務實現即可。

其它方面

uni-app為提升效能體驗,在很多細節上都有特殊設計。比如常見的 SPA 框架一般採用div區域滾動,uni-app為改善使用者體驗,使用的是body滾動,由此填了很多坑,比如不同頁面的background-color,若使用div滾動,則在編譯階段就可完成樣式定義,但基於body滾動,就需要在頁面前進、後退時動態設定body的背景色。

github

uni-app在H5平臺的相關程式碼均已全部開源,詳見uni-app,歡迎大家 star 支援.

相關文章