原文連接-https://github.com/AlloyTeam/omi/tree/master/tutorialhtml
Omi框架在架構設計的時候就決定把update的控制權交給了開發者,視靈活性比生命還重要。否則的話,若是遇到React Fiber要解決的這類問題的話,就須要推翻原有架構從新搞了。node
先引用下咱們團隊小鮮肉Stark偉-復旦大四 / 騰訊@AlloyTeam在知乎上的回答react
React 的核心思想是每次對於界面 state 的改動,都會從新渲染整個 virtual dom,而後新老的兩個 virtual dom 樹進行 diff,對比出變化的地方,而後經過 renderer 渲染到實際的UI界面(這裏多是瀏覽器的DOM,也多是native組件)。這樣實質上就是把界面變成一個純粹的狀態機,React 的做用就是把這個狀態機之間的狀態轉換高效率地運行出來。可是存在如下問題:git
或者看顏什麼都不記得適的回答:程序員
狀態轉移時,是在一次 tick 中遞歸遍歷組件樹,找出須要更新的節點 rerender。可是這樣形成了一些問題:github
Omi有上面的問題嗎? 沒有。web
Omi的賣點之一即是:更自由的更新,每一個組件都有update方法,自由選擇你認爲最佳的時機進行更新。這樣設計的一大好處是更加靈活,若是想要自動更新集成個mobx或者obajs即可,進可功退可守護。
數據和視圖雖然是關係密切,可是解耦的設計仍是很是必要,這樣能夠應付更多的場景。好處:瀏覽器
component update說完了嗎?沒有... Omi不只僅有component update!還有更增強大的 updateSelf。架構
先說下二者的區別:框架
以下圖所示:
標紅的表明會進行更新的節點。
class TestComponent extends Omi.Component { render () { return `<div> <h3>{{title}}</h3> <List name="list" data="listData" /> </div>`; } }
組件結構上面代碼所示:
好比咱們僅僅修改了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的實現細節。主要包含兩點:
進行updateSelf的時候,就算子組件的data發生了變化,也不去改變子組件。由於updateSelf就意思就是更新自身。
因此子組件的HTML不須要使用模板和data生成,只須要component.node.outerHTML就能夠了。outerHTML在古老的firefox是不支持的,能夠經過建立節點插入而後讀innerHTML進行polyfill。
組件自己的HTML是須要使用模板和data生成,子組件就使用剛剛的outerHTML替換即可。可是問題來了,子組件的DOM diff實際上是沒有必要的,雖然morphdom的DOM diff已經足夠輕量快速。可是子組件他們原本就是如出一轍,沒有必要的開銷。因此須要關閉DOM diff~~。而後morphdom沒有ignore相關的配置....
API:
morphdom(node, newNodeHTML, { ignoreAttr: ['attr1','attr2'] } )
好比上面表明只要標記了attr1或者attr2的就是忽略,固然爲了規避錯誤,這裏須要嚴格的匹配纔會ignore DOM diff。怎麼算嚴格的匹配?就是:
Omi Store體系之前經過addView進行視圖收集,store進行update的時候會調用組件的update。
與此同時,Omi Store體系也新增了addSelfView的API。
固然,store內部會對視圖進行合併,好比addView裏面加進去的全部視圖有父子關係的,會把子組件去掉。爺孫關係的會把孫組件去掉。addSelfView收集的組件在addView裏已經收集的也去進行合併去重,等等一系列合併優化。