基于Taro Next(React)的微信小程序渲染

Taro 是一個(gè)開放式跨端跨框架解決方案唱捣,支持使用 React/Vue/Nerv 等框架來開發(fā)微信/京東/百度/支付寶/字節(jié)跳動(dòng)/ QQ 小程序/H5 等應(yīng)用郁稍。
本篇文章重點(diǎn)關(guān)注基于Taro Next(React)的微信小程序渲染,主要將從以下幾個(gè)方面進(jìn)行:

  • 瀏覽器渲染流程
  • React 渲染流程
  • 微信小程序渲染流程
  • 基于Taro Next(React)的微信小程序渲染流程
  • 基于Taro Next(React)的微信小程序渲染問題和解決方案

瀏覽器渲染流程

Web Rendering

用戶通過在地址欄輸入一個(gè)網(wǎng)站的URL后穿肄,內(nèi)容顯示到瀏覽器的完整過程

  1. 瀏覽器查看是否需要redirect, 如果需要闺阱,則redirect到對應(yīng)url
  2. 查看是否命中緩存焚辅,如果有直接到7己儒,如果沒有繼續(xù)3
  3. 解析域名,進(jìn)行DNS查找
  4. 創(chuàng)建http(s)連接
  5. 開始發(fā)送請求
  6. 接收服務(wù)端響應(yīng)
  7. 解析處理HTML標(biāo)記并構(gòu)造DOM樹
  8. 預(yù)加載掃描儀將解析可用的內(nèi)容并請求高優(yōu)先級資源巾腕,如CSS面睛、JavaScript和web字體
  9. 解析處理CSS并構(gòu)建CSSOM樹
  10. 下載其他資源。當(dāng)CSS被解析并創(chuàng)建CSSOM時(shí)尊搬,其他資源叁鉴,包括JavaScript文件正在下載。JavaScript被解釋毁嗦、編譯亲茅、解析和執(zhí)行。
  11. CSSOM樹和DOM樹組合 創(chuàng)建一個(gè)Render樹狗准。Render樹保存所有具有內(nèi)容和計(jì)算樣式的可見節(jié)點(diǎn)
  12. 在Render樹上運(yùn)行布局以計(jì)算每個(gè)節(jié)點(diǎn)的幾何體
  13. 將各個(gè)節(jié)點(diǎn)繪制到屏幕上克锣,在繪制或光柵化階段,瀏覽器將在布局階段計(jì)算的每個(gè)框轉(zhuǎn)換為屏幕上的實(shí)際像素
  14. 合成文檔中不同的層腔长,以確保相互重疊層以正確的順序繪制到屏幕上袭祟,并正確顯示內(nèi)容

React 渲染流程

React Render

JSX 會(huì)被編譯轉(zhuǎn)換成 React.createElement 函數(shù)的調(diào)用,其返回值就是 VNode(JS對象)捞附,虛擬DOM節(jié)點(diǎn)的描述對象巾乳。

  1. 在首次渲染時(shí),所有組件會(huì)創(chuàng)建對應(yīng)的VNode
  2. React 將 React.render 接收到的 VNode 轉(zhuǎn)化虛擬 DOM 樹
  3. 根據(jù)虛擬 DOM 樹的層級關(guān)系鸟召,構(gòu)建生成出 DOM 樹并渲染至屏幕中
  4. 狀態(tài)改變時(shí)胆绊,通過diff算法對比2課虛擬DOM樹,得到差異(patches)
  5. 將差異應(yīng)用到DOM樹上欧募,并將變化更新到屏幕中(進(jìn)行重新渲染)

Note: Fiber 是 React 16 中新的協(xié)調(diào)引擎压状。它的主要目的是使 Virtual DOM 可以進(jìn)行增量式渲染。了解更多.

對于首次渲染,React 的主要工作就是將 React.render 接收到的 VNode 轉(zhuǎn)化 Fiber 樹种冬,并根據(jù) Fiber 樹的層級關(guān)系镣丑,構(gòu)建生成出 DOM 樹并渲染至屏幕中。

而對于更新渲染時(shí)娱两,F(xiàn)iber 樹已經(jīng)存在于內(nèi)存中了莺匠,所以 React 更關(guān)心的是計(jì)算出 Fiber 樹中的各個(gè)節(jié)點(diǎn)的差異,并將變化更新到屏幕中十兢。

微信小程序渲染流程

MINA 是在微信中開發(fā)小程序的框架趣竣。其目標(biāo)是通過盡可能簡單、高效的方式讓開發(fā)者可以在微信中開發(fā)具有原生 APP 體驗(yàn)的服務(wù)纪挎。

MINA 提供了自己的渲染層描述語言 WXML 和 WXSS期贫,以及基于 JavaScript 的邏輯層框架,核心是一個(gè)響應(yīng)的數(shù)據(jù)綁定系統(tǒng)异袄。

小程序的運(yùn)行環(huán)境分成渲染層和邏輯層,其中 WXML 模板和 WXSS 樣式工作在渲染層玛臂,JS 腳本工作在邏輯層烤蜕。

小程序的渲染層和邏輯層分別由2個(gè)線程管理:

  • 渲染層的界面使用了WebView 進(jìn)行渲染
  • 邏輯層采用JsCore線程運(yùn)行JS腳本

一個(gè)小程序存在多個(gè)界面,所以渲染層存在多個(gè)WebView線程迹冤,這兩個(gè)線程的通信會(huì)經(jīng)由微信客戶端(下文中也會(huì)采用Native來代指微信客戶端)做中轉(zhuǎn)讽营,邏輯層發(fā)送網(wǎng)絡(luò)請求也經(jīng)由Native轉(zhuǎn)發(fā),小程序的通信模型下圖所示


WeChat Mini Program

渲染過程:

  • 在渲染層泡徙,宿主環(huán)境(微信App)會(huì)把WXML轉(zhuǎn)換成對應(yīng)的JS對象(可以看作與React的VNode)
  • 將JS對象再次轉(zhuǎn)換成真實(shí)DOM樹橱鹏,交由渲染層線程渲染(Weview初始化完成后的流程與瀏覽器渲染流程一致)
  • 數(shù)據(jù)變化時(shí)(在小程序容器中,邏輯層到渲染層的更新堪藐,只能通過 setData() 來實(shí)現(xiàn)莉兰。),邏輯層提供最新的變化數(shù)據(jù)礁竞,生成新的JS對象與之前的JS對象進(jìn)行diff算法對比
  • 將最新變化的內(nèi)容反映到真實(shí)的DOM樹中糖荒,更新UI

基于Taro Next(React)的微信小程序渲染流程

從實(shí)現(xiàn)原理上,開源社區(qū)的跨端框架大致分為下面兩類:

  • compile time 編譯時(shí)
    框架約定了一套自己的 DSL 模捂,在編譯打包的過程中捶朵,利用 babel 工具通過 AST 進(jìn)行轉(zhuǎn)譯,生成符合小程序規(guī)則的代碼狂男,如Taro v1/2
  • runtime 運(yùn)行時(shí)
    跨端框架真正的在小程序的邏輯層中運(yùn)行起 React 或者是 Vue 的運(yùn)行時(shí)综看,然后通過適配層,實(shí)現(xiàn)自定義渲染器岖食,如Taro Next

React 16版本帶來了全新的 fiber 的架構(gòu)红碑,代碼拆分也非常清晰,大體上可以拆分成這三大塊:

  • React component API
  • Reconciler
  • Renderer

其中渲染器Renderer負(fù)責(zé)將內(nèi)容渲染到具體的平臺(tái)上县耽。最常見的 ReactDOM 就是 web 瀏覽器平臺(tái)的自定義渲染器句喷。即當(dāng)調(diào)用操作 WEB 瀏覽器 web DOM的方法镣典,如createElement、appendhild唾琼,那么就創(chuàng)建/更新瀏覽器中的 web 頁面兄春。

擴(kuò)展閱讀,【2萬字長文】深入淺出主流的幾款小程序跨端框架原理

在一個(gè)頁面加載時(shí)需要經(jīng)歷以下步驟:

  • React把頁面渲染到虛擬 DOM 中
  • Taro 運(yùn)行時(shí)把頁面的虛擬 DOM 序列化為JSON 樹狀數(shù)據(jù)锡溯,并使用 setData() 驅(qū)動(dòng)頁面渲染
  • 小程序本身渲染序列化數(shù)據(jù)赶舆,渲染到小程序頁面
  • 數(shù)據(jù)變化時(shí),通過setData()去更新上面小程序的 JSON 樹狀數(shù)據(jù)
  • JSON 樹狀數(shù)據(jù)被更新了祭饭,小程序會(huì)觸發(fā)更新數(shù)據(jù)對應(yīng)的那塊視圖的渲染

基于Taro Next(React)的微信小程序渲染問題和解決方案

和原生小程序或編譯型小程序框架相比芜茵,基于Taro Next(React)的微信小程序渲染流程中的步驟 1 和 步驟 2 是新增的。如果頁面的業(yè)務(wù)邏輯代碼沒有性能問題的話倡蝙,大多數(shù)性能瓶頸出在步驟 2 的 setData() 上九串。
由于初始化渲染是頁面的整棵虛擬 DOM 樹,數(shù)據(jù)量比較大寺鸥,因此 setData() 需要傳遞一個(gè)比較大的數(shù)據(jù)猪钮,導(dǎo)致初始化頁面時(shí)會(huì)一段白屏的時(shí)間。這樣的情況通常發(fā)生在頁面初始化渲染的 wxml 節(jié)點(diǎn)數(shù)比較大或用戶機(jī)器性能較低時(shí)發(fā)生胆建。

解決方案:

  1. 多使用stateless component
  2. stateful component在setData的時(shí)候減小數(shù)據(jù)量
  3. 正確使用hooks dependencies, 并減少 setData 函數(shù)的調(diào)用次數(shù)
  4. Taro 3 官方也提供了一些種方式:

參考文檔:
https://developer.mozilla.org/zh-CN/docs/Web/Performance/How_browsers_work
https://reactjs.org/docs/rendering-elements.html#gatsby-focus-wrapper
https://reactjs.org/docs/reconciliation.html
http://yunlaiwu.github.io/blog/2017/08/14/react-virtual-dom-fiber/
https://juejin.cn/post/6923073253988810765
https://zhuanlan.zhihu.com/p/103506207
https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/framework.html
https://developers.weixin.qq.com/miniprogram/dev/framework/MINA.html
https://juejin.cn/post/6881597846307635214
https://juejin.cn/book/6844733744830480397
https://taro-docs.jd.com/taro/docs/optimized
https://docs.taro.zone/blog/2021-02-08-taro-jxpp

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烤低,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子笆载,更是在濱河造成了極大的恐慌扑馁,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凉驻,死亡現(xiàn)場離奇詭異腻要,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沿侈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門闯第,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缀拭,你說我怎么就攤上這事咳短。” “怎么了蛛淋?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵咙好,是天一觀的道長。 經(jīng)常有香客問我褐荷,道長勾效,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮层宫,結(jié)果婚禮上杨伙,老公的妹妹穿的比我還像新娘。我一直安慰自己萌腿,他們只是感情好限匣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著毁菱,像睡著了一般米死。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贮庞,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天峦筒,我揣著相機(jī)與錄音,去河邊找鬼窗慎。 笑死物喷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捉邢。 我是一名探鬼主播脯丝,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伏伐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起晕拆,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤藐翎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后实幕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吝镣,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年昆庇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了末贾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡整吆,死狀恐怖拱撵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情表蝙,我是刑警寧澤拴测,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站府蛇,受9級特大地震影響集索,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一务荆、第九天 我趴在偏房一處隱蔽的房頂上張望妆距。 院中可真熱鬧,春花似錦函匕、人聲如沸娱据。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吸耿。三九已至,卻和暖如春酷窥,著一層夾襖步出監(jiān)牢的瞬間咽安,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工蓬推, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妆棒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓沸伏,卻偏偏與公主長得像糕珊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子毅糟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353