資源表+載入器的方案為什麼沒有webpack的本地打包方案流行?

生成資源表+自己寫的載入器,可以實現更細粒度的載入方案,感覺比webpack的方案更直觀,可控性好。webpack只能實現本地打包,為什麼更加流行?


一開始看到這個問題的時候有一點不是很理解。所謂的資源表是一張全局資源表,還是每個頁面對應的資源表?更細粒度的載入是什麼?直觀和可控如何體現?

我想了一下,估計是這樣的場景:有一張全局的資源表,記錄原始資源地址和上線後資源的地址,然後頁面聲明自己需要載入哪一些資源,用資源表去一一載入。

直觀嘛,也確實挺直觀的,資源表和載入的資源一一對應。可控也挺可控的,增減資源都很明白。

但是webpack的表現不好么?

webpack不需要你提供資源表,自己會處理好原始資源地址和上線後資源的地址,不需要頁面聲明自己要載入哪一些資源,而是使用入口文件的方式,將依賴全部自動處理好,明明是更省事的呀。

那所謂的直觀和可控呢?難道是指可以將資源拆開載入,這個webpack也有代碼分割來做的,也有common chunks提取公共資源呀。

感覺還是缺少前提和場景,寫不下去了,不如說說我想到的一些考慮點吧。

HTTP連接數

使用資源表的形式來載入資源,是否意味著沒有前置打包動作?如果是的話,那麼HTTP連接數過多將成為一個巨大的問題。可以參考一下require.js的方案,它也是在runtime進行動態載入的,但是為了減少HTTP連接數,也不得不推出r.js來進行打包,一旦涉及到打包,那就進入了webpack的優勢領域。

緩存

之所有會想到更細粒度的載入,不知道是不是因為考慮到緩存,粒度越細,被複用的代碼越多,緩存的可能性也就越大。但是緩存的粒度跟HTTP連接數是一個矛盾的東西,這是長久以前一直被討論的問題,代碼要合併到什麼樣的粒度,才能在緩存和HTTP連接數中取得平衡。而webpack給出了common chunks的機制,並不是很好用,但是能用。

按需載入

不知道是否有人認為,資源表可以按需載入,而webpack只能一大堆打成一個大包。這明顯是一個誤區,webpack給出了非同步載入的方案,會自動拆包和定址,用起來很方便。

模塊化規範

webpack剛開始流行起來時,有一個很重要的因素,就是它同時支持AMD/CommonJS規範,同時支持使用npm來做包管理,社區無數的代碼可以直接拿過來用,或者自己的代碼也可以使用npm更好地復用。而如果使用資源表+載入器(沒有編譯過程)的話,只能支持AMD,或者自己發明一個類似CMD之類的規範,而且還面臨包管理的難題。

編譯

在很多時候我們會混用「打包」和「編譯」這兩個詞,但是在這個問題下,區分是有必要的。打包主要是指把代碼合併成一個(幾個)文件,而編譯則涉及到代碼的轉換過程。事實上webpack的編譯帶來了非常多的可能性,比如我們可以在代碼中使用JSX、TypeScript、vue單文件組件、es 2015/2016/2017/...的特性、npm包等等,也可以使用autoprefixer、postcss、less、sass等做預處理。當然,這一些並不是webpack發明的,但是webpack把它們集成得相當好。同時,因為loader和plugin的機制,還有非常多的玩法,比如ProvidePlugin為代碼注入build時使用的變數(process.env.NODE_ENV==production等),比如更好地shim老舊代碼(庫)。


webpack也會生成資源表。


webpack和資源表打包不衝突。其實我們就是實現了使用一個資源表管理webpack如何打包文件的插件。實現原理就是利用commonschunkplugin的原理。


資源載入是一個權衡過程,很多時候web首要問題不是資源細粒度的管理,而是頁面打開速度。

在http2之前,每次資源訪問都需要重新發起連接請求。當資源過多會受到遊覽器限制而造成堵塞。反而造成等待時間過長。

webpack同樣支持code split,你想多細都行。但是大部分情況下,保持有限度的拆分來保證頁面載入速度才是正解。


Webpack不僅僅是打包,它的loader機制允許你使用級聯的處理器分類處理資源,這個是一個很乾凈高效的抽象,僅依靠數行聲明就可以完成gulp數個任務才能完成的工作

如果你使用過mvvm前端框架或者把大型項目從gulp遷移到webpack,這個感受應該是很深的


推薦閱讀:

我如何將 Webpack 包大小縮減一半
webpack源碼學習系列之一:如何實現一個簡單的webpack
Webpack原理-編寫Plugin
編寫自己的Webpack Loader
用webpack,輸出多個出口文件,每個出口文件對應一個頁面,重複引用jquery?

TAG:前端性能優化 | webpack |