京東小程序 Taro 開發對比原生開發測評


Taro 已經 100% 支持轉換京東小程序,受到了很多同學的關注。當中有歡呼雀躍的聲音:“一鍵轉換為京東小程序,終於可以准時下班啦”。也有對 Taro 不太了解的同學提出了一些疑問:“轉換的效果如何?”、“轉換后代碼的性能是否達標?” 等等。

針對各種疑問,我們從性能與開發體驗的角度切入,把京東小程序原生開發與 Taro 開發進行了一番對比。

性能對比

針對性能的問題,我們分別測試了 Taro 空項目的包大小和 Taro 在長列表中的表現。因為包大小會影響小程序的首次加載速度,而長列表則是常常出現性能瓶頸的場景。

Taro 空項目包大小

目前各小程序都有對主包的大小進行限制,如京東小程序限制為 5M、微信小程序限制為 2M。這是因為初次進入的速度對於用戶的體驗非常地關鍵,而主包體積越大下載的時間就最長。因此小程序框架的大小也成為了開發前框架選型的重要參考指標之一,倘若框架體積過大,就會壓縮業務邏輯的可用空間。

下列圖片分別是 Taro 運行時框架壓縮前后的大小,可以看到壓縮后僅為84k,對主包空間的影響十分小。

壓縮前:

QQ20191025-141758

壓縮后:

QQ20191025-142728

長列表渲染表現

benchmark 介紹

我們參照 js-framework-benchmark 編寫了一份 benchmark,測試對比了 Taro 代碼與原生代碼在長列表場景下的渲染表現。

測速指標
  • 初始化:從進入頁面開始到完成 40 個商品的渲染。

  • 創建:頁面 onLoad 后創建 40 個商品。

  • 增加:往已創建了 40 個商品的列表中每次增加 20 個商品。

  • 部分更新:在 400 個商品中更新每第 10 個商品的名稱。

  • 交換:在 400 個商品中交換其中兩個商品的位置。

  • 選中:點擊商品圖片,改變商品名稱的字體顏色。

計時點

Taro

開始:事件響應函數的頂部。

結束:setState 回調函數的頂部。

原生小程序

開始:事件響應函數的頂部。

結束:setData 回調函數的頂部。

其它

benchmark 倉庫:Github

Taro 版本:1.3.21

測試機型:魅藍 note

測試方法:每組測試 10 條數據,去除其中最大值與最小值后求平均值

測試結果

因為在京東小程序與微信小程序中,setData 的 callback 的觸發時機稍有不同,所以分開列出

操作 Taro jd 原生京東小程序
初始化 150 123
創建 87 85
部分更新 125 235
交換 140 213
選中 131 155
操作 Taro weapp 原生微信小程序
初始化 1155 1223
創建 500 408
部分更新 167 307
交換 252 309
選中 193 178

經測試發現,列表的長度會對增加操作的耗時產生影響:列表越長,增加操作的耗時越久。因此不能簡單地對 N 次增加操作求平均增加耗時。這里我們選擇使用折線圖來展現出隨增加操作次數的變化,渲染耗時的變化趨勢。

京東小程序——增加

微信小程序——增加

測試結論

創建

在創建時,Taro 會對數據做一些處理,因此會比原生稍慢。

初始化

初始化與創建相比,差別是引入了頁面構造耗時。即初始化耗時 = 頁面構造耗時 + 創建操作耗時

Taro 在頁面初始化、創建操作時都會對數據進行處理,因此整個初始化耗時會比原生稍慢。

那為什么微信小程序中 Taro 初始化耗時更短呢?在 benchmark 中 Taro 和原生分別在 componentWillMountonLoad 渲染列表,而 Taro 使用 Component 構造頁面,componentWillMount 其實是在 attached 生命周期中觸發。因為在微信小程序中 attachedonLoad 早觸發得多,所以會出現如此現象。

選中

因為 Taro 只是把回調函數包裝了一層,處理了事件參數和 this 等,所以和原生的速度相當。

部分更新、交換、增加

Taro 的速度會優於原生。原因是 Taro 會先對將要 setData 的數據和當前 data 的數據做一次 diff,這能夠大大減少 setData 的數據量,加快渲染速度。對比兩個折線圖可以得知,數據量越大,diff 的優化收益也越大。

Taro 對小程序的性能優化

setData

在小程序中,性能的問題主要在於單次 setData 數據量過大和頻繁調用 setData 上。Taro 利用 diff 解決了單次 setData 數據量過大的問題,而對於頻繁調用 setData 也有解決的辦法。

Taro 的 setState 遵循 React 規范,不同於 setData 的同步更新,它會異步地去更新視圖。因此假設開發者在單次事件循環中多次調用 setState,最后也只會在下一個事件循環中進行一次 setData。

跳轉預加載

小程序由 A 頁面跳轉到 B 頁面的過程中,從 A 頁面發起跳轉到 B 頁面觸發 onLoad,有着 300~400 毫秒的延時。Taro 提供了 componentWillPreload 鈎子,鈎子會在發起跳轉后立即執行。開發者可以盡早地在鈎子里做一些數據拉取的工作,相比在 onLoad 觸發后再去拉取數據就能夠節省 300~400 毫秒的延時。

shouldComponentUpdate & Taro.PureComponent

開發者的 Class Component 可以繼承 Taro.PureComponent,這樣組件在更新前會對新舊 props 和新舊 state 各做一次淺對比,避免不必要的更新。當然開發者可以自己實現 shouldComponentUpdate,通過手動控制新舊 props 和新舊 state 的對比,決定是否更新組件。

Taro.memo

如果開發者書寫的是函數式組件,則可以利用 Taro.memo 實現 shouldComponentUpdate 的相同功能。

開發體驗對比

語法

京東小程序的原生語法和微信小程序相仿,都是類 MVVM 語法,沒有接觸過小程序的開發者有一定學習成本。另外樣式語法為 css 的子集,其中自適應尺寸單位為 rpx,這樣意味着如果我們需要 css 預處理器時需要手動配置工作流,並且在編寫樣式時處處注意尺寸單位的轉換。

目前 Taro 遵循 React 語法(將來會支持所有 Web 前端框架),JSX 令我們的代碼更加靈活。因此擁有 React 開發經驗的開發者可以馬上上手 Taro 的開發工作。在樣式方面 Taro 支持在創建項目時選擇是否使用 css 預處理器,選擇后會自動配置相應的工作流。對於樣式單位 Taro 也會把用戶編寫的 px 數值自動轉換成對應的 rpx 數值,開發者無需再分心處理各平台的樣式單位。

項目結構

原生開發中,頁面和組件各由4個文件(js、jxml、jxss、json)所組成,代碼管理相對麻煩。

Taro 中頁面和組件均由一份 js 文件和一份樣式文件組成,創建與維護十分容易。

開發生態

微信小程序經過不斷迭代,相繼推出了插件系統和支持引用 npm 包的功能。但京東小程序暫不支持前兩者,京東小程序社區也還沒打造起來,開發生態資源十分匱乏。

Taro 中不但能自由引用 npm 包,而且還大量支持 React 社區中沉淀的優秀工具和庫,如 react-redux、mobx-react 等。

開發輔助

京東小程序原生開發不支持 Typescript,只能在 IDE 的編輯器中有自動補全功能,編碼效率不高,同時也容易出錯。

Taro 完美支持 Typescript,自帶代碼智能提示和代碼實時檢查功能,能讓開發效率大大提升。

寫在最后

看到這里大家可能會問,Taro 性能真的優於原生嗎?其實並不然,針對每個場景,我們都可以用原生寫出性能最佳的代碼。但是這樣做工作量太大,實際項目開發中需要掌握效率與優化之間的平衡。Taro 的優勢在於能讓我們在書寫更有效率的代碼、擁有更豐富的生態的同時,還帶來了不錯的性能。

最后,歡迎大家來使用 Taro 開發各端應用,有任何開發問題或合作意願請聯系 taro@jd.com,我們會第一時間回復。

相關鏈接

Taro 官方網站

Taro 文檔

Taro 論壇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM