Taro 已經 100% 支持轉換京東小程序,受到了不少同窗的關注。當中有歡呼雀躍的聲音:「一鍵轉換爲京東小程序,終於能夠準時下班啦」。也有對 Taro 不太瞭解的同窗提出了一些疑問:「轉換的效果如何?」、「轉換後代碼的性能是否達標?」 等等。css
針對各類疑問,咱們從性能與開發體驗的角度切入,把京東小程序原生開發與 Taro 開發進行了一番對比。html
針對性能的問題,咱們分別測試了 Taro 空項目的包大小和 Taro 在長列表中的表現。由於包大小會影響小程序的首次加載速度,而長列表則是經常出現性能瓶頸的場景。前端
目前各小程序都有對主包的大小進行限制,如京東小程序限制爲 5M、微信小程序限制爲 2M。這是由於初次進入的速度對於用戶的體驗很是地關鍵,而主包體積越大下載的時間就最長。所以小程序框架的大小也成爲了開發前框架選型的重要參考指標之一,假若框架體積過大,就會壓縮業務邏輯的可用空間。react
下列圖片分別是 Taro 運行時框架壓縮先後的大小,能夠看到壓縮後僅爲84k,對主包空間的影響十分小。git
壓縮前:github
壓縮後:npm
咱們參照 js-framework-benchmark 編寫了一份 benchmark,測試對比了 Taro 代碼與原生代碼在長列表場景下的渲染表現。json
初始化:從進入頁面開始到完成 40 個商品的渲染。redux
建立:頁面 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 和原生分別在 componentWillMount
和 onLoad
渲染列表,而 Taro 使用 Component 構造頁面,componentWillMount
實際上是在 attached
生命週期中觸發。由於在微信小程序中 attached
比 onLoad
早觸發得多,因此會出現如此現象。
選中
由於 Taro 只是把回調函數包裝了一層,處理了事件參數和 this 等,因此和原生的速度至關。
部分更新、交換、增長
Taro 的速度會優於原生。緣由是 Taro 會先對將要 setData 的數據和當前 data 的數據作一次 diff,這可以大大減小 setData 的數據量,加快渲染速度。對比兩個折線圖能夠得知,數據量越大,diff 的優化收益也越大。
在小程序中,性能的問題主要在於單次 setData 數據量過大和頻繁調用 setData 上。Taro 利用 diff 解決了單次 setData 數據量過大的問題,而對於頻繁調用 setData 也有解決的辦法。
Taro 的 setState 遵循 React 規範,不一樣於 setData 的同步更新,它會異步地去更新視圖。所以假設開發者在單次事件循環中屢次調用 setState,最後也只會在下一個事件循環中進行一次 setData。
小程序由 A 頁面跳轉到 B 頁面的過程當中,從 A 頁面發起跳轉到 B 頁面觸發 onLoad,有着 300~400 毫秒的延時。Taro 提供了 componentWillPreload
鉤子,鉤子會在發起跳轉後當即執行。開發者能夠儘早地在鉤子裏作一些數據拉取的工做,相比在 onLoad 觸發後再去拉取數據就可以節省 300~400 毫秒的延時。
開發者的 Class Component 能夠繼承 Taro.PureComponent
,這樣組件在更新前會對新舊 props 和新舊 state 各作一次淺對比,避免沒必要要的更新。固然開發者能夠本身實現 shouldComponentUpdate
,經過手動控制新舊 props 和新舊 state 的對比,決定是否更新組件。
若是開發者書寫的是函數式組件,則能夠利用 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,咱們會第一時間回覆。
相關連接