<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      Omi架構與React Fiber

      2017-03-29 11:28  【當耐特】  閱讀(2468)  評論(4)    收藏  舉報

      原文鏈接-https://github.com/AlloyTeam/omi/tree/master/tutorial

      寫在前面

      Omi框架在架構設計的時候就決定把update的控制權交給了開發者,視靈活性比生命還重要。不然的話,如果遇到React Fiber要解決的這類問題的話,就需要推翻原有架構重新搞了。

      React Fiber

      先引用下我們團隊小鮮肉Stark偉-復旦大四 / 騰訊@AlloyTeam知乎上的回答

      React 的核心思想是每次對于界面 state 的改動,都會重新渲染整個 virtual dom,然后新老的兩個 virtual dom 樹進行 diff,對比出變化的地方,然后通過 renderer 渲染到實際的UI界面(這里可能是瀏覽器的DOM,也可能是native組件)。這樣實質上就是把界面變成一個純粹的狀態機,React 的作用就是把這個狀態機之間的狀態轉換高效率地運行出來。但是存在以下問題:

      • 1、不是每一次狀態的變化都要立刻執行。
      • 2、不同的狀態變化之間是有輕重緩急之分的,比如『動畫』這種狀態變化的優先級,出于對用戶體驗的考量,為了避免動畫卡頓或者掉幀,一般比『改變頁面數據』的優先級更高。
      • 3、我們現在的做法只是調用 setState 觸發重新渲染,然后 React 會收集一個 tick 內的 state 變化,然后執行,所以有可能大量的計算會在同一時刻阻塞進程。但我們沒法控制 React 運算的時序問題,也不太可能通過手工聲明讓動畫的優先級比數據變更更高。而 React 作為一個用戶交互的框架,它本應該能讓程序員能控制這些東西。所以這個破事要怎么解決咧?( ⊙ o ⊙ )我們知道,任何的函數調用都會有自己的調用棧,比如對于 v = f(d) 這個函數來說,函數 f 可能又調用了一系列其它的函數,這些函數就包括在 f 的調用棧中。關鍵的問題在于,這種原生的調用棧是基本不可延遲的,它會立即執行,如果計算量很大的話就會阻塞住進程,讓界面失去響應,這種事情經常發生在 React 的渲染過程中。

      或者看顏什么都不記得適的回答

      狀態轉移時,是在一次 tick 中遞歸遍歷組件樹,找出需要更新的節點 rerender。但是這樣造成了一些問題:

      • 在 UI 中,不是所有的狀態轉移都需要立即執行。大量的同時計算可能會導致資源的浪費,以致出現掉幀的狀況,降低用戶體驗。
      • 不同類型的狀態轉移應有不同的優先級,比如點擊按鈕出現動畫的優先級應該比 Fetch API 要高。
      • React 是 pull-based 實現的,事務的時序全部由 React 決定。我們沒辦法操控執行事務的時序。

      Omi component update

      Omi有上面的問題嗎? 沒有。

      Omi的賣點之一便是:更自由的更新,每個組件都有update方法,自由選擇你認為最佳的時機進行更新。這樣設計的一大好處是更加靈活,如果想要自動更新集成個mobx或者obajs便可,進可功退可守護。
      數據和視圖雖然是關系密切,但是解耦的設計還是非常必要,這樣可以應付更多的場景。好處:

      • 你可以等某個動畫播放完成再進行update
      • 你可以控制update順序
      • 你可以update前后干一些事情而不需要利用生命周期的鉤子函數(有的時候鉤子函數讓連續的邏輯打得粉碎...)

      component update說完了嗎?沒有... Omi不僅僅有component update!還有更加強大的 updateSelf。

      Omi component updateSelf

      先說下兩者的區別:

      • update: 更新組件樹
      • updateSelf: 更新組件(不包含任何子節點)

      如下圖所示:

      標紅的代表會進行更新的節點。

      場景模擬

      class TestComponent extends Omi.Component {
          render () {
              return `<div>
                          <h3>{{title}}</h3>
                          <List  name="list" data="listData" />
                      </div>`;
          }
      }
      

      組件結構上面代碼所示:

      • 如果調用組件實例的update的話,會更新組件本身以及 List組件
      • 如果調用組件實例的updateSelft的話,會更新組件本身,不會更新List組件

      比如我們僅僅修改了this.data.title,就可以調用this.updateSelf方法,雖然一般情況下無腦update也能達到同樣的結果,雖然morphdom的DOM diff已經足夠輕量快速,但是一定沒有updateSelf方法快速。上面的例子updateSelf優勢可能不明顯,如果這樣呢:

      class TestComponent extends Omi.Component {
          render () {
              return `<div>
                          <h3>{{title}}</h3>
                          <List  name="list" data="listData" />
                          <List  name="list" data="listData" />
                          <Content  name="list" data="listData" />
                          <Slider  name="list" data="listData" />
                      </div>`;
          }
      }
      

      再或者Content、Slider里面再嵌套了子組件,子組件又嵌套了子組件,如果僅僅只是需要修改title的話,updateSelf優勢就盡顯無疑。

      實現細節

      這里主要說一說updateSelf的實現細節。主要包含兩點:

      • 不重新render的情況下拿到子組件的完整的HTML
      • 關閉子組件的DOM diff

      進行updateSelf的時候,就算子組件的data發生了變化,也不去改變子組件。因為updateSelf就意思就是更新自身。
      所以子組件的HTML不需要使用模板和data生成,只需要component.node.outerHTML就可以了。outerHTML在古老的firefox是不支持的,可以通過創建節點插入然后讀innerHTML進行polyfill。

      組件本身的HTML是需要使用模板和data生成,子組件就使用剛剛的outerHTML替換便可。但是問題來了,子組件的DOM diff其實是沒有必要的,雖然morphdom的DOM diff已經足夠輕量快速。但是子組件他們本來就是一模一樣,沒有必要的開銷。所以需要關閉DOM diff~~。然后morphdom沒有ignore相關的配置....

      擴展 morphdom

      API:

       morphdom(node, newNodeHTML, {
                              ignoreAttr: ['attr1','attr2']
                          } )
      

      比如上面代表只要標記了attr1或者attr2的就是忽略,當然為了規避錯誤,這里需要嚴格的匹配才會ignore DOM diff。怎么算嚴格的匹配?就是:

      • 當同樣的attr的DOM,并且該attr在ignoreAttr里才會ignore DOM diff

      Omi Store體系addSelfView

      Omi Store體系以前通過addView進行視圖收集,store進行update的時候會調用組件的update。

      與此同時,Omi Store體系也新增了addSelfView的API。

      • addView 收集該組件視圖,store進行update的時候會調用組件的update
      • addSelfView 收集該組件本身的視圖,store進行update的時候會調用組件的updateSelf

      當然,store內部會對視圖進行合并,比如addView里面加進去的所有視圖有父子關系的,會把子組件去掉。爺孫關系的會把孫組件去掉。addSelfView收集的組件在addView里已經收集的也去進行合并去重,等等一系列合并優化。

      Omi相關

      主站蜘蛛池模板: 一 级做人爱全视频在线看| 亚洲嫩模喷白浆在线观看| 亚洲三级香港三级久久| 亚洲AVAV天堂AV在线网阿V| 亚洲精品无amm毛片| 欧美亚洲色综久久精品国产| 激情久久av一区二区三区| 国产不卡精品视频男人的天堂| 遂昌县| 免费观看激色视频网站| 亚洲av永久无码精品水牛影视| 艳妇臀荡乳欲伦69调教视频| 国产亚洲一区二区三区成人| 四虎永久免费精品视频| 欧美人禽杂交狂配| 亚洲性日韩精品一区二区| 美女黄18以下禁止观看| 欧美18videosex性欧美黑吊| 麻豆精品一区二区视频在线| 亚洲第一极品精品无码久久| 欧洲熟妇色xxxx欧美老妇多毛网站| 蜜桃久久精品成人无码av | 久久精品无码免费不卡| 成熟了的熟妇毛茸茸| 精品久久丝袜熟女一二三| 亚洲男人AV天堂午夜在| 西西人体44www大胆无码| 精品一区二区三区女性色| 丰满爆乳一区二区三区| 沅陵县| 午夜免费视频国产在线| 亚洲色欲或者高潮影院| 日韩人妻精品中文字幕| 综合区一区二区三区狠狠| 人妻聚色窝窝人体WWW一区| 亚洲女同精品久久女同| 熟妇人妻久久精品一区二区 | 国产精品成人av电影不卡| 色综合久久综合久鬼色88| 國產尤物AV尤物在線觀看| 人人澡超碰碰97碰碰碰|