超越react16

萬事屋大掌櫃發表於2019-03-03

Dan Abramov日前在JSConf Iceland做了相關分享闡述react未來的一些特性和發展方向,主要集中在兩方面:Time Slicing(時間切片)和Suspense(懸停)

超越react16

CPU Demo

超越react16

一個文字框用於輸入,波浪圖顯示react app的元件渲染情況,時鐘顯示幀與幀之間的效能,綠色優秀,紅色表示卡頓。

超越react16

從這張圖可以看到,隨著輸入的增多,時鐘出現紅色,效能也越來越差。主要的問題是輸入與react元件的更新是同步的,輸入文字之後立即更新,效能非常差。

解決的思路就是輸入和更新分開,即圖中的debounced。這樣的效能稍微好一點,但是任然帶來兩個問題:1. 如果元件的巢狀層次非常深,效能仍然非常差,因為react的更新是同步的。2. 使用者體驗不太好,因為這是要等所有的輸入結束後,才會更新元件。

所以,針對上面的這些情況,Dan帶來了非同步渲染的機制,react 未來的版本支援非同步渲染。

超越react16

上圖表示,即使cpu慢4倍的情況下,非同步更新的效能仍是非常理想。

CPU Demo表示,react 會根據優先順序來判斷是否渲染。如果有些高優先順序的任務如使用者輸入,渲染會暫停,把控制權還給瀏覽器,等瀏覽器完成輸入完成後,再繼續後面的工作,這個功能就叫做Time Slicing(時間切片)。

作用如下:

1. React 渲染時不阻塞執行緒。

2. 如果裝置效能良好,感覺如同步更新。

3. 如果裝置效能較差,更新也是響應式的。(會讓位優先順序高的內容,空閒時更新)

4. 只有渲染好後的最終狀態會展示

5. 同樣採用宣告式元件方式


IO DEMO

超越react16

超越react16

IO demo演示了一個電影列表和詳情頁的功能。詳情頁包括了圖片,詳情和評論。

超越react16

上圖注意movieDetailsFetcher.read這個函式,是未來react提供的獲取資料的方式,提供了一個簡單的快取,作用原理如下:

1. 在渲染方法裡,從cache取值

2. 如果快取存在,繼續渲染

3. 如果快取不存在,cache扔出一個promise物件

4. 當promise的狀態為resolve,react繼續渲染。

5. 快取會被new context API用到整個react 元件樹渲染,也就是全域性的資料。

這個非同步獲取資料的可以用在render()裡面,配合deferState方法,目前render只支援同步資料。如果在render時,發現非同步請求,走上面的流程,等待資料返回,才會繼續渲染。

因此,配合placeholder,我們可以採用如下的方式增強使用者體驗

1. 等詳情資料回來再展示

超越react16

2. 先展示部分內容,剩下的慢慢展示

超越react16

在此過程中由於是非同步的,因為可以隨時點選返回按鈕返回列表。

如果圖片過大發生抖動,可以等圖片返回後,繼續promise resolve操作,展示詳情。

程式碼分割

超越react16

此外,為了提高效能,可以在fetcher裡面import 對應模組,做到動態載入JS。

suspence相關總結

1. 在資料準備好前可以暫停任何狀態更新,直到資料返回。

2. 對任何元件可以新增非同步資料,不會引起堵塞。

3. 網路快,整個元件樹ready之後更新。

4. 網路慢,精確控制更新狀態(通過placeholder和loading來控制整體或者部分)

5.對不同的層級提供對應的low-level api和high-level api。


看了分享之後,感覺react未來發展方向朝著更好的使用者體驗方向發展,相關的特性總結如下

1 React會根據使用者的裝置和網路狀態採取不同的機制

2. 如果裝置好,網路快,就能享受絲滑般的感覺。

3.如果裝置差,網路慢,使用者也能得到響應式的反饋


ps: 網易重點部門誠徵前端,如果對相關職位感興趣,請投簡歷xff1874@gmail.com






相關文章