<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                上一小節介紹了如何做圖片加載相關的優化以及壓縮代碼,這一部分內容會稍微深入點,講解如何利用瀏覽器的緩存以及在 webpack 中實現按需加載代碼。 ## 分離代碼文件 關于分離 CSS 文件這個主題,之前在介紹如何搭建基本的前端開發環境時有提及,在 webpack 中使用 [extract-text-webpack-plugin](https://doc.webpack-china.org/plugins/extract-text-webpack-plugin) 插件即可。 先簡單解釋一下為何要把 CSS 文件分離出來,而不是直接一起打包在 JS 中。最主要的原因是我們希望更好地利用緩存。 假設我們原本頁面的靜態資源都打包成一個 JS 文件,加載頁面時雖然只需要加載一個 JS 文件,但是我們的代碼一旦改變了,用戶訪問新的頁面時就需要重新加載一個新的 JS 文件。有些情況下,我們只是單獨修改了樣式,這樣也要重新加載整個應用的 JS 文件,相當不劃算。 還有一種情況是我們有多個頁面,它們都可以共用一部分樣式(這是很常見的,CSS Reset、基礎組件樣式等基本都是跨頁面通用),如果每個頁面都單獨打包一個 JS 文件,那么每次訪問頁面都會重復加載原本可以共享的那些 CSS 代碼。如果分離開來,第二個頁面就有了 CSS 文件的緩存,訪問速度自然會加快。雖然對第一個頁面來說多了一個請求,但是對隨后的頁面來說,緩存帶來的速度提升相對更加可觀。 因此當我們考慮更好地利用緩存來加速靜態資源訪問時,會嘗試把一些公共資源單獨分離開來,利用緩存加速,以避免重復的加載。除了公共的 CSS 文件或者圖片資源等,當我們的 JS 代碼文件過大的時候,也可以用代碼文件拆分的辦法來進行優化。 那么,如何使用 webpack 來把代碼中公共使用的部分分離成為獨立的文件呢?由于 webpack 4.x 和 webpack 3.x 在代碼分離這一塊的內容差別比較大,因而我們分別都介紹一下。 3.x 以前的版本是使用 CommonsChunkPlugin 來做代碼分離的,而 webpack 4.x 則是把相關的功能包到了 `optimize.splitChunks` 中,直接使用該配置就可以實現代碼分離。 我們先介紹在 webpack 4.x 中如何使用這個配置來實現代碼分離。 ## webpack 4.x 的 optimization webpack 的作者推薦直接這樣簡單地配置: ``` module.exports = { // ... webpack 配置 optimization: { splitChunks: { chunks: "all", // 所有的 chunks 代碼公共的部分分離出來成為一個單獨的文件 }, }, } ``` 我們需要在 HTML 中引用兩個構建出來的 JS 文件,并且 commons.js 需要在入口代碼之前。下面是個簡單的例子: ``` <script src="commons.js" charset="utf-8"></script> <script src="entry.bundle.js" charset="utf-8"></script> ``` 如果你使用了 html-webpack-plugin,那么對應需要的 JS 文件都會在 HTML 文件中正確引用,不用擔心。如果沒有使用,那么你需要從 `stats` 的 `entrypoints` 屬性來獲取入口應該引用哪些 JS 文件,可以參考 [Node API](https://doc.webpack-china.org/api/node/) 了解如何從 `stats` 中獲取信息,或者開發一個 plugin 來處理正確引用 JS 文件這個問題。第 15 小節會介紹如何開發 webpack plugin,plugin 提供的 API 也可以正確獲取到 `stats` 中的數據。 之前我們提到拆分文件是為了更好地利用緩存,分離公共類庫很大程度上是為了讓多頁面利用緩存,從而減少下載的代碼量,同時,也有代碼變更時可以利用緩存減少下載代碼量的好處。從這個角度出發,筆者建議將公共使用的第三方類庫顯式地配置為公共的部分,而不是 webpack 自己去判斷處理。因為公共的第三方類庫通常升級頻率相對低一些,這樣可以避免因公共 chunk 的頻繁變更而導致緩存失效。 顯式配置共享類庫可以這么操作: ``` module.exports = { entry: { vendor: ["react", "lodash", "angular", ...], // 指定公共使用的第三方類庫 }, optimization: { splitChunks: { cacheGroups: { vendor: { chunks: "initial", test: "vendor", name: "vendor", // 使用 vendor 入口作為公共部分 enforce: true, }, }, }, }, // ... 其他配置 } // 或者 module.exports = { optimization: { splitChunks: { cacheGroups: { vendor: { test: /react|angluar|lodash/, // 直接使用 test 來做路徑匹配 chunks: "initial", name: "vendor", enforce: true, }, }, }, }, } // 或者 module.exports = { optimization: { splitChunks: { cacheGroups: { vendor: { chunks: "initial", test: path.resolve(__dirname, "node_modules") // 路徑在 node_modules 目錄下的都作為公共部分 name: "vendor", // 使用 vendor 入口作為公共部分 enforce: true, }, }, }, }, } ``` 上述第一種做法是顯示指定哪些類庫作為公共部分,第二種做法實現的功能差不多,只是利用了 `test` 來做模塊路徑的匹配,第三種做法是把所有在 node\_modules 下的模塊,即作為依賴安裝的,都作為公共部分。你可以針對項目情況,選擇最合適的做法。 ## webpack 3.x 的 CommonsChunkPlugin 下面我們簡單介紹一下在 webpack 3.x 中如何配置代碼分離。webpack 3.x 以下的版本需要用到 webpack 自身提供的 CommonsChunkPlugin 插件。我們先來看一個最簡單的例子: ``` module.exports = { // ... plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: "commons", // 公共使用的 chunk 的名稱 filename: "commons.js", // 公共 chunk 的生成文件名 minChunks: 3, // 公共的部分必須被 3 個 chunk 共享 }), ], } ``` chunk 在這里是構建的主干,可以簡單理解為一個入口對應一個 chunk。 以上插件配置在構建后會生成一個 commons.js 文件,該文件就是代碼中的公共部分。上面的配置中 `minChunks` 字段為 3,該字段的意思是當一個模塊被 3 個以上的 chunk 依賴時,這個模塊就會被劃分到 `commons` chunk 中去。單從這個配置的角度上講,這種方式并沒有 4.x 的 `chunks: "all"` 那么方便。 CommonsChunkPlugin 也是支持顯式配置共享類庫的: ``` module.exports = { entry: { vendor: ['react', 'react-redux'], // 指定公共使用的第三方類庫 app: './src/entry', // ... }, // ... plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor' // 使用 vendor 入口作為公共部分 filename: "vendor.js", minChunks: Infinity, // 這個配置會讓 webpack 不再自動抽離公共模塊 }), ], } ``` 上述配置會生成一個名為 vendor.js 的共享代碼文件,里面包含了 React 和 React-Redux 庫的代碼,可以提供給多個不同的入口代碼使用。這里的 `minChunks` 字段的配置,我們使用了 `Infinity`,可以理解為 webpack 不自動抽離公共模塊。如果這里和之前一樣依舊設置為 3,那么被 3 個以上的 chunk 依賴的模塊會和 React、React-Redux 一同打包進 vendor,這樣就失去顯式指定的意義了。 `minChunks` 其實還可以是一個函數,如: ``` minChunks: (module, count) => { console.log(module, count); return true; }, ``` 該函數在分析每一個依賴的時候會被調用,傳入當前依賴模塊的信息 `module`,以及已經被作為公共模塊的數量 `count`,你可以在函數中針對每一個模塊做更加精細化的控制。看一個簡單的例子: ``` minChunks: (module, count) => { return module.context && module.context.includes("node_modules"); // node_modules 目錄下的模塊都作為公共部分,效果就如同 webpack 4.x 中的 test: path.resolve(__dirname, "node_modules") }, ``` 更多使用 CommonsChunkPlugin 的配置參考官方文檔 [commons-chunk-plugin](https://doc.webpack-china.org/plugins/commons-chunk-plugin/#-)。 而關于 webpack 4.x 的 splitChunks 配置,筆者寫這一部分的時候官方文檔還沒有更新出來,上述配置預估可以滿足大部分項目的需求,更加詳細的內容還請等待官方文檔更新后查閱。 ## 小結 本小節是優化前端資源加載這個主題的第二部分,主要分別介紹了在 webpack 4.x 版本和 3.x 版本中,如何配置分離代碼文件來更加高效地利用瀏覽器緩存。webpack 兩個版本關于分離代碼這一塊的使用差異比較大,筆者還是推薦使用 4.x 版本,因為它的配置相對來說要更加簡單一些。接下來第 11 小節會介紹優化前端資源加載的最后一個部分的內容。 ## 例子 本小節提及的一些簡單的 Demo 可以在 [webpack-examples](https://github.com/teabyii/webpack-examples) 找到。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看