首頁  >  文章  >  web前端  >  聊對現代前端框架的認知

聊對現代前端框架的認知

青灯夜游
青灯夜游原創
2018-09-10 16:14:151385瀏覽

本章聊聊對現代前端框架的認知,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

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

其實之所以現在我們需要選擇框架,本質上是因為我們面臨的需求改變了。大家一定都明白如果我們只寫一個純粹展示資訊的頁面,沒有任何互動功能的頁面,其實即便是現在,我們也是不需要選擇框架的,我們只需要寫幾行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(&#39;<p>Test</p>&#39;)
  .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。關於模板編譯的實作原理我特別寫過一篇文章介紹過,傳送門。

總結

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




以上是聊對現代前端框架的認知的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn