溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

RN 技術(shù)探索:Hermes Engine 初探

發(fā)布時間:2020-08-11 08:02:23 來源:ITPUB博客 閱讀:618 作者:滴滴技術(shù) 欄目:編程語言

RN 技術(shù)探索:Hermes Engine 初探

桔妹導(dǎo)讀:自從 Google 的 Flutter 發(fā)布之后,F(xiàn)acebook 對 React-Native 的迭代開始快了起來,優(yōu)化 React-Native 的性能表現(xiàn),避免被 Flutter 比下去。最近一個比較大的動作是開源了一個 JavaScript 引擎,并將其包含到 React-Native 中。那么這款引擎它有什么不同,相比 V8、JSC 這些 JavaScript 引擎又有什么優(yōu)勢呢,現(xiàn)在本文來為你揭曉。

1.Hermes 引擎是什么,優(yōu)勢有哪些?

重要的事情提前說:Hermes 引擎是 Facebook 研發(fā),在 React-Native Android 端用于替換 JavaScript Core 的 JavaScript 引擎。Hermes 引擎的優(yōu)勢是適合移動端的輕量級 JavaScript 引擎,使用 aot 編譯,可以減少 Android 端內(nèi)存使用,減小安裝包大小,提升執(zhí)行效率。

2.什么是 JavaScript 引擎?

JavaScript 引擎是一個專門處理 JavaScript 腳本的虛擬機(jī),一般會附帶在網(wǎng)頁瀏覽器之中。

3.主流 JavaScript 引擎

V8(Google)、JavaScriptCore(Apple)、SpiderMonkey(Firefox)

4.RN 中的 JavaScript 引擎

Weex,Android:V8,iOS:JavaScriptCore

RN,Android:JavaScriptCore(Hermes、V8),iOS:JavaScriptCore(Apple 要求)

注:Hermes Engine在React-native 0.60.2 版本后支持

5.Hermes 的特色
  • 預(yù)編譯字節(jié)碼(引擎加載二進(jìn)制代碼效率高于運(yùn)行JS腳本)

  • 無 JIT 編譯器(減小了引擎大小,優(yōu)化內(nèi)存占用,但直接運(yùn)行 JS 腳本的性能差于 V8 和 JSC)

  • 針對移動端的垃圾回收策略



6.優(yōu)化原理


RN 技術(shù)探索:Hermes Engine 初探截取自code.fb.com
傳統(tǒng) JavaScript 引擎通常是以上圖的模式完成代碼執(zhí)行的,編譯階段只完成 babel 轉(zhuǎn)義和 minify 壓縮,產(chǎn)物還是 JavaScript 腳本,解釋與執(zhí)行的任務(wù)都需要在運(yùn)行時完成(如 V8 引擎,還會在運(yùn)行時將 JavaScript 編譯為本地機(jī)器碼)很明顯缺點(diǎn)就是在運(yùn)行時需要邊解釋邊執(zhí)行,甚至需要占用系統(tǒng)資源執(zhí)行編譯任務(wù)。
RN 技術(shù)探索:Hermes Engine 初探
截取自code.fb.com
Hermes 引擎使用了 aot 編譯的方式,將解釋和編譯過程前置到編譯階段,運(yùn)行時只完成機(jī)器碼的執(zhí)行,大大提高了運(yùn)行效率。
7.已有項(xiàng)目接入 Hermes
  • 升級 React-Native 及相關(guān)庫升級(成本較?。?/span>

  • 因?yàn)?React-Native 0.60.x 變更為依賴 AndroidX,所以 Android 項(xiàng)目需要使用 28 以上版本編譯,適配 Android 高版本,且需要遷移到 AndroidX(成本較大)

  • 修改 build.gradle,添加 Hermes 相關(guān)屬性及依賴(成本較?。?/span>

8.是否支持 CodePush?
Hermes 引擎預(yù)編譯后的產(chǎn)物與RN原方式相同,都是在 assets 文件夾下生成的 index.android.bundle 文件。RN 原方式中 index.android.bundle 是經(jīng)過壓縮的 JavaScript 腳本文件,Hermes 預(yù)編譯后則是二進(jìn)制文件。因?yàn)橹挥挟a(chǎn)物文件格式的區(qū)別,并沒有修改原有JS Bundle 的加載方式,所以 CodePush 可以繼續(xù)使用。
目前 code-push 的兩種發(fā)布模式支持情況:
發(fā)布方式是否支持備注
code-push release-react
支持,但無法產(chǎn)生預(yù)編譯腳本產(chǎn)物
需依賴react-native bundle命令完成腳本打包,該命令尚不支持預(yù)編譯
code-push release
支持

9.調(diào)試效率
Debug 模式下 Hermes 不開啟預(yù)編譯以支持 Hot Reload ,缺點(diǎn)是 Release 模式下所有Hermes 引擎優(yōu)勢都不存在,甚至因?yàn)闊o JIT 導(dǎo)致性能還要差于原有引擎。但開發(fā)者模式并不追求性能,而更追求調(diào)試效率。

Debug 模式內(nèi)置 libhermes-inspector.so ,支持 Chrome inspect 的使用,支持 DevTools 協(xié)議,比原有 RN 調(diào)試體驗(yàn)更佳(應(yīng)用內(nèi)代理,不能同步調(diào)試原生調(diào)用)
10.ES 標(biāo)準(zhǔn)支持
Hermes 支持 ES6,緊跟最新的 JavaScript 規(guī)范。為了優(yōu)化引擎大小,不支持 RN 程序中使用較少的語言特性,如本地 eval()。
11.性能調(diào)研

包大小分析

RN 技術(shù)探索:Hermes Engine 初探
JSC 引擎 Release 包
RN 技術(shù)探索:Hermes Engine 初探
Hermes 引擎 Release 包
原包大小 20MB(JSC)
新包大小 18MB(Hermes)
包大小減小 2MB,整體減少 2MB / 20MB = 10%
分析具體包大小減小的原因可以發(fā)現(xiàn),包內(nèi)容兩者只有 lib 大小和 assets 的大小存在差異。
RN 技術(shù)探索:Hermes Engine 初探
JSC 引擎 Release 包
RN 技術(shù)探索:Hermes Engine 初探
Hermes 引擎 Release 包
對比 lib 內(nèi)容,發(fā)現(xiàn)大小差距主要是由 libjsc.so 和 libhermes.so 兩者的差距導(dǎo)致的,即 Hermes 引擎的大小。
RN 技術(shù)探索:Hermes Engine 初探
JSC 引擎 Release 包
RN 技術(shù)探索:Hermes Engine 初探
Hermes 引擎 Release 包
對比 assets 內(nèi)容,發(fā)現(xiàn)大小變化主要由 index.android.bundle ,即 JavaScript 打包產(chǎn)物引起,Hermes 模式下反而更大的原因是進(jìn)一步編譯為二進(jìn)制代碼。
兩者影響疊加導(dǎo)致整體減小,包大小得到優(yōu)化。(支持的平臺越多,包體積優(yōu)化效果越好)

內(nèi)存分析

實(shí)驗(yàn)方法:在相同的業(yè)務(wù)頁面穩(wěn)定狀態(tài)下通過 Memory Profiler 查看內(nèi)存占用情況
RN 技術(shù)探索:Hermes Engine 初探
JSC 引擎 Release 包
RN 技術(shù)探索:Hermes Engine 初探
Hermes 引擎 Release 包
原包平均內(nèi)存占用 210MB
新包平均內(nèi)存占用 190MB
內(nèi)存占用平均減小20MB以上,整體減小20MB / 210MB = 10%
分析 Profiler 數(shù)據(jù)可以發(fā)現(xiàn),內(nèi)存優(yōu)化主要發(fā)生在 Code 內(nèi)存區(qū)。
RN 技術(shù)探索:Hermes Engine 初探
JSC 引擎 Release 包
RN 技術(shù)探索:Hermes Engine 初探
Hermes 引擎 Release 包
Google 官方文檔中對內(nèi)存 Code 區(qū)的描述:
Code:您的應(yīng)用用于處理代碼和資源(如 dex 字節(jié)碼、已優(yōu)化或已編譯的 dex 碼、.so 庫和字體)的內(nèi)存。
聯(lián)系到上個章節(jié)中包大小分析中 libhermes.so 尺寸的減小,可以很容易想到,內(nèi)存占用的減少就是因?yàn)?.so 對內(nèi)存占用的減小。另外兩者對 JavaScript 內(nèi)存的占用也有細(xì)微差別,但是可以忽略不計。

TTI性能

TTI:Time to Interactive,用戶可交互時間,啟動到頁面渲染完成并且可以正常響應(yīng)用戶的輸入的時間,衡量用戶體驗(yàn)的移動端指標(biāo)。
React-Native Android 中主要是 Application onCreate 開始到 RN 組件渲染完成可交互的時間。
值得吐槽的是,在 iOS 版本的 Pref Monitor 中直接就包含了這個指標(biāo)的顯示,但是 Android 版本的 Pref Monitor 只有四個指標(biāo),且并沒有 TTI 這一指標(biāo)。
在 Android 平臺上可以通過 RN 提供的 ReactFindViewUtil 類獲取 RN 組件對應(yīng)的原生組件,注冊對應(yīng)的渲染回調(diào),在控件渲染完成時記錄TTI結(jié)束時間。

RN 技術(shù)探索:Hermes Engine 初探
JSC 引擎 Release 包

RN 技術(shù)探索:Hermes Engine 初探
Hermes 引擎 Release 包
原包 TTI 829ms
新包 TTI 694ms
TTI 減少 135ms,整體減少 135ms / 829ms = 16%
12.總結(jié)
面對 Flutter 的咄咄攻勢,React-Native 終于做出了一些改變,Hermes 作為一款適合移動端的 JavaScript 引擎,確實(shí)有其性能優(yōu)勢,希望通過本文能夠讓你更加了解 Hermes。
本文首發(fā)自普惠出行產(chǎn)品技術(shù) (ID:pzcxtech)
本文作者
?
RN 技術(shù)探索:Hermes Engine 初探
王李坤
滴滴 | 高級軟件開發(fā)工程師    哲學(xué)程序員,是個氣管炎、偽學(xué)霸,主要研究移動端技術(shù),目前負(fù)責(zé)終端技術(shù)的落地。相信“技術(shù)能夠改變世界”,喜歡學(xué)習(xí)新技術(shù)
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI