182
技術社區[雲棲]
小程序技術方案探討
微信小程序上線大半年,大部分技術原理也有文章介紹了,本文嚐試從需求出發探討微信小程序技術方案的來源,以及最近公測的支付寶小程序技術方案上的考量。
微信小程序
微信小程序的需求是讓第三方開發者可以接入,可以使用微信的提供的接口去開發應用嵌入在微信裏。對於這個需求,最簡單的實現方案是:讓外部開發者開發純H5應用,在微信的 H5 容器裏打開,容器提供微信 native 接口,就行了。在有小程序之前,已經有很多這樣的業務接入,像京東購物,錢包裏的各種友商大眾點評/滴滴出行等,都可以認為是一個“小程序”,內嵌在微信裏,能調用微信 native 接口,是不是沿著這種模式下去,把相應的接口開放給第三方,再提供個入口就行了?
實際上這種簡單的方案不能滿足需求,在產品上微信小程序有另外兩個很重要的需求:
- 管控。作為一個平台必須對接入的應用有管控能力,必須能盡量精確控製應用的內容和類型,畢竟若出現非法應用平台是要承擔責任的,H5 的方式太過自由,開發者可以隨時改變整個應用的內容,平台難以檢測到這些改變,無法管控。另外H5開發質量參差不齊,平台也無法管控,這對於一向有潔癖的微信來說無法接受。
- 體驗。作為一個“小程序”需要讓體驗接近原生,而上述像京東購物這些普通 H5 頁麵的體驗不太行,包括啟動速度/頁麵切換流暢度都有問題,跟原生體驗沒法比。
所有小程序的技術方案都是為了這兩個需求服務。
管控
為了滿足管控的需求,技術上微信做了兩個事情:小程序框架和分離JS運行環境。
框架/DSL
H5太自由,首先要做的就是限製它的自由,怎樣限製?自然是做個框架套住,讓開發者隻能按框架的規則去開發。那應該使用怎樣的框架?
在 PC SNS 時代,Facebook 做開放平台時有類似的場景,為了第三方開發者能在 Facebook 平台上開發,同時又能限製住開發者的權限,Facebook 要求開發者使用自定義的一套 DSL(FBML)去開發,而這個 DSL 能怎麼寫,最終能轉成什麼,如何執行,都是平台說了算,同時也可以很方便做代碼掃描和審查。
小程序正好能借鑒這樣的設計思路,界麵不使用 HTML 開發,而是自定義一套 DSL,這樣就可以很容易配合審核/代碼掃描/域名限製等係列措施去做管控,這就是小程序這一套框架的來源。這套框架通過 wxml 去描述界麵,wxss 描述樣式,js 去處理邏輯和數據,再通過工具一係列處理把這些轉為 HTML/CSS/JS 顯示在 webview 上,並處理界麵交互和數據更新。
這樣用一套框架去限製開發方式,再造一層 DSL,除了管控外還有一個好處,就是容易進行針對性優化,DSL 最終轉成什麼,最終如何執行渲染都由框架決定,上層不感知,可以做成由 webview 渲染,有條件也可以用類似RN的方案自己實現渲染層。
JS 環境
通過框架限定開發方式後,管控上還有個問題,就是如何限製應用端類JS語言調用dom API?小程序跑在 webview 上,渲染時必然要通過 JS 操作 dom,如果小程序框架和應用 JS 代碼都有權限操作 dom,應用可能會通過各種方式在上線後繞過檢查,注入 JS 調用 dom 接口去修改頁麵結構和內容,變成跟審核時不一樣的應用。怎樣能限製應用的 JS 調用 dom 的權限?微信想了個比較創新的解決方案,就是:JS 運行環境與瀏覽器分離,運行在單獨的 JS 引擎上。
脫離了瀏覽器,JS 自然沒有 dom 的調用權限,任何跟 webview 界麵相關的 API 都無法拿到。而小程序框架核心JS運行在webview上,可以自由操作dom,通過小程序框架定義的機製,應用端通過 wxml/wxss 定義固定的渲染樣式,JS 端隻管數據綁定,數據可以通過 native 橋梁從 JS 引擎傳遞到 webview,JS端無法做任何渲染相關的操作,可以對渲染的內容有完整的管控權。
獨立的 JS 運行環境除了滿足管控需求外,也額外帶來一些好處和一些壞處,好處在於:
- 多個頁麵可以共享一個 JS 運行環境,數據可以很方便地共享,整個小程序生命周期裏共享同一個上下文,更接近 APP 的開發體驗。
- JS 與頁麵渲染分離並行執行,不會出現 JS 執行時卡住頁麵渲染的情況,提升渲染性能。
壞處在於:
- 多了數據序列化傳輸的開銷,數據需要從 JS 傳到 webview 給視圖層渲染,需要序列化為字符串格式再進行傳輸。
- iOS 上 WKWebview 的 JS 引擎比 JavaScriptCore 多了 JIT 優化,執行速度快很多倍,小程序的 JS 運行在 JavaScriptCore 上無法享受到這個優化。
由於管控需求過於剛需,這個方案帶來壞處可以接受。
體驗
小程序最主要的兩個技術點 — 框架和JS運行分離 都是源自管控需求,而體驗上的需求就是由各種細致的性能優化組成了,很多文章也分析過,這裏簡單說下,包括:
- 離線包:整個小程序打包下發,不需要打開每個頁麵都去請求,減少第二次打開時間以及頁麵切換時間。
- 預加載:預加載多一個wkwebview放後台,用戶打開小程序時省去初始化wkwebview時間。另外對於一個小程序內的頁麵切換,得益於框架的設計,可以做到預渲染模板,切換時再填充數據,加快渲染速度。
- 緩存:退出小程序後不會立即銷毀,會在後台繼續跑5分鍾,在這期間用戶切回小程序時速度快。
- 視覺:小程序首次加載通過loading和動畫的方式過渡,拒絕白屏,給人一種快的感覺,同時提升了小程序的標識度。
剩下的就是圍繞小程序這個平台的周邊建設了,像組件,native接口,IDE,後台管理,版本管理,權限控製等基礎支持。
支付寶小程序
策略
微信小程序推出時主要麵向的場景是線下,希望商家能開發小程序,做像點菜買票這樣的即時性應用,提升線下商戶體驗,支付寶作為線下戰場的主要競爭對手自然要跟進。
支付寶要做小程序應該怎麼做?可以根據自身的情況,定義另一套技術體係,讓第三方接入。但這樣的話第三方如果要同時接入微信和支付寶,需要開發兩套程序,成本很高,而微信有先發和平台優勢,很可能變成隻開發微信小程序而放棄接入支付寶小程序,所以最好的做法是降低這裏的接入成本,讓微信小程序的代碼可以複用在支付寶小程序上。所以支付寶小程序對外的框架/API/組件必須是跟微信小程序接近或力求一致,技術上沒得選擇,所以可以看到支付寶小程序公測版的文檔很多跟微信一致。
實現
支付寶小程序框架對外接口是跟微信一樣,又因為同樣有管控/安全和體驗的需求,有些策略是類似的,像獨立 JS 環境,離線包,緩存策略等,但在小程序框架的實現上就跟微信完全不一樣。小程序框架作為一層屏蔽了實現細節的 DSL 層,最終通過什麼技術手段實現都可以是由框架底層自由定製的,這邊底層架構基於螞蟻前端團隊多年的積累,最終 web 版小程序是以 react 為基礎實現。
React Native
除了對外的跟微信一致的 web 版小程序,內部一直在嚐試 React Native 版小程序,渲染層不適用 webview,而是用 RN 去渲染,提升性能和體驗,這也是小程序 DSL 層帶來的好處,底層渲染引擎可以很方便地替換實現方案,甚至同時存在多套方案。
很多人問為什麼不用 weex,按我理解首先是螞蟻的前端技術棧基於 react,切換成本高,另一個 RN 相對 weex 成熟度高,社區支持度高,並保持著不間斷的更新,相對友好。
RN 本身不跨平台,iOS/Android有各自的寫法,在 RN 的使用上,業界很多人各自實現了基於 RN 的跨三端或兩端的開發方式(例如JDReact),也就是一次開發,能同時支持 RN 在 iOS / Android 兩端做原生渲染,也支持 fallback 到 webview 渲染。這裏小程序也算是這樣一套方案,上層通過自定義 DSL 開發業務,部署時通過工具分別轉換成三個平台不同的代碼,在三個平台運行。
內部應用
小程序是一套對外的方案,主要用於第三方應用接入,因為上文也說了,框架上很多技術方案都是為了滿足對第三方管控和安全方麵的需求,而小程序相關的很多體驗優化其實用純 H5 也可以做到,內部業務用 web 版小程序開發並沒有帶來什麼好處,反而增加學習成本。但 RN 版小程序不一樣,它有一些優勢,包括:
- RN 相對 webview 性能優勢明顯,秒開率高,交互也更流暢。
- 相對於單純使用 RN 開發,使用小程序可以屏蔽平台差異,實現跨平台一次開發。
- 小程序有配套的開發環境/IDE/包管理等基礎設施支持,無需再重複建設。
- 對外業務開發者小程序不是全新的一套開發方式,在業界可複用,對內框架實現者使用RN,有強大的社區支持。避免了另外創建一套隻能在內部使用的技術體係,極大降低技術成本。
基於這些原因,在螞蟻財富這邊一些內部原本應該使用 H5 實現的業務,也正嚐試更多地使用小程序實現,以提升用戶體驗,目前部分基於小程序 RN 版開發的業務已在線上穩定運行,後續也會繼續嚐試把小程序 RN 版持續打造成高性能穩定的三端統一動態化方案。
最後
本文隻是嚐試粗略探討從微信小程序到支付寶小程序一些技術方案的演進,關於支付寶小程序更多的實現細節和數據可以參考主創人員的文章:
支付寶小程序技術曆程 - 框架概述:https://www.atatech.org/articles/88918
小程序在螞蟻聚寶上的首發實踐:https://www.atatech.org/articles/72438
支付寶小程序Native版介紹:https://www.atatech.org/articles/89573
最後必須打個廣告,歡迎轉崗螞蟻財富,一起完善 RN 版小程序,探索最佳的跨平台動態化方案,團隊推崇全棧,iOS/Android/H5 都歡迎。
最後更新:2017-09-19 11:32:56