WebPack系列--開啟HappyPack之后,再將項目打包速度縮短5秒


效果展示

打包時間:縮短了 26.296s-20.586s=5.71s

先看兩組測試數據,第一組是沒有使用DllPlugin的打包測試數據,測量三次取平均值是26.296s
(25.72+25.56+27.61)/3≈26.296s

 

第二組是使用了DllPlugin的打包測試數據,測量三次取平均值是20.586s
(20.62+21.31+19.83)/3≈20.586s 

 

 

打包體積:減少了 8.72M-4.8M=3.92M

沒用動態庫之前是8.72M

用了動態庫之后是1.8M+2958K≈4.8M
 

減少的原因是避免了在業務代碼中重復引入第三方工具包。

為什么會快?

我們的項目代碼,可以分為第三方工具包和業務代碼,第三方工具包一般比較成熟,用webpack打包編譯過,無需每次項目構建時都再次打包。可以把這部分代碼從剝離出去,通過外鏈script標簽引入,每次構建,只打包業務代碼。所以能縮短整體打包時間。

如何實現

要想實現這樣的效果,你需要在現有項目的基礎上,做如下配置:

第一步,安裝依賴

yarn add -D assets-webpack-plugin clean-webpack-plugin webpack-bundle-analyzer

第二步,編寫生成dll庫的webpack配置文件

const path = require("path");
const webpack = require("webpack");
const WebpackBar = require("webpackbar");
const AssetsPlugin = require("assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // 打包前清空dll文件夾
// 讀取package.json里的運行依賴包
const pkg = require("../package.json");
let dependencies = Object.keys(pkg.dependencies) || [];
dependencies = dependencies.length > 0 ? dependencies : [];

console.log("dll", dependencies);
module.exports = {
  entry: {
    dll: dependencies,
  },
  mode: "production",
  output: {
    path: path.resolve(__dirname, "../dll"),
    filename: "[name]_[hash:6].js",
    library: "[name]_[hash:6]", // 暴露給外部使用
    // libraryTarget 指定如何暴露內容,缺省時就是 var
  },
  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: [path.resolve(__dirname, "../dll/*.*")],
    }),
    new webpack.DllPlugin({
      path: path.resolve(__dirname, "../dll", "[name]-manifest.json"),
      name: "[name]_[hash:6]", // name和library一致
    }),
    // 把帶hash的dll.js插入到index.html中,和html-webpack-plugin插件配合使用,告訴html-webpack-plugin插入的dll.js文件名稱
    new AssetsPlugin({
      filename: "dll-config.json",
      path: "./dll/",
    }),
    // webpackbar可以在打包時實時顯示打包進度
    new WebpackBar(),
  ],
};

在package.json中,添加生成dll庫的指令:

"scripts": {
    "build:dll": "webpack --config webpack/dll.js",
},

生成動態庫

第三步:在index.html靜態模板中,加載動態庫

<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="utf-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover" />
    <meta name="theme-color" content="#000000" />
    <meta name="keywords" content="" />
    <meta name="description" content="" />
    <title></title>
</head>

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="//at.alicdn.com/t/font_1343302_nuzqn1v7zae.js"></script>
    <!-- 插入動態庫 -->
    <% if (htmlWebpackPlugin.options.dllJsName) { %>
    <script src="<%= htmlWebpackPlugin.options.dllJsName %>"></script>
    <% } %>
    <!-- iconfont svg地址 -->
</body>

</html>

第四步:在webpack.base.js中,配置動態庫加載和庫映射文件路徑

// 是否為本地開發環境
const isDev = process.env.NODE_ENV === "development";
// 根目錄
const basename = process.env.BASE_NAME ? `${process.env.BASE_NAME}/` : "/";
const publicPath = isDev ? "/" : `/${basename}`;
// 這里的路徑與webpack文件夾下的dll.js配置文件中的路徑保持一致
const dllConfig = require("../dll/dll-config.json");
const manifest = require("../dll/dll-manifest.json");

module.exports = {
  plugins: [
    new HtmlPlugin({
      template: path.resolve(rootPath, "./index.html"),
      favicon: path.resolve(rootPath, "./favicon.ico"),
      // index.html中加載dll的script標簽的src地址
      dllJsName: isDev ? `${publicPath}dll/${dllConfig.dll.js}` : "",
      // html壓縮
      minify: {
        collapseWhitespace: true,
        preserveLineBreaks: true,
      },
    }),
    // 加載生成的dll庫
    isDev
      ? new webpack.DllReferencePlugin({
          manifest,
        })
      : () => {},
  ],
};

打包構建時,查看打包內容和大小的配置

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; // 包分析工具
module.module.exports = () => {
  return merge(webpackBaseConfig, {
    plugins: [
      process.argv.indexOf("--pa") !== -1
        ? new BundleAnalyzerPlugin()
        : () => {},
    ],
  });
};

沒使用動態庫之前入口文件大小是1.43M

 使用了動態庫之后入口文件大小是648K

 問題與解答

首頁加載速度對比:使用動態庫之后,首頁加載速度變慢了3.08 - 2.51 =0.57s

使用動態庫之前,首頁加載時間是2.51s

使用動態庫之后,首頁加載時間是3.08s

使用了動態庫之后,如何不拖慢首頁的加載速度?

首頁加載速度變慢了一些,是由於打包的第三方庫,不再是按需加載,而是在首頁一次性加載,要改善這種情況,有兩條思路:

1.縮小打包體積,只把每個頁面都會用到的三方工具打包進動態庫, 還有對打包之后的內容進行gzip壓縮。

2.只在開發環境使用動態庫功能。

Dll和External的區別

對於如下的引用, Dll直接將庫的應用指向xxx庫,不會再把xxx/lib/module打包,而External則認為 import Foo from 'xxx' 和 import AA from 'xxx/lib/module',是引用了兩個不同的庫,因此xxx在項目中已經存在的情況下, xxx/lib/module還會被打包進項目。用import Foo from 'xxx/lib/module'這樣的方式引用模塊,使用動態庫是比較吃虧的。

import Foo from 'xxx/lib/module'

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM