聊聊對現代前端架構的認知

來源:互聯網
上載者:User
本章聊聊對現代前端架構的認知,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。

那為什麼現在人們需要選擇各種架構了呢?

其實之所以現在我們需要選擇架構,本質上是因為我們面臨的需求變了。大家肯定都明白如果我們唯寫一個純展示資訊的頁面,沒有任何互動功能的頁面,其實即便是現在,我們也是不需要選擇架構的,我們只需要寫幾行CSS和HTML就可以完成任務。所以是因為我們面臨的需求變得複雜了,我們的應用經常需要在運行時做一些互動。

這裡面有三個很重要的字我標了粗體,叫做運行時(Runtime)。現代的前端開發,我們開發的應用經常需要在運行時來做一些互動,這些互動在早期只是個投影片或者Tab切換下拉式功能表等一些簡單的互動,這些互動用jQuery實現完全沒什麼問題。但現代的前端我們的目標是用Web去PK原生應用,去和Native進行PK。

那這個時候我們會發現用jQuery來開發應用,我們的代碼變得很難以維護,那為什麼使用現代架構比如Vue,React等就變得容易維護了呢?

Vue和jQuery之間的區別只有一點,聲明式與命令式。

我們可以想一下,我們用jQuery去操作DOM的目的是什嗎?是為了局部更新視圖,換句話說是為了局部重新渲染。

jQuery是命令式的操作DOM,命令式的局部更新視圖,而現代主流架構Vue,React,Angular等都是聲明式的,聲明式的局部更新視圖。

為什麼聲明式的操作DOM就可以讓應用變得好維護了呢?

弄明白這個問題首先我們先簡單介紹下什麼是命令式,什麼是聲明式。

命令式

命令式,像jQuery,我們都是想幹什麼然後就去幹就完了,例如下面的代碼:

$('.box')  .append('<p>Test</p>')  .xxx()  .yyy()  .jjj()  ...

命令式就是想幹什麼就直接去調用方法直接幹就完了,簡單直接粗暴。

試想一個很簡單的情境,比如一個toggle效果,點擊一個按鈕,切換顏色。

用命令式寫,我們肯定是這樣寫,如果當前是什麼顏色就讓它變成另外一個顏色。

如果你仔細思考,其實這裡面可以細分成兩個行為,一個是對狀態判斷,另一個是操作DOM。

那什麼是聲明式??

聲明式

聲明式是通過描述狀態與視圖之間的映射關係,然後通過這樣的一個映射關係來操作DOM,或者說具體點是用這樣的映射關係來產生一個DOM節點插入到頁面去。比如Vue中的模板。模板的作用就用是來描述狀態與DOM的映射關係。

同樣的情境,我們用Vue中的模板來實現,當我們用模板描述了映射關係之後,我們在點擊按鈕時,我們只需要對顏色這個變數進行修改就可以完成需求。

看到區別了嗎?

仔細思考下,用Vue來實現同樣的需求,如果細分來看,我們在邏輯上只有一個行為,只有狀態。而jQuery是兩個行為,狀態+DOM操作。

所以聲明式為什麼可以簡化維護應用代碼的複雜度?

因為它讓我們可以把關注點只放在狀態的維護上。這樣一來當應用複雜後,其實我們的思維,我們管理代碼的方式只在狀態上,所有的DOM操作都不用關心了,可以說大大降低代碼維護的複雜度。

我們不再需要關注怎麼操作DOM,因為架構會幫我們自動去做,我們只關注狀態就好了。

但是如果應用特別特別複雜,我們會發現即便是我們只關注狀態的維護,依然很難,即便只維護狀態也很難,所以才出現了Vuex,Redux等技術解決方案。

什麼是渲染?

經過前面的介紹,你會發現其實現代主流架構要解決的最本質的問題依然是渲染,只是不同架構之間的解決方案有差異,那麼什麼是渲染?

現在開發前端,我們的應用在運行時需要不斷的進行各種互動,現代主流架構讓我們把關注點放在了狀態的維護上,也就是說應用在運行時,應用內部的狀態會不斷的發生變化。

而將狀態產生DOM插入到頁面展示在使用者介面上,這一套流程叫做渲染。

現代前端架構對渲染的處理

當應用在運行時,內部狀態會不斷的發生變化,這時使用者頁面的某個局部地區需要不停的重新渲染。

如何重新渲染?

最簡單粗暴的解決方式,也是我平時在沒有使用任何架構的項目裡寫的一些簡單的功能時最常用的方式是用狀態產生一份新的DOM,然後用innerHTML把舊DOM替換了。

我寫的小功能塊用這種方式沒問題,因為功能涉及到的DOM標籤少,狀態變的時候,幾乎就是我這個功能塊的所有標籤都需要變,所以即便是用innerHTML也不會有太大的效能浪費,是在可接受範圍內的。

但是架構不行,架構如果用innerHTML這樣去替換,那就不是局部重新渲染了,而是整個頁面整體重新整理,這性質就變了,那麼架構如何做到局部重新渲染?

解決這個問題,需要一些技術方案來解決,可以是VirtualDOM,但並不一定必須是VirtualDOM,也可以是Angular中的髒檢測的流程,也可以是細粒度的綁定,像Vue1.0就是使用細粒度的綁定來實現的。

什麼是細粒度綁定?

細粒度的綁定意思是說,當某個狀態,與之綁定的是頁面中的某個具體的標籤。就是說,如果模板中有十個標籤使用了某個變數,那麼與這個變數所綁定的就是10個具體的標籤。

相對比較React和Angular粒度都比較粗,他們的變化偵測其實不知道具體哪個狀態變數,所以需要一個暴力的比對,比對後才知道需要對視圖中的哪個部分進行更新。

而Vue這種細粒度的綁定其實在狀態發生變化的那一個瞬間,立刻就知道哪個狀態變了,而且還知道有哪些具體的標籤使用了這個狀態,那麼事情就變的簡單的多了,直接把與這個狀態所綁定的這些具體的標籤進行更新就能達到局部更新的目的。

但是這樣做其實也有一定的代價,因為粒度太細,會有一定的依賴追蹤的開銷。所以Vue2.0開始採取了一個折中的方案,就是把綁定調整為中等粒度。

一個狀態對應某個組件,而不再是具體標籤,這樣做有一個好處是可以大大降低依賴的數量,畢竟組件的數量與DOM中的具體標籤比,數量要少的多。但是這樣就需要多一個操作,當狀態發生變化只通知到組件,那麼組件內部如何知道具體更新哪個DOM標籤??

答案是VirtualDOM。

也就是說,當粒度調整為中等之後,需要多一個操作就是在組件內部使用VirtualDOM去重新渲染。

Vue很聰明地通過變化偵測+VirtualDOM這兩種技術方案,提升了架構啟動並執行效能問題。

所以說,Vue2.0引入VirtualDOM並不是因為VirtualDOM有多好,而是恰好VirtualDOM結合變化偵測可以將綁定調整成中等粒度來解決依賴追蹤的開銷問題。

關於變化偵測我專門寫過文章來介紹Vue是如何?變化偵測的。傳送門。

所以變化偵測的方式,在一定程度上就已經決定了架構如何進行渲染。

關於VirtualDOM的實現原理我寫過一個PPT,有興趣的可以看看,傳送門。

還有一個是模板編譯,其實前面對於模板編譯這個問題並沒有說太多,模板的作用是描述狀態與DOM之間的映射關係,通過模板可以編譯出一個渲染函數,執行這個渲染函數可以得到VirtualDOM中所提供的VNode,事實上你看過我前面介紹VirtualDOM原理的PPT你就會知道VirtualDOM對節點進行diff其實是對VNode進行diff。關於模板編譯的實現原理我專門寫過一篇文章介紹過,傳送門。

總結

現在的前端我個人感覺有點浮躁,很多人都在追新,每天關注一些今天出了一個新特性,明天出了一個新架構什麼的,對於這些我是贊成的,但是我更希望在追新的同時,要看到它的本質。所有技術解決方案的終極目標都是在解決問題,都是先有問題,然後在有解決方案,解決方案可能並不完美,可能解決方案有很多種,那麼他們之間都有哪些優缺點?解決問題的同時各自都做了哪些權衡和取捨?我們要透過現象看本質才不至於被表面所迷惑。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.