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'
WebPack系列--开启HappyPack之后,再将项目打包速度缩短5秒的更多相关文章
- sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩
经常有新手同学抱怨说sencha touch的项目加载速度为什么这么慢,经常要10秒左右的时间甚至更多, 大家都知道,sencha touch开发的项目中引用了大量的js文件,当我们打开项目时,st的 ...
- vue+webpack+element-ui项目打包优化速度与app.js、vendor.js打包后文件过大
从开通博客到现在也没写什么东西,最近几天一直在研究vue+webpack+element-ui项目打包速度优化,想把这几天的成果记录下来,可能对前端牛人来说我这技术比较菜,但还是希望给有需要的朋友提供 ...
- vue项目打包文件配置(vue-clli3)
练手项目完结打包的时候遇到一些问题,特此记录 先贴我的vue.config.js文件的代码(vue-cli3构建的项目默认是没有此文件的,需手动添加)更多详细配置参考官方配置文档,我的项目不大不小,这 ...
- Vue实战Vue-cli项目构建(Vue+webpack系列之一)
用Vue比较长一段时间了,大大小小做了一些项目,最近想总结一下知识点,出一个Vue+webpack系列,先从项目构建说起--vue-cli. 由于是Vue+webpack这里就不赘述git那些东西,默 ...
- 深入浅出的webpack构建工具---HappyPack优化构建(九)
阅读目录 一:什么是HappyPack? 作用是什么? 二:如何在配置中使用HappyPack? 回到顶部 一:什么是HappyPack? 作用是什么? Webpack是允许在NodeJS中的,它是单 ...
- Webpack系列-第三篇流程杂记
系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节 ...
- 实战webpack系列03
03.Webpack的强大功能 一.生成Source Maps(使调试更容易) 通过简单的配置,webpack就可以在打包时为我们生成的source maps,这为我们提供了一种对应编译文件和源文件的 ...
- 【webpack 系列】基础篇
Webpack 基础篇 基本概念 Webpack 是一个现代 JavaScript 应用程序的静态模块打包器.当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每 ...
- 【webpack 系列】进阶篇
本文将继续引入更多的 webpack 配置,建议先阅读[webpack 系列]基础篇的内容.如果发现文中有任何错误,请在评论区指正.本文所有代码都可在 github 找到. 打包多页应用 之前我们配置 ...
随机推荐
- SpringCloud之服务调用
1.Ribbon 1.1负载均衡LB 全称Load Balance,将用户的请求平摊到多个服务器上,从而达到系统的HA.集中式LB:在服务消费者和服务提供者之间使用独立的LB设施,如硬件,由该设施负责 ...
- spring boot的 yml和properties的对比
Spring Boot 虽然做了大量的工作来简化配置,但其配置依然是相当的复杂!支持的外部配置方式就有很多种,笔者没有去统计,也许是为了灵活使用吧. application.yml 和 appli ...
- Kubernetes-2.组件
内容主要摘自官网文档资料 官网地址 本文概述了交付正常运行的Kubernetes集群所需的各种组件. 本文编写基于kubernetes v1.17版本 目录 Kubernetes集群 Master组件 ...
- springboot源码(4)
我们上3个篇章写了springboot的自动装配.servlet组件的注入以及web容器实现内嵌的原理,现在我们来看springboot启动过程中到底做了些什么,也就是打开我们的run方法: 这里我们 ...
- Linux常用操作命令之文件权限(二)
一.基本概念 Linux/Unix是多用户系统:root是超级用户,拥有最高权限,其他用户及权限由root管理.文件/目录的权限有三种,可读read(r)可写write(w)可执行excute(x). ...
- 一个 java 文件的执行过程详解
平时我们都使用 idea.eclipse 等软件来编写代码,在编写完之后直接点击运行就可以启动程序了,那么这个过程是怎么样的? 总体过程 我们编写的 java 文件在由编译器编译后会生成对应的 cla ...
- pytorch(05)计算图
张量的一系列操作,增多,导致可能出现多个操作之间的串行并行,协同不同的底层之间的协作,避免操作的冗余.计算图就是为了解决这些问题产生的. 计算图与动态图机制 1. 计算图 计算图用来描述运算的有向无环 ...
- FreeBSD 12.2 vmware 虚拟机镜像 bt 种子
安装了 KDE5 火狐浏览器 Fcitx 输入法 并进行了中文设置 替换软件源为国内可用. VirtualBox虚拟机也可以用 magnet:?xt=urn:btih:E88885631B57426 ...
- 你想知道的 std::vector::push_back 和 std::vector::emplace_back
引言 C++ 11 后,标准库容器 std::vector 包含了成员函数 emplace 和 emplace_back.emplace 在容器指定位置插入元素,emplace_back 在容器末尾添 ...
- 2017算法期末复习练习赛-G Beihang Couple Pairing Comunity 2017 题解(网络流)
理解不够透彻.好题不可浪费,写题解以增进理解.会陆续补充题目.(咕咕咕) G Beihang Couple Pairing Comunity 2017 题目链接 Beihang Couple Pair ...