這應該是uni-app在H5平臺的相對其餘小程序框架更友好的地方css
隨着微信小程序的火爆及百度、頭條小程序的持續推動,跨端開發的需求愈發迫切,業界隨之出現了一系列的跨端框架,但對於H5平臺跨端支持的都不太完全:html
Vue
技術棧的小程序框架:對於H5平臺支持廣泛較弱React
技術棧的小程序框架:雖支持生成可在H5端運行的代碼,但僅僅是代碼可運行,離項目直接發行上線的目標還存在必定差距。鑑於客觀需求及現狀,DCloud前端團隊響應開發者完全跨端的呼聲,通過連續奮戰,uni-app
1.2版本支持發行到H5平臺,完整模擬小程序生命週期、事件處理、組件規範等,真正實現「一套代碼、多端發行」的目標。前端
本文主要分享,咱們在實現uni-app
發行到H5平臺時,在引擎實現、差別抹平、性能優化方面都作了哪些工做。vue
uni-app
設計的開發標準是:Vue.js的語法 + 小程序的API + 條件編譯擴展平臺個性化能力。其中:webpack
Vue.js
的語法在微信小程序端,uni-app
是經過編譯器 + 運行時加強實現,在H5端則默認支持;uni-app
若要發佈到H5平臺,則需完整模擬實現小程序運行時環境。以下是一個簡易的小程序運行時框架,核心是一個響應的數據綁定系統。git
爲實現小程序、H5兩端的完整跨端,uni-app
在H5平臺完整模擬實現了小程序的邏輯層和視圖層,相比業界其它跨端框架,uni-app
在H5平臺有以下幾點實現更完善。github
小程序中的導航條、選項卡是經過配置文件生成的,配置後由原生組件進行渲染,uni-app
在H5平臺一樣兼容這些配置,不過會降級經過div
控件模擬實現,所以開發者無需單獨爲H5平臺添加導航條或選項卡。web
uni-app
在H5平臺實現了完整的小程序生命週期,爲此填了不少坑。舉一個詳情頁互跳的栗子:canvas
詳情A 打開 詳情B,在一般的 web 端 SPA 方案中,會在詳情A頁面獲取B詳情的數據,僅會觸發詳情頁A的updated
生命週期,不會觸發onHide
;但在小程序中,則會打開一個新的webview並加載詳情B,此時會觸發詳情A的onHide
生命週期,也會觸發詳情B的onShow
生命週期;uni-app
完整模擬了小程序的生命週期,詳情頁之間互相切換時,會觸發onHide
、onShow
等生命週期;這樣的實現,即保證了兩端兼容性,同時在詳情B返回詳情A時,詳情A已被緩存,無需再次聯網加載,也會有更高的性能。小程序
方法 | 做用 |
---|---|
onLoad | 監聽頁面加載 |
onShow | 監聽頁面顯示 |
onReady | 監聽頁面初次渲染完成 |
onHide | 監聽頁面隱藏 |
onUnload | 監聽頁面卸載 |
uni-app
對於頁面事件處理函數支持更爲全面,下拉刷新、上拉觸底等經常使用函數都可在H5平臺正常複用,無需二次開發。
方法 | 做用 |
---|---|
onPullDownRefresh | 頁面相關事件處理函數--監聽用戶下拉動做 |
onReachBottom | 頁面上拉觸底事件的處理函數 |
onPageScroll | 頁面滾動觸發事件的處理函數 |
onTabItemTap | 當前是 tab 頁時,點擊 tab 時觸發 |
uni-app
H5平臺的組件實現,有兩個特色:
navigator
等組件在H5平臺可正常跳轉微信小程序是一種 native + web 混合渲染的機制,好比小程序的導航條(navigationBar)、選項卡(tabBar)爲原生組件,但H5平臺爲純 web 渲染,導航條、選項卡均爲 web 實現,這可能引起頁面 fixed 元素 和導航條/選項卡位置發生互相遮擋的問題,以下一段 fixed 定位的代碼:
.fixed{
position: fixed;
z-index: 9999;
bottom: 0px;//底部距離爲0
background-color:peru;
}
複製代碼
在不一樣平臺上運行效果不一樣,以下圖所示:
uni-app
經過引入css變量
解決這類問題,在編譯到不一樣平臺時,給css變量
設置對應的值。
CSS變量 | 描述 | 小程序 | H5 |
---|---|---|---|
--window-top | 內容區域距離頂部的距離 | 0 | 如有導航條則爲導航條 的高度,不然爲0 |
--window-bottom | 內容區域距離底部的距離 | 0 | 如有TabBar則爲TabBar 的高度,不然爲0 |
有了css變量
,開發者若需處理 fixed 定位的元素,只需像以下方式編寫便可:
.fixed{
bottom:var(--window-bottom)
}
複製代碼
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平臺時也作了不少性能優化。
uni-app
有8大類、幾十個內置組件,但開發者實際開發時僅會使用其中的一部分組件,好比不少App不會用到map
、canvas
等組件,若打包時將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 |
當打包構建 SPA 應用時,Javascript 包會變得很是大,影響頁面加載。雖然開發者基於Vue
的異步組件和 Webpack
的code-splitting 功能,能夠實現路由組件的懶加載,但開發者需調整.vue
源碼及Webpack
配置,有必定的學習門檻,且比較繁瑣。
uni-app
在H5平臺實現了自動按需加載路由組件,開發者無需調整組件開發方式,僅需關心業務實現便可。
uni-app
爲提高性能體驗,在不少細節上都有特殊設計。好比常見的 SPA 框架通常採用div
區域滾動,uni-app
爲改善用戶體驗,使用的是body
滾動,由此填了不少坑,好比不一樣頁面的background-color
,若使用div
滾動,則在編譯階段就可完成樣式定義,但基於body
滾動,就須要在頁面前進、後退時動態設置body
的背景色。
uni-app
在H5平臺的相關代碼均已所有開源,詳見uni-app,歡迎你們 star 支持.