尤雨溪 在 2019 JSConf 的分享 Seeking the Balance in Framework Design 十分精彩,道出瞭如何進行合理的前端框架設計與框架選型。前端
正如所說,框架對比不能只停留在 Star 數量、Npm 下載量、Stackoverflow 問題量這些簡單的數據對比,而要深刻到技術細節進行比較。比較框架有多種不一樣維度,此次分享就從服務範圍、渲染機制、狀態機制這三個維度進行對比。git
此次分享的精彩之處在於不偏不倚的站在客觀立場分析了框架各維度好的一面與壞的一面,從中咱們不只能學習到一些框架知識,還能培養思辨能力。github
服務範圍是個比較難翻譯的單詞,在原 PPT 中用了 「Scope」 這個單詞表示,能夠理解爲 「做用域、框架的承諾功能範圍、服務配套齊全程度」。好比提供的是一個工具庫仍是總體框架,插件管理是集中式仍是依賴生態。設計模式
React 是典型的小服務範圍框架,核心包只實現了基本功能,而其餘生態基本靠社區拓展;Angular 是典型大服務範圍框架,官方對全部業務場景都作了最佳實踐能力覆蓋;Vue 處在中間區域,經過功能分層,既擁有小服務範圍的能力,又能夠搭配官方插件實現更多場景化能力。安全
概念少,易上手性能優化
小的服務範圍表明了小的學習成本,由於暴露的基本能力較少,概念也會比較少,對新人上手比較友好。前端框架
生態繁榮,百花齊放微信
因爲不少功能沒有被官方實現,社區就有機會填補這些空白,所以會冒出許多第三方庫,並且一旦作得好,就有機會成爲 「事實標準」,所以開發者會更加積極參與到社區開發,本身作的框架 「上升空間」 也很是大。架構
同時,社區的力量會致使多元化,所以總體生態完整度與創新性都會很是亮眼,並且具備持續迭代的能力。框架
核心維護成本低
官方維護的核心代碼較少,所以維護成本大大下降,並且官方能夠將精力放在更多核心能力加強上,好比 Suspense 等,而不是將精力消耗在生態插件上。
複雜場景要引入新概念
複雜場景沒法支持時,就要引入新的概念解決,這致使後續技術選型可能產生分歧,並帶來持續的新概念理解成本。
非官方的開發模式逐漸產生
隨着時間的流逝,會逐漸涌出一些新的設計模式,成爲當下幾乎是必不可少的方案,但卻不會出如今官方文檔中,形成選型時的疑惑。Redux 就是一個例子。
生態變化快,碎片化且持續流失
非官方的生態也意味着不穩定,並且缺少統一的管理,碎片化的模塊之間可能常常出現不兼容的問題。
並且任何模塊均可能被時代無情的淘汰,就像 Flux 到 Redux 再到 Hooks,帶來額外的遷移成本和認知成本。誰也不但願本身的項目架構 「變得過期」,或者隨時面臨被新架構取代的風險,但第三方社區幾乎必定表明將來會出現一種模式取代現有模式,只是時間遲早而已。
大部分業務場景都被內置解決
減小沒必要要的技術方案調研與紛爭,大服務範圍的框架內置的方案就能解決幾乎 100% 業務問題,團隊不再會爲通用架構問題煩惱了。
生態穩定、連貫
穩定是指,官方維護做爲背書,幾乎不會存在一些生態包忽然不維護、與已有版本不兼容、被植入惡意程序等等意外狀況。
連貫是指,官方會統一考慮一個改動在全部生態插件形成的影響,並以一個最合理的思路作總體改造,生態包不管是接口仍是兼容性都不須要擔憂,設計思路也會一脈相承。
前期上手成本高
全家桶的概念致使上手難度偏高,由於必須理解全部內置概念後才能開始項目。
若是內置模塊沒法知足業務,會以爲有些死板
一旦發生內置功能沒法知足業務的場景,就很難拓展了,由於 all in one 的思路本質上就是排斥自定義拓展的,這點從 angular-cli 就能看出來。
之因此以爲死板,是由於這種狀況沒辦法用優雅的方式解決,只能在現有約束的框架內經過某些 「Hack」 方式解決,天然會有種死板的感受。
分層設計,容許新特性漸進加入
Vue 經過分層設計作到了折中,即官方仍是會維護生態,只不過生態不是必須的,能夠按需使用。這樣作的好處是兼顧了一些優點。
低學習門檻
與小服務範圍框架同樣,對於核心包來講學習成本都比較低。
依然有最佳實踐解決全部業務問題
和大服務範圍框架同樣,擁有全套官方最佳實踐,但不內置,不強求必定要使用,所以你能夠按需使用。
維護成本高
和大服務範圍框架同樣,雖然生態不強求,但畢竟官方仍是要持續維護的,所以維護成本高的問題依然存在。
生態多樣性不高
雖然生態是按需的,但畢竟中等服務範圍的框架官方會實現一套標準生態插件,這會極大影響社區生態的發展空間,致使 「非官方插件沒人願意作」,所以生態多樣性會差一些。
渲染機制區別主要在 JSX vs Template 之間,不一樣的表達方式之間仍是存在一些很本質的區別,然而正如一開始所說,沒法一言蔽之,必須從多個角度拆解的看。
純 JS 表達 UI
單這一點就很是重要了,知足了 All In Js 的幻想。畢竟 Html、Css 相比 Js 來講,模塊化能力和靈活性都很弱,將其都收斂到 Js 不只表達方式更統一,更重要的是都得到了與 Js 同樣的模塊化、靈活性、Typescript 支持等能力。
視圖即數據
將視圖看做一種數據,讓針對視圖的邏輯測試成爲可能。
同時也將視圖概念泛化了,由於數據是平臺無關的,一份描述視圖的 DSL 能夠運行在任何平臺。
開銷大
頁面節點越多,Diff 開銷就越大。
動態渲染很難性能優化
因爲全部 DOM 節點都是動態生成,所以沒法根據初始狀態結構進行安全的優化。相比之下,Template 模式能夠肯定哪部分屬於變量,哪部分是固定的,對固定部分的 Diff 檢測均可以跳過。
動態調度雖然改善了性能,但依賴更重的運行時
React ConcurrentMode 是一個調度優化器,但實現的邏輯也比較複雜,加劇了運行時負擔。
原生性能
因爲 Template 對節點進行直接渲染,所以與原生性能一致。
Runtime 更小
因爲不須要額外優化,運行時代碼會小不少。
被 Template 語法約束,且沒法拓展
對於 Template 不支持的,只能選擇接受,由於除了框架本身,沒有人能拓展 Template 的特性。當遇到一些很是動態場景,但 Template 不支持的狀況,只能選擇接受,並用比較 Hack 的方式繞過解決,除此以外別無他法。
模版冗長
JSX 能夠利用循環語句或者變量賦值進行模版區塊的複用,但 Template 模式每次新模版都要一行一行的打出來,這種冗長的開發體驗不太友好。
運行時解析開銷或者依賴編譯期邏輯
要麼經過編譯器預先生成 AST,要麼運行時動態將 Template 解析成 AST,不管哪一種方案都有額外的開銷,一種是工程依賴的開銷,一種是運行時動態解析的性能開銷。
Vue 在 Template 基礎上支持了虛擬 DOM,所以兼具二者特點。
性能上,在編譯時就進行 AST 解析,減小了運行時解析開銷。
功能上,支持模版與 JSX 兩種語法。
狀態機制 尤雨溪 在 JSConf 提到要單獨拆出來說,由於內容較多,時間可能不夠,本次精讀也限於篇幅緣由略過:
顯然,狀態機制方案更是仁者見仁智者見智的事情,一樣得從多個維度進行獨立分析,並根據實際業務場景具體選擇。
最後,意識到沒有一個絕對均衡的框架設計方案,由於在工程領域,沒有最好只有更好。
咱們再延伸談一談爲何框架設計要尋找平衡點。
框架設計沒有銀彈
與數學公式不一樣,框架設計甚至整個工程技術設計都沒有所謂的真理,所謂條條大路通羅馬,實現同一個技術目標的衆多方案之間也許就是平行關係,能夠根據不一樣維度列出一二三的對比,但沒法得出一個總的結論,孰優孰劣。
使用場景不一樣
不一樣使用場景決定了對框架訴求的不一樣。
好比開發很是定製、炫酷的可視化大屏,那麼前端開發框架基本也用不上,由於關注點不會聚焦在項目路由、UI 描述、甚至是數據流,而是聚焦在性能、圖形渲染等問題。解決這些領域的框架多是 虛幻 四、Unity 等遊戲引擎,但普通的前端開發框架毫不會涉足這種領域,框架必定要肯定本身功能範圍。
即使僅侷限在 Web 領域,也須要考慮是否要支持非 Web 場景,那麼將 HTML 抽象成一個通用 DSL 就多是一種選擇,但非 Web 領域畢竟不是主打業務領域,在這種業務場景周邊生態維護可能就比較少,這也是須要取捨的地方。
使用的人不一樣
不一樣團隊對框架的要求也不一樣。
剛起步的小團隊可能更須要保姆式的框架,由於這樣最節省人力成本。對於規模較大的團隊,但願對框架擁有較大定製能力時,小服務範圍的框架可能更受青睞。固然框架做者能夠像 Vue 同樣作出漸進式官方能力加強方案,以此知足不一樣需求的用戶,但畢竟也不能將生態徹底交給社區,仍是要作取捨。
因此當遇到更新更酷的框架時,須要冷靜思考的不僅是這個框架帶來的收益與花費的遷移成本哪一個更高,以及團隊可否接受這套框架的開發習慣,更須要思考的是這個框架自身作了哪些權衡,若是這些權衡與 React、Vue、Angular 相似,那麼僅僅變化了語法或者語言的改動其實意義不大,此時須要慎重考慮。
此次沒有提到的狀態機制對比,你能分別列舉出優缺點嗎?歡迎留言。
若是你想參與討論,請 點擊這裏,每週都有新的主題,週末或週一發佈。前端精讀 - 幫你篩選靠譜的內容。
關注 前端精讀微信公衆號
版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享 3.0 許可證)