效果展示

打包时间:缩短了 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'

WebPack系列--开启HappyPack之后,再将项目打包速度缩短5秒的更多相关文章

  1. sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩

    经常有新手同学抱怨说sencha touch的项目加载速度为什么这么慢,经常要10秒左右的时间甚至更多, 大家都知道,sencha touch开发的项目中引用了大量的js文件,当我们打开项目时,st的 ...

  2. vue+webpack+element-ui项目打包优化速度与app.js、vendor.js打包后文件过大

    从开通博客到现在也没写什么东西,最近几天一直在研究vue+webpack+element-ui项目打包速度优化,想把这几天的成果记录下来,可能对前端牛人来说我这技术比较菜,但还是希望给有需要的朋友提供 ...

  3. vue项目打包文件配置(vue-clli3)

    练手项目完结打包的时候遇到一些问题,特此记录 先贴我的vue.config.js文件的代码(vue-cli3构建的项目默认是没有此文件的,需手动添加)更多详细配置参考官方配置文档,我的项目不大不小,这 ...

  4. Vue实战Vue-cli项目构建(Vue+webpack系列之一)

    用Vue比较长一段时间了,大大小小做了一些项目,最近想总结一下知识点,出一个Vue+webpack系列,先从项目构建说起--vue-cli. 由于是Vue+webpack这里就不赘述git那些东西,默 ...

  5. 深入浅出的webpack构建工具---HappyPack优化构建(九)

    阅读目录 一:什么是HappyPack? 作用是什么? 二:如何在配置中使用HappyPack? 回到顶部 一:什么是HappyPack? 作用是什么? Webpack是允许在NodeJS中的,它是单 ...

  6. Webpack系列-第三篇流程杂记

    系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节 ...

  7. 实战webpack系列03

    03.Webpack的强大功能 一.生成Source Maps(使调试更容易) 通过简单的配置,webpack就可以在打包时为我们生成的source maps,这为我们提供了一种对应编译文件和源文件的 ...

  8. 【webpack 系列】基础篇

    Webpack 基础篇 基本概念 Webpack 是一个现代 JavaScript 应用程序的静态模块打包器.当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每 ...

  9. 【webpack 系列】进阶篇

    本文将继续引入更多的 webpack 配置,建议先阅读[webpack 系列]基础篇的内容.如果发现文中有任何错误,请在评论区指正.本文所有代码都可在 github 找到. 打包多页应用 之前我们配置 ...

随机推荐

  1. 完整的 LDAP + phpLDAPadmin安装部署流程 (ubuntu18.04)

    LDAP 安装部署以及基础使用 因工作需求需要使用ldap管理用户权限,在踩了一系列坑之后,总结了一些流畅的文档,希望可以帮到和曾经的我一样迷茫的人. 基础环境:Ubuntu 18.04 一.安装 r ...

  2. 死磕hyperledger fabric源码|Order节点概述

    死磕hyperledger fabric源码|Order节点概述 文章及代码:https://github.com/blockchainGuide/ 分支:v1.1.0 前言及源码目录 Orderer ...

  3. ZooTeam 前端周刊|第 111期

    转: ZooTeam 前端周刊|第 111期 ZooTeam 前端周刊|第 111期 浏览更多往期周刊,请访问: https://weekly.zoo.team 基于Vue的前端架构,我做了这15点 ...

  4. HDOJ-1069(动态规划+排序+嵌套矩形问题)

    Monkey and Banana HDOJ-1069 这里实际是嵌套矩形问题的变式,也就是求不固定起点的最长路径 动态转移方程为:dp[i]=max(dp[j]+block[i].h|(i,j)∈m ...

  5. PAT-1145(Hashing - Average Search Time)哈希表+二次探测解决冲突

    Hashing - Average Search Time PAT-1145 需要注意本题的table的容量设置 二次探测,只考虑正增量 这里计算平均查找长度的方法和书本中的不同 #include&l ...

  6. 如何快速的插入 100W数据到数据库,使用PreparedStatement 最快实现!

    有时候,我们使用数据库的时候,如何快速的添加测试数据到数据库中,做测试呢,添加100W 数据,如果使用工具的话可能很慢,这里我推荐大家使用 PreparedStatement 预编译 去进行操作:单线 ...

  7. ECMAScript 2016(ES7)新特性简介

    简介 自从ES6(ECMAScript 2015)在2015年发布以来,ECMAScript以每年一个版本的速度持续向前发展.到现在已经是ECMAScript 2020了. 每个版本都有一些新的特性, ...

  8. Android R 新特性分析及适配指南

    Android R(Android 11 API 30)于2020年9月9日正式发布,随国内各终端厂商在售Android设备的版本更新升级,应用软件对Android R 版本的兼容适配已迫在眉睫. 对 ...

  9. Java中的四种权限修饰符及六种非访问修饰符(简识)

    一.是哪四种访问权限修饰符呢? public > protected > [default] > private (公共的 ) (受保护的) (默认的) (私有的) 二.简单认识四种 ...

  10. C语言II博客作业02

    这个作业属于那个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-4 这个作业要求在哪里 https://edu.cnblogs.com/campus/zs ...