React的將來特性

週末參加GDG今年的活動時,聽人安利Angular2的宏偉藍圖和規劃,忽然好奇React將來規劃如何,以前還關注過react-fiber-architecture。而後在YouTube上搜索到了Andrew Clark: What's Next for React — ReactNext 2016,本文便是翻譯整理而來。
本文從屬於筆者的Web 前端入門與最佳實踐React 入門與最佳實踐 系列文章。前端

React Fiber是對於React核心算法的重寫,可能會在將來某個版本中投入使用。不過Andrew Clark一直在提醒由於該特性還處於實驗階段,所以React團隊並不能肯定什麼時候發佈乃至是否能達到預期的目標。在2014年的一篇Twitter中,就有人@React核心團隊但願引入多線程調和等特性。至此以後,React團隊成員進行了不少關於列表中列舉出的特性的實驗與研究。react

而React Fiber則是目前最新的實驗迭代得出的成果。git

Why Fiber:爲啥要花大精力複寫

Scheduling:調度

調度的概念即在不一樣的場景、不一樣的上下文中咱們須要爲不一樣的任務設置不一樣的優先級,而React自己做爲提供聲明式組件支持的框架,使開發者不用再關注於具體的狀態轉化到UI顯示的流程。React爲咱們提供了控制如何去更改UI狀態以及什麼時候更改UI狀態的接口,其遵循的是Push方式去更改頁面狀態,而React Fiber便是但願尋找更優的算法來決定調度策略。目前來講,咱們在界面的開發中每每會碰到以下幾種須要進行狀態更新的狀況:github

  • 用戶事件:Clicks,Input Change算法

  • 外部訂閱的狀態變動:Redux,MobX,Relay瀏覽器

  • Animations:Transitions,Gestures緩存

目前的React核心算法中並無對這幾種狀況進行想起的區分,而是統一對待。而從用戶體驗的角度來講,對於狀態管理中外部狀態變化引起的內部狀態變化可能對於用戶體驗影響不大, 畢竟數據加載自己就存在延遲。而對於動畫而言,一旦有所延遲則會引起掉幀,從而大大影響用戶體驗。多線程

Animations are more important than typical updates併發

ListView

上文說起,Scheduling容許咱們爲不一樣的任務定義不一樣的執行優先級。這裏以某個超長列表爲例:

完整的列表包含一千多行數據,如今咱們無論對於屏幕內仍是屏幕外的數據都會進行相同的操做,從而致使了大量的無心義的損耗。所以理想的狀況咱們是但願在用戶中止滾動以前不進行其餘額外的操做而且不對屏幕以外的列表項進行渲染。從調度的角度來講,咱們就但願對屏幕外的列表項設置較低的優先級,而對屏幕內的列表項設置較高的渲染優先級。框架

How it Works:工做原理

Concurrency

併發性是Fiber的核心精髓,首先須要明瞭的是併發與並行的區別。React的渲染一直是同步進行的,那麼假設當咱們須要去渲染某個動畫幀的時候(通常來講完整的動畫須要每秒60幀,大概16.5毫秒每幀),渲染線程忙於渲染一些低優先級的組件,譬如那一些離屏的組件時候,咱們但願的場景是渲染線程可以暫停當前的動做去渲染動畫幀,渲染完畢後繼續剛纔的工做。其流程概述以下:

  • 中斷當前低優先級的工做

  • 完成高優先級工做

  • 繼續剛纔未完成的工做

此時的一個核心問題就是如何中斷現有的渲染工做,目前React的渲染操做能夠爲抽象爲v = f(d)這樣一個函數調用,那麼問題就被轉化爲了如何去中斷該函數調用。ES6中內置有Generator對象是個不錯的考慮,如今也有不少的框架利用Generator去實現Concurrency Primitive。不過Clark在這裏介紹的是debugger;表達式,Debugger表達式可以給程序打斷點,就像這樣:

上圖描述的簡單的對每一個棧幀打斷點的過程就是如今Fiber中斷渲染過程而後恢復的機制,其流程概述爲:

  • 中斷當前渲染的調用棧

  • 將當前的調用棧暫存

  • 執行某些擁有獨立調用棧的高優先級的任務

  • 返回原始調用棧而且恢復其執行

到這裏咱們能夠將Fiber定義爲Reimplementation Of The Stack,A Fiber is a Virtual Stack Frame。

Fiber

Fiber 更多的是語言中的某個抽象,用於實現某些語言中複雜的特性。在下表中就是將Stack Frame與Fiber中的名詞進行了對比:

除了上表列舉的Fiber的基本性質,其還具有以下屬性:

  • 優先級

  • 可緩存的輸入(Props)

  • Key,用於調和時使用

基於Fiber就能夠將本來的渲染工做切分到可併發的細小單元,而後按照優先級依次執行。下一步咱們就是須要解決應該在什麼時候暫停當前工做以及什麼時候恢復原調用棧。目前瀏覽器爲咱們提供了兩個用於動畫渲染的API:

  • requestAnimationFrame(cb):按期調用動畫幀,若是你想作逐幀動畫的時候,你應該用這個方法。這就要求你的動畫函數執行會先於瀏覽器重繪動做。一般來講,被調用的頻率是每秒60次,可是通常會遵循W3C標準規定的頻率。若是是後臺標籤頁面,重繪頻率則會大大下降。

  • requestIdleCallback(cb):在瀏覽器空閒時調用回調函數。

上圖就是展現了Fiber的工做流,目前有40個單位的低優先級工做,若是用上面的連續性渲染,咱們並不能在渲染過程當中插入動畫幀。而在下面的可中斷恢復的方案中,咱們能夠將動做拆分爲四個塊,而後在塊之間插入高級別的動畫幀。

What it can do:有啥做用

  • Integrated Layout

  • 在render函數中返回多個元素

  • 更加清晰的代碼庫

相關文章
相關標籤/搜索