2016前端探索總結——前端工程與未來

016年彈指一揮間,轉眼間已到了自己學習web的第三個年頭。在過去的這一年,前端領域發生了翻天覆地的變化——

  • Angular1.x慢慢退出舞臺,Angular2、React、Vue等新興的MVVM框架已接近成熟。經過一年的迭代,API與底層設計思路上有趨同之勢,但也慢慢顯現出在各自領域中的優勢。

  • 以Redux和Vuex為代表的類Flux設計架構,經過一年的探索和實踐,其在開發效率和維護追蹤上的優勢已被驗證,取代MVC成為了中大型web應用中最流行的框架模式。

  • Webpack、Rollup等包管理工具已是工程必備,ES6和Babel普及度已經很高了,前端開發完成從頁面到組件化??榛?、從解釋型到構建型的工程性轉變。

寫這篇文章的初衷,一是由于這一年中也大大小小做過好幾個項目,對于前端工程有一些淺薄的理解和經驗,想要成文記錄下來;二是結合已有的知識,暢想一下未來web發展的趨勢。

關于Flux的經驗思考

码报开奖结果本期 www.iwqgw.icu 何為Flux不再過多贅述,不懂的讀者推薦這篇文章圖解Flux。


說白了,Flux就是一種新的單向數據流的“視圖綁定式”解決方案。這里我個人加了“視圖綁定式”這個定義,是因為只有在View-Model綁定的基礎上,Flux才能充分發揮它的作用。

上圖是Flux的架構圖。簡單地說,Flux將視圖變成了狀態機,所有對視圖的操作都轉變為對Store的狀態操作。狀態的更新會通過各種框架的映射機制反應到視圖上。而在具體的實現中(Redux,Vuex),Store往往被設置成全局的單一狀態樹。這樣一來,各組件、各??櫓浣淮嬖諶魏問萁換ス叵?,完全解耦。所有的??榛蜃榧蛔鋈攏航郵沼沒г謔油疾愕鬧噶?,更改全局Store樹,從Store中獲取各組件的狀態。

由于沒有基于Redux做過工程方面的實踐,所以這里重點說一下Vuex,不知道Vuex的同學可以戳這里Vuex。(這里要特別安利Vue.js這款非常棒的漸進式框架,本身很輕,適合小型應用的開發,同時又有構建大型應用的解決方案)


(Vuex架構圖)

個人認為,利用Vuex,與傳統的MVVM架構相比,對于構建中大型項目有如下優勢——

  1. 很好地解決了父子組件數據級聯與組件間的通訊問題。在傳統的MVVM模式下,我們通常采用事件機制進行跨組件的數據傳輸,這種做法的一大壞處就在于組件之間產生耦合。在中大型規模的項目中,常常有上百甚至上千的組件(像這學期的學雷鋒項目教學輔助應用,算是中小型規模,就已經有將近50個組件),組件間的交互將變得極其復雜和難以追蹤,導致開發和維護成本非常高。而在Flux,確切地說是Vuex中,組件的所有動作都是發送事件,調用全局的action(action本質上是訂閱的回調函數)。同時,組件的狀態也是由全局的state樹派生出來,并與其綁定。如此,所有組件對視圖的更改,都轉變為對全局狀態的更改,從而避免了組件間的通訊。

  2. 方便追蹤應用數據流。前面我們提到,級聯的跨組件通訊帶來了很強的耦合性,不僅如此,還使得數據流難以追蹤。在使用MVC架構的中大型規模web項目中,前端往往一次性要存儲和展示幾十甚至上百種數據,牽扯到好幾種Model,并且這些Model之間一定是“糾纏不清”的。這時候一旦出現Bug,很難去進行Bug定位。而Vuex中數據流是單向的,事情就簡單很多——首先,定位出現Bug的相關視圖和操作;然后,根據視圖分析出相關State->Mutations->Actions(過程和數據流方向是相反的);最后,通過Actions和視圖操作找到出問題的組件。(如果你嚴格按照??榛蜃榧哪J嚼醋櫓?,那Debug效率又會提升很多。)

  3. 方便預測和回溯應用狀態。前面也提到,Flux架構下的應用實際是一個狀態機,而整個數據流是單向的,因此我們很容易根據一個Action便預測出應用下一階段的狀態。同時,在做“撤回”、“重做”等類似回溯的功能時,也可以很輕易地通過保存和提取應用在某一階段的狀態來實現。另外,Vuex中的Mutations專門用于更改State,官方建議是同步操作放在Mutations(參考這篇答案),這樣的好處是每當調用Mutations便可同步獲得一個新的應用狀態,方便做snapshot。

但任何框架或架構的引入,都必須基于對于項目類型和項目規模的考量之上。Flux尤擅于數據類型繁多,交互密集的應用,但對于數據類型較少、交互不多的應用(例如H5,展示型網站等),就不適用了。

另外,盡管是在中大型項目中,嚴格遵循Flux有時也會把一些問題復雜化,例如下面的.vue模板代碼:

<template>
  <div>
    <v-loading v-if="isLoading"></v-loading>     //一個loading動畫
  </div></template><script>
  import {mapState} from "vuex";
  export default {
    data(){
       return{
         isLoading:false           //局部state的形式
       }
    },
    computed:mapState(state){      //引入全局state的形式
       isLoading:state=>state.isLoading
    },
    methods:{
       someFunction(){
          isLoading=true;                             //第一種方式
          //this.$store.dispatch('isloading',true)    //第二種方式
          ...
       }
    }
  }</script>

上段代碼中使用了兩種引入state的模式,一種是組件自身的局部state,由data進行初始化;另一種是嚴格遵守Flux,從全局Store中提取的state。如果我們使用第二種方式更改一個動畫loading,那我們需要專門像下面的代碼一樣編寫actions,mutations:

export const loading=({commit},signal)=>{
  commit('loading',signal);}
const state={
  isLoading:false;                    //loading的全局state狀態}const mutations={
  loading(state,signal){
    state.isLoading=signal;           //更改state
  }}

當loading比較多的時候,會顯得很麻煩。而如果采用局部state的方式,我們只需要在methods中更改狀態即可。但問題在于,actions中常常有異步事件(如AJAX),需要在異步完成后調整loading的狀態,根據單向數據流的原則,看上去只能通過修改全局的state來達到目的。

ES6提供了一個非常好的工具——Promise。具體請參照Vuex文檔。如此我們便可以做到類似如下的調用:

    ...
  },
  methods:{
    someFunction(){
      this.$store.dispatch('loading',true).then(
        ()=>{          //成功回調
          isLoading=true;
        },        
        ()=>{}         //失敗回調
      )
    }
  }}

如此一來便能在Vuex的架構下充分利用局部State管理視圖,不僅可以提高開發效率,也有利于保持全局State的簡潔。

框架與工具的思考

尤大在文章"Vue2.0 漸進式前端解決方案"里對工具框架引入的考量作了非常恰當的比喻。

工具復雜度是為了處理內在復雜度所做的投資。為什么叫投資?那是因為如果投的太少,就起不到規模的效應,不會有合理的回報。這就像創業公司拿風投,投多少是很重要的問題。如果要解決的問題本身是非常復雜的,那么你用一個過于簡陋的工具應付它,就會遇到工具太弱而使得生產力受影響的問題。

這里的復雜度,我認為是針對特定團隊而言的。比如你的團隊對React全家桶有豐富的實踐經驗,那么在為相同的項目選型時,React的復雜度于你的團隊和于其他團隊是不同的。但這么看其實是很虛的,原因是很少有人能準確地評估應用內在復雜度和工具復雜度。

經過觀察,通常情況是高估內在復雜度,低估工具復雜度。所以現階段我總結了一條不是很正確,但起碼不會錯的方法論:以最佳實踐為基礎,再增量考察和評估額外的工具引入成本。


舉兩個栗子:

  1. 對于非常輕的頁面,如H5、活動頁面,最佳實踐一般是Jquery或zepto+UI庫。但現在很多輕頁面開始有一些數據交互的需求,需要考慮引入一些MVVM框架,這時候再增量評估引入React、Vue這些View層框架的復雜度及應用內在復雜度,而不是把Jquery或Zepto和它們放到同一地位來進行比較考量。

  2. 開發單頁面應用,一般來說是以數據交互為主的需求。Vue全家桶的最佳實踐是Webpack+Vue(單文件組件解決方案)+Vue-router。React全家桶的最佳實踐是Webpack+React+React-router。以此為基準,綜合項目預期成本,再考慮加入UI庫、Babel、Redux(Vuex)帶來的額外復雜度和消弭應用內在復雜度之間的平衡關系。

這樣的好處是基本跳過最佳實踐的復雜度評估,直接對風險較高、把握較低的復雜度部分進行評估,節省了決策成本,原因有二:

  • 一般來說,最佳實踐是在各種工具的組合下,復雜度最低的方案。

  • 最佳實踐本身包含了前人的決策經驗和教訓,沒有必要花過多時間來做重復地評估決策。

另外,以上所說的“最佳實踐”,有兩點需要注意的地方:

  1. 重點不是在best,而是在experience。不要陷入了找尋最優解的泥潭。

  2. “最佳”不是絕對概念,而是相對概念。一定要針對個人(團隊)的情況來考慮何為“最佳”。

前端工程化的思考總結

下圖展示了整個前端工程可能涉及到的各個環節,前端技術體系大局觀一文覆蓋式地簡要介紹了各層系統的職能。


這里我結合自身的知識和實踐經驗,列出一些實現成本并不大并且性價比很高的工程化方案:

  • 網絡性能優化:現在的web應用,大小動則上MB,加上一些靜態資源,在目前我大天朝的網絡環境下,在不做優化的基礎下達到類似“首屏3s”或“動態加載xxs”的非功能性需求,需要付出很昂貴的硬件成本。目前網絡優化主要有兩個思路:CDN加速和緩存策略。對于前者,大公司往往采取自建CDN節點的方式,而小公司可以使用類似七牛云這樣的云儲存來進行靜態資源的加速。而緩存策略則有許多的解決方案,有時還會牽扯到部署、迭代的問題。我的另一篇文章介紹了前端如何利用Webpack和服務器的緩存機制來解決應用緩存與增量更新的問題。(推薦這篇回答大公司里怎樣開發和部署前端代碼?)

  • 流量統計:這一塊市面上已有非常成熟的方案,如CNZZ、百度站長統計等。當然也可以自己做一套,難度并不大,基本原理是在頁面中拼裝出<script>標簽,再遠程加載javascript。

  • 自動化部署系統:這個系統可以包含倉庫代碼管理、一鍵部署、一鍵Pull/Push,具體可以針對業務定制。它可以簡化web應用從構建到上線的流程,提高效率,在快速迭代的web項目中非常有用。一個實現思路是利用后端服務調用預先編好的Shell腳本來完成命令行集操作,實現自動刪除舊代碼,clone新代碼,安裝環境等行為。

  • 代碼質量監控:可選的工具有JSLint和JSHint。前者對代碼要求極為嚴格,后者對代碼要求可以很寬松。Webstorm和PHPStorm已內置兩種工具,個人推薦使用JSHint。

除此之外,還有諸如日志系統、監控預警、自動化測試、API測試等細節領域,我還在探索階段,這里就不過多贅述了~

Web前端的未來

我認為一種技術的未來前景可以從這三個維度來分析:全新體驗、成本下降趨勢、市場潛力。

  • 全新體驗:即帶給用戶一個前所未有的體驗。從需求角度來說就是幫助用戶塑造全新的預期,并做持續性的滿足。

  • 成本下降趨勢:這里的成本,不僅包括開發人員的人時成本、維護成本、工具鏈成本等,還包括可能遺留的技術債務,未來“還清債務”的成本。

  • 市場潛力:評估某項技術的市場潛力,可以看以這項技術為核心的行業在未來的市場容量。

從這三個維度出發,我們不難發現web未來發展的三個可能趨勢:

  1. WebVR:WebVR是一塊全新的領域,能夠在低成本設備上塑造VR的體驗,同時也是高端平臺快速瀏覽、分發內容的一種形式。早在2016年上半年,Mozilla就攜手一眾廠商完成了WebVR標準的制定,并在年底發布了Mobile、Oculus Rfit、HTC vive三種平臺的解決方案Mozilla VR。同時,優秀了很久的3D引擎庫three.js,也將成為WebVR的重要技術基石。

  2. 大前端:@向昶宇向總在我浙INA的一次內部分享中也提到了對“大前端”的看法,我非常贊同。 Web,準確地說是Javascript,將會成為web應用、移動端Native應用、桌面應用、智能設備應用、智能硬件(沒錯,JS已經能用來寫硬件了——Ruff)的一種更廉價的替代技術。在未來,也許你的公司不再需要同時組件Web、IOS、Android三支開發隊伍,取而代之的是一支大前端團隊。

  3. WebRTC:目前各大網站的視音頻通訊和游戲都依賴于Flash,而Flash在未來兩年應該會被全面淘汰。WebRTC被瀏覽器原生支持,實現了瀏覽器之間P2P的實時數據傳輸,同時是目前對于瀏覽器來說唯一一個可以不用Flash與外界使用UDP進行數據交換的技術,在流量節省和擁塞控制上具有很大的優勢。隨著各大瀏覽器實現對WebRTC的支持(目前只有Chrome、Firefox和Opera),在未來它一定會成為網絡音視頻和在線游戲實時數據傳輸的主要解決方案。

作者:LowesYang
來源:知乎

上一篇: 前端進階之路!如何高質量完成產品需求開發?

下一篇: JavaScript技術面試時要小心的三個問題

分享到: 更多
美女捕鱼游戏手机版 东京五分彩 北京pk10十码刷水 时时彩平台哪个好 北京pk赛车开结果结果 越南河内时时彩开奖结果 850通比牛牛怎么赢 非凡炸金花要怎么下载 单机麻将免费版手机版 二八杠棋牌游戏平台 抢庄牌九网站 十三幺怎么胡 单机斗地主电脑版下载 近期电子送彩金网址 拼多多签到满十元怎么提现 百人牛牛