【CSDN 編者按】爲了實現更清晰、更易維護的源代碼架構,Vue.js 作者尤雨溪於 2018 年年底透露 Vue 下一版本 Vue 3.0 將從頭開始寫

如今一年多時間已過,在上個月,我們終於見證了 Vue 3.0 beta 的發佈:https://github.com/vuejs/vue-next#status-beta,不過對於該測試版,尤雨溪表示,“暫時還不建議升級生產環境應用,升級指南和配套工具都還沒完善,但是可以在新/小項目裏試用。”

針對重寫最新版本的 Vue, 尤雨溪於日前發表了長文 對其過程中獲得的經驗教訓,作了詳細闡述,對此,CSDN 進行了全文翻譯,望共勉。

作者 | 尤雨溪

譯者 | 蘇本如 ,責編 | 屠敏

圖 | CSDN 下載自東方 IC

出品 | CSDN(ID:CSDNnews)

以下爲譯文:

在過去的一年裏,Vue團隊一直在開發Vue.js的下一個主要版本Vue 3,我們希望能在2020年上半年將其發佈(在撰寫本文時,這項開發工作正在進行中)。重寫Vue新的主要版本的構想是在2018年底形成的,當時Vue 2的代碼庫大約已有兩年半的運行歷史。這看起來不像是通用軟件生命週期中的一段很長的時間,但在這段時間裏,前端環境發生了巨大的變化。

兩個關鍵的因素導致了我們考慮重寫Vue新的主要版本:

第一,主流瀏覽器對新的JavaScript語言特性的普遍支持。

第二,當前Vue代碼庫隨着時間的推移而暴露出來的設計和體系架構問題。

爲什麼要重寫?

▐   使用新的語言特性

隨着ES2015標準的發佈,Javascript(正式稱爲ECMAScript,簡稱ES)得到了重大改進,主流瀏覽器終於開始爲這些新添加的特性提供適當的支持。其中一些特性特別地爲我們提供了極大提升Vue能力的機會。

其中一個最值得注意的特性是Proxy,它允許框架攔截針對對象(屬性)的操作。Vue的一個核心特性是能夠監聽對用戶定義的狀態所做的更改,並對DOM進行響應式地更新。Vue 2通過使用getter和setter來替換有狀態對象的屬性,來實現這種響應式的更新。切換到Proxy方式將允許我們消除Vue現有的限制(例如無法檢測新的屬性添加),並提供更好的性能。

然而,Proxy是一個原生語言特性,在傳統瀏覽器中這個特性無法用polyfill來兼容。因此,爲了利用這個特性,我們必須調整Vue框架的瀏覽器支持範圍,這是一個重大的突破性的改變,只能在新的主要版本中發佈。

▐   解決體系架構存在的問題

在維護Vue 2的過程中,我們積累了一些由於現有體系架構的限制而難以解決的問題。例如,模板編譯器的編寫方式使得正確的源映射(source-map)支持非常具有挑戰性。另外,雖然Vue 2在技術上支持構建針對非DOM平臺的更高級別的渲染器,但爲了實現這一點,我們必須分叉代碼庫並複製大量代碼。在當前的代碼庫中修復這些體系架構問題將需要風險巨大的重構工作,而這些重構幾乎等同於重寫。

同時,我們還積累了技術債務,表現爲各種模塊的內部和似乎不屬於任何地方的浮動代碼之間的隱式耦合。這使得孤立地理解代碼庫的一部分變得更加困難,我們注意到貢獻者中很少有人有信心做出大範圍的更改。重寫將使我們有機會帶着這些問題和想法來重新考慮整個代碼庫結構。

初始原型的構建階段

我們在2018年底開始Vue 3的原型開發,初步目標是驗證這些問題的解決方案。在這一階段,我們主要致力於爲進一步開發打下堅實的基礎。

▐   切換到TypeScript

Vue 2最初是用純ES(Javascript)寫成的。在原型設計階段之後不久,我們意識到一個類型系統(Type system)對於這樣一個規模的項目非常有用。類型檢查(Type check)大大減少了在重構過程中引入意外錯誤的機會,並幫助貢獻者更有信心進行大範圍的更改。我們採用了Facebook的Flow type checker,因爲它可以逐漸添加到現有的純ES項目中。Flow type checker在一定程度上起到了幫助作用,但我們並沒有從中得到我們所希望的那麼多好處。特別是,持續的重大改變使得升級成爲一種痛苦。相比較TypeScript與Visual Studio Code集成開發工具的深度集成,Flow type checker對集成開發環境的支持也不理想。

我們還注意到,用戶越來越多地同時使用Vue和TypeScript。爲了支持它們的用例,我們必須獨立於使用不同類型系統的源代碼來編寫和維護TypeScript聲明。切換到TypeScript將允許我們自動生成聲明文件,從而減輕維護負擔。

▐   解耦內部包

我們還採用了monorepo設置,其中框架由內部包組成,每個包都有各自的API、類型定義和測試程序。我們希望能夠使這些模塊之間的依賴關係更加明確,以便開發人員能夠更容易地閱讀、理解和更改所有模塊。這是我們努力降低項目貢獻障礙和提高其長期可維護性的關鍵。

▐   設置RFC(徵求修正意見)流程

到2018年底,我們已經成功構建了一個可工作的原型,它帶有新的響應式系統和虛擬DOM渲染器。我們已經驗證了我們想要進行的內部架構改進,但是面向公衆的API的更改還停留在草稿階段。是時候把它們變成具體的設計了。

我們知道我們必須儘早並且小心地處理這件事。Vue的廣泛採用意味着任何重大改變都可能導致用戶的巨大遷移成本和潛在的生態系統碎片化。爲了確保用戶能夠提供關於這些重大改變的反饋,我們在2019年初採用了RFC(徵求修正意見)流程。每個RFC都使用一個模板,重點關注動機、設計細節、權衡和採用策略。由於該過程是在GitHub repo中進行的,我們將我們建議的更改作爲pull請求提交,因此討論以評論的形式有效地展開了。

事實證明,RFC流程非常有效,它作爲一個思想框架,迫使我們充分考慮潛在變化的方方面面,並允許我們的社區參與設計過程,提交深思熟慮的功能請求。

更快更小

性能對前端框架至關重要。儘管Vue 2號稱具有良好的性能,但重寫提供了一個機會,可以通過試驗新的渲染策略來更提供更好的性能。

▐   克服虛擬DOM的瓶頸

Vue有一個相當獨特的渲染策略:它提供類似於HTML的模板語法,但是,它是將模板編譯成渲染函數來返回虛擬DOM樹。Vue框架通過遞歸遍歷兩個虛擬DOM樹,並比較每個節點上的每個屬性,來確定實際DOM的哪些部分需要更新。由於現代JavaScript引擎執行的高級優化,這種有點暴力的算法通常非常快速,但是DOM的更新仍然涉及許多不必要的CPU工作。當你看到一個基本上是靜態內容、只有少量動態綁定的模板時,效率低下的情況尤其明顯,因爲這時候仍然需要遞歸地遍歷整個虛擬DOM樹,以找出需要更改的內容。

幸運的是,模板編譯步驟使我們有機會對模板執行靜態分析並提取有關動態部分的信息。Vue 2在某種程度上是通過跳過靜態子樹來實現的,但是過於簡單的編譯器體系架構使得更高級的優化很難實現。在Vue 3中,我們使用適當的AST轉換管道重寫編譯器,這允許我們以轉換插件的形式將編譯時(compile-time)優化組合進來。

隨着新的體系架構的出現,我們希望找到一種能夠儘可能減少開銷的渲染策略。一種選擇是拋棄虛擬DOM並直接生成命令式DOM操作,但這樣做會消除直接編寫虛擬DOM渲染函數的能力,而我們發現這種能力對於高級用戶和庫的編寫者非常有價值。另外,這將是一個巨大的突破性改變。

另一個更好的辦法是去掉不必要的虛擬DOM樹遍歷和屬性比較,這在更新期間往往會產生最大的性能開銷。爲了實現這一點,編譯器和運行時需要協同工作:編譯器分析模板並生成帶有優化提示的代碼,而運行時儘可能獲取提示並採用快速路徑。這裏有三個主要的優化:

首先,在DOM樹級別。我們注意到,在沒有動態改變節點結構的模板指令(例如v-if和v-for)的情況下,節點結構保持完全靜態。如果我們將一個模板分成由這些結構指令分隔的嵌套“塊”,則每個塊中的節點結構將再次完全靜態。當我們更新塊中的節點時,我們不再需要遞歸遍歷DOM樹 - 該塊內的動態綁定可以在一個平面數組中跟蹤。這種優化通過將需要執行的樹遍歷量減少一個數量級來規避虛擬DOM的大部分開銷。

其次,編譯器積極地檢測模板中的靜態節點、子樹甚至數據對象,並在生成的代碼中將它們提升到渲染函數之外。這樣可以避免在每次渲染時重新創建這些對象,從而大大提高內存使用率並減少垃圾回收的頻率。

第三,在元素級別。編譯器還根據需要執行的更新類型,爲每個具有動態綁定的元素生成一個優化標誌。例如,具有動態類綁定和許多靜態屬性的元素將收到一個標誌,提示只需要進行類檢查。運行時將獲取這些提示並採用專用的快速路徑。

綜合起來,這些技術大大改進了我們的渲染更新基準,Vue 3有時佔用的CPU時間不到Vue 2的十分之一。

注:CPU時間指的是執行JavaScript計算所花費的時間,不包括瀏覽器DOM操作。

▐   最小化bundle的大小

框架的大小也會影響其性能。這是Web應用程序的一個獨特關注點,因爲所有相關的代碼需要動態下載,並且在瀏覽器解析出必要的JavaScript之前,應用程序不會進行交互。對於單頁應用程序尤爲如此。雖然Vue一直都比較輕量級,但Vue 2的運行時壓縮後的大小也約有23 KB,我們注意到兩個問題:

首先,並不是每個人都使用框架的所有特性。例如,一個從不使用transition特性的應用程序仍然需要付出與使用transition特性相關的代碼的下載和解析成本。

第二,隨着我們添加新特性,框架會無限制地增長。當我們權衡一個新特性添加的利弊時,我們就給了與bundle大小不成比例的權重。因此,我們傾向於只包含大多數用戶使用的特性。

理想情況下,用戶應該能夠在構建時刪除未使用的框架特性(也稱爲“樹抖動-tree shaking”)的代碼,並且只爲他們使用的代碼付出成本。這也將使我們能夠在不增加其他用戶的有效負荷成本的情況下,發佈一些用戶認爲有用的特性。

在Vue 3中,我們通過將大多數全局API和內部幫助程序移動到Javascript的module.exports屬性上實現這一點。這允許現代模式下的module bundler能夠靜態地分析模塊依賴關係,並刪除與未使用的module.exports屬性相關的代碼。模板編譯器還生成了對樹抖動友好的代碼,只有在模板中實際使用某個特性時,該代碼才導入該特性的幫助程序。

框架中有些部分永遠不會被“樹抖動”(這部分的代碼永遠不會從框架中刪除),因爲它們對任何類型的應用程序都是必不可少的。我們稱這些不可缺少的部分爲基線大小。儘管增加了許多新特性,但Vue 3被壓縮後的基線大小約爲10 KB,不到Vue 2的一半。

解決規模性的需求

我們還希望提高Vue處理大規模應用程序的能力。我們最初的Vue設計專注於低門檻和溫和的學習曲線。但是隨着Vue被越來越廣泛地採用,我們對包含數百個模塊並由數十名開發人員長期維護的項目的需求瞭解得更多。對於這種類型的項目,TypeScript之類的類型系統和乾淨地組織可重用代碼的能力是至關重要的,而Vue 2在這些領域的支持並不理想。

在設計Vue 3的早期階段,我們試圖通過提供對使用類編寫組件的內置支持來改進TypeScript集成。然而挑戰在於,在正式成爲JavaScript的一部分之前,我們需要使類可用的許多語言特性(如類字段和裝飾器)仍然是建議的,並且可能會發生更改。所以,這種方法所涉及的複雜性和不確定性使我們懷疑添加類API是否真的是合理的,因爲除了提供稍好一點的TypeScript集成之外,它沒有提供任何其他特性。

我們決定研究其他方法來解決規模性難題。受React鉤子的啓發,我們考慮公開較低級別的響應性和組件生命週期API,以實現一種更自由形式的編寫組件邏輯的方法,我們稱之爲Composition API。Composition API不需要通過指定一長串選項來定義組件,而是允許用戶像編寫函數一樣自由地表達、組合和重用有狀態的組件邏輯,同時提供出色的TypeScript支持。

我們對這個主意很興奮。儘管Composition API是爲解決一類特定的問題而設計的,但在技術上只有在編寫組件時纔有可能使用它。在提案的初稿中,我們有點超前,並暗示在將來的版本中,我們可能會用Composition API替換現有的Options API,這導致了社區成員的強烈抵制。這件事給了我們一個寶貴的教訓,讓我們學會清楚地傳達長期計劃和意圖,以及理解用戶的需求。在聽取了我們社區的反饋後,我們徹底修改這個提議,明確表示Composition API將是Options API的附加和補充。對於這一訂正提案的反饋要積極得多,並收到了許多建設性的建議。

尋求平衡

在Vue超過100萬開發人員的用戶羣中,有隻掌握HTML/CSS基礎知識的初學者,有從jQuery轉移來的專業人員,有從另一個框架遷移過來的老手,有尋找前端解決方案的後端工程師,以及處理大規模軟件的軟件架構師們。開發人員知識背景的多樣性導致了用例的多樣性:一些開發人員可能希望在老舊的應用程序上添加交互性,另一些開發人員可能正在處理一次性的項目,這些項目的週轉速度很快,但維護問題有限;而架構師們可能不得不在項目的生命週期中處理大型的、多年的項目和麪對不斷變化的開發團隊。

Vue的設計不斷地受到這些需求的影響,我們試圖在各種需求之間取得平衡。Vue的口號“漸進式框架”就是對通過這種過程產生的分層API設計的一種概括。初學者們可以通過使用CDN腳本、基於HTML的模板和直觀的Options API,享受平滑的學習曲線,而專家們則可以使用功能齊全的CLI、渲染函數和Composition API來處理複雜的用例。

爲了實現我們的願景,還有很多工作要做。最重要的工作是更新支持庫、提供文檔和工具,以確保遷移的順利進行。我們將在接下來的幾個月裏努力工作,我們迫不及待地想看看Vue社區會使用Vue 3構建出什麼。

原文: https://increment.com/frontend/making-Vue-3/

今晚20:00 ,CSDN 創始人&董事長、極客幫創投創始合夥人蔣濤攜手全球頂級開源基金會主席、董事,聚焦中國開源現狀,直面開發者在開源技術、商業上的難題,你絕不可錯過的開源巔峯對談!立即 免費圍觀

更多精彩推薦
☞可怕!CPU 竟成了黑客的幫兇!
☞7 輪 Google 面試!內幕大公開 | 原力計劃
☞微信被指監聽用戶,騰訊回應;谷歌意外推送 Android 11 Beta 更新;Linux 5.7 發佈 | 極客頭條
☞追憶童年,教你用Python畫出兒時卡通人物
☞藉助大數據進行社交媒體營銷,企業們得這麼玩!
☞好撲科技結合區塊鏈行業發展趨勢,重磅推出“好撲區塊鏈合夥人”計劃
點擊閱讀原文,精彩繼續。
你點的每個“在看”,我都認真當成了喜歡
相關文章