Webpack 性能优化 (一)(使用别名做重定向)
前言
Webpack 是 OneAPM 前端技术栈中非常重要的一部分。它非常好用,假设你还不了解它,建议你阅读这篇Webpack 入门指迷,在 OneAPM 我们用它完毕静态资源打包。ES6 代码的转换 ,React 组件的组织等,在接下来的日子里,我们将通过一系列文章和业界分享我们在使用 Webpack 过程中关于性能方面的经验。
作为系列文章的第一篇。我们会重点介绍 Webpack 中的 resolve.alias ,也就是请求重定向。
只是请注意 Webpack 里的请求是对模块的依赖,也就是一个 require语句,而不是一个 HTTP 请求。
必要的准备
- 须要你有一定的 Node.js 基础
- 电脑上装有最新版的 Webpack (npm install webpack -g)
- 了解 Webpack 配置文件的格式
样例:本地时钟
要实现的功能非常easy。就是在页面上用中文显示当前时间,须要用到 moment 这个库,这个库封装了非常多和日期相关的函数,并且自带了国际化的支持。
新建一个 Node.js 项目
使用 npm init 初始化你的项目,然后通过npm install moment -D加上 moment 的开发人员依赖。
新建一个entry.js作为入口文件,当然你也能够用 app.js 这种名字,仅仅是大部分的 Webpack 演示样例都是用的是 entry.js。
var moment = require('moment');
document.write(moment().locale('zh-cn').format('LLLL'));
新建一个页面index.html, 引用 bundle.js:
<body>
<h5>当前时间:</h5>
<script src="dist/bundle.js"></script>
</body>
此时的文件文件夹看起来是这种:
index.html
package.json
entry.js
node_modules/moment
到眼下为止 bundle.js 这个文件还不存在,只是别着急,接下来的工作就交给 Webpack 来完毕。
index.html ------------------------+
package.json |
+--> <Clock App>
entry.js --------+ |
+-->bundle.js+--+
node_modules/moment-+
如图,Webpack 会把 entry.js 和 moment模块一起打包成一个 bundle.js 文件,和 index.html 一起构成了我们的 Clock App。怎么样,是不是已经听到 Clock App 滴答作响了?
使用 webpack 打包代码
在命令行执行:
webpack --entry ./entry.js --output-path dist --output-file bundle.js
你会看到相似以下的输出结果:
Hash: bf9007fb1e0cb30e3ef7
Version: webpack 1.10.0
Time: 650ms
Asset Size Chunks Chunk Names
bundle.js 378 kB 0 [emitted] null
[0] ./entry.js 125 bytes {0} [built]
+ 86 hidden modules
能够看到,耗时 650ms,这么慢着实让人意外,一定要想办法提高“新一代神器”速度;还有一方面,最后一行的 + 86 hidden modules 非常让人怀疑:明明是一个简单的 Clock App,怎么会有这么多的依赖。
怎样高速定位 Webpack 速度慢的原因
再一次。在命令行输入:
webpack --entry ./entry.js --output-path dist --output-file bundle.js \
--colors \
--profile \
--display-modules
只是这次新添加了三个參数,这三个參数的含义各自是:
--colors输出结果带彩色,比方:会用红色显示耗时较长的步骤--profile输出性能数据,能够看到每一步的耗时--display-modules默认情况下node_modules下的模块会被隐藏,加上这个參数能够显示这些被隐藏的模块
这次命令行的结果已经非常有參考价值,能够帮助我们定位耗时比較长的步骤
Hash: bf9007fb1e0cb30e3ef7
Version: webpack 1.10.0
Time: 650ms
Asset Size Chunks Chunk Names
bundle.js 378 kB 0 [emitted] null
[0] ./entry.js 125 bytes {0} [built]
factory:11ms building:8ms = 19ms
[1] ../~/moment/moment.js 102 kB {0} [built]
[0] 19ms -> factory:7ms building:141ms = 167ms
[2] (webpack)/buildin/module.js 251 bytes {0} [built]
[0] 19ms -> [1] 148ms -> factory:132ms building:159ms = 458ms
[3] ../~/moment/locale ^\.\/.*$ 2.01 kB {0} [optional] [built]
[0] 19ms -> [1] 148ms -> factory:6ms building:10ms dependencies:113ms = 296ms
[4] ../~/moment/locale/af.js 2.57 kB {0} [optional] [built]
[0] 19ms -> [1] 148ms -> [3] 16ms -> factory:52ms building:65ms dependencies:138ms = 438ms
..... 广告切割线,Node.js project师简历请发 nodejs@oneapm.com ......
[85] ../~/moment/locale/zh-cn.js 4.31 kB {0} [optional] [built]
[0] 22ms -> [1] 162ms -> [3] 18ms -> factory:125ms building:145ms dependencies:22ms = 494ms
[86] ../~/moment/locale/zh-tw.js 3.07 kB {0} [optional] [built]
[0] 22ms -> [1] 162ms -> [3] 18ms -> factory:126ms building:146ms dependencies:21ms = 495ms
从命令行的结果里能够看到从 Request[4] 到 Request[86] 都是在解析 moment.js附带的大量本地化文件。所以我们遇到的速度慢的问题事实上是由 moment引起的。
假设你想知道为什么 Webpack 会载入这么多的模块。能够參考这篇文章 Why Enormous Locales During Webpack MomentJS
我们再来看看 entry.js代码的第一行,标准的 CommonJS写法:
var moment = require('moment');
也就是说。请求的是 moment的源代码。实际上。通过 NPM 安装moment 的时候会同一时候安装 moment 的源代码和压缩后的代码,试验证明以下这种写法也是可行的:
var moment = require('moment/min/moment-with-locales.min.js');
仅仅只是这样改,可读性会有所下降,并且每个用到moment 的地方都得这么写。另外,假设相同的问题出如今第三方模块中,改动别人代码就不那么方便了。
以下来看看用 Webpack 怎么解决问题。
在 Webpack 中使用别名
别名(resolve.alias) 是 Webpack 的一个配置项,它的作用是把用户的一个请求重定向到还有一个路径,比如通过改动 webpack.config.js配置文件,添加:
resolve: {
alias: {
moment: "moment/min/moment-with-locales.min.js"
}
}
这样待打包的脚本中的 require('moment'); 事实上就等价于 require('moment/min/moment-with-locales.min.js'); 。通过别名的使用在本例中能够降低差点儿一半的时间。
Hash: cdea65709b783ee0741a
Version: webpack 1.10.0
Time: 320ms
Asset Size Chunks Chunk Names
bundle.js 148 kB 0 [emitted] main
[0] ./entry.js 125 bytes {0} [built]
factory:11ms building:9ms = 20ms
[1] ../~/moment/min/moment-with-locales.min.js 146 kB {0} [built] [1 warning]
[0] 20ms -> factory:8ms building:263ms = 291ms
[2] (webpack)/buildin/module.js 251 bytes {0} [built]
[0] 20ms -> [1] 271ms -> factory:3ms building:1ms = 295ms
WARNING in ../~/moment/min/moment-with-locales.min.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./locale in */webpack_performance/node_modules/moment/min
@ ../~/moment/min/moment-with-locales.min.js 1:2731-2753
在 Webpack中忽略对已知文件的解析
module.noParse 是 webpack 的还有一个非常实用的配置项,假设你 确定一个模块中没有其他新的依赖 就能够配置这项,webpack 将不再扫描这个文件里的依赖。
module: {
noParse: [/moment-with-locales/]
}
这样改动。再结合前面重命名的样例,更新后的流程是:
webpack检查到entry.js文件对moment的请求;- 请求被
alias重定向,转而请求moment/min/moment-with-locales.min.js; noParse规则中的/moment-with-locales/一条生效,所以webpack就直接把依赖打包进了bundle.js。
Hash: 907880ed7638b4ed70b9
Version: webpack 1.10.0
Time: 76ms
Asset Size Chunks Chunk Names
bundle.js 147 kB 0 [emitted] main
[0] ./entry.js 125 bytes {0} [built]
factory:13ms building:13ms = 26ms
[1] ../~/moment/min/moment-with-locales.min.js 146 kB {0} [built]
[0] 26ms -> factory:13ms building:5ms = 44ms
时间进一步被压缩,仅仅须要 76ms,比前一步还降低了 75%。
在 Webpack 中使用公用 CDN
Webpack 是如此的强大。用其打包的脚本能够执行在多种环境下。Web 环境仅仅是其默认的一种,也是最经常使用的一种。考虑到 Web 上有非常多的公用 CDN 服务。那么 怎么将 Webpack 和公用的 CDN 结合使用呢?方法是使用 externals声明一个外部依赖。
externals: {
moment: true
}
当然了 HTML 代码里须要加上一行
<script src="//apps.bdimg.com/libs/moment/2.8.3/moment-with-locales.min.js"></script>
这次打包。结果仅仅用了 49 ms。差点儿达到了极限。
总结
本文结合本地时钟的样例,展示了定位 Webpack 性能问题的步骤,以及所须要的两个參数 :--display-modules 和 --profile。然后,重点介绍了 resolve.alias 即利用别名做重定向的方法和场景。在此基础上,配合module.noParse 忽略某些模块的解析能够进一步加高速度。最后介绍了用 externals 定义外部依赖方法来使用公用 CDN。
关于
本文相关的源代码在: https://github.com/wyvernnot/webpack_performance/tree/master/moment-example;
本文系 utm_source=Common&utm_medium=Articles&utm_campaign=TechnicalArticles&from=matefiseco">OneAPM
OneAPM是中国基础软件领域的新兴领军企业,能帮助企业用户和开发人员轻松实现:缓慢的程序代码和SQL语句的实时抓取。想阅读很多其他技术文章。请訪问OneAPM官方技术博客。
Webpack 性能优化 (一)(使用别名做重定向)的更多相关文章
- webpack性能优化-实战
题外话:年初项目重构上线,项目技术栈使用vue+webpack,测试执行整个打包流程需要10分钟,同时又因涉及三个渠道,部署好环境就需半个小时,这严重延误了上线进度,因此提高webpack构建效率,成 ...
- webpack 性能优化 dll 分包
webpack 性能优化 dll 分包 html-webpack-externals-plugin DLLPlugin https://www.webpackjs.com/configuration/ ...
- webpack性能优化——DLL
Webpack性能优化的方式有很多种,本文之所以将 dll 单独讲解,是因为 dll 是一种最简单粗暴并且极其有效的优化方式. 在通常的打包过程中,你所引用的诸如:jquery.bootstrap.r ...
- webpack 性能优化小结
背景 如今前端工程化的概念早已经深入人心,选择一款合适的编译和资源管理工具已经成为了所有前端工程中的标配,而在诸多的构建工具中,webpack以其丰富的功能和灵活的配置而深受业内吹捧,逐步取代了gru ...
- Web前端性能优化,应该怎么做?
摘要:本文将分享一些前端性能优化的常用手段,包括减少请求次数.减小资源大小.各种缓存.预处理和长连接机制,以及代码方面的性能优化等方面. base64:尤其是在移动端,小图标可以base64(webp ...
- webpack性能优化
Webpack优化打包速度以及性能优化 1.跟上技术的迭代(Node.Npm.Yarn) 2.在尽可能少的模块上应用loader 3.Plugin尽可能精简并确保可靠 4.resolve参数合理配置 ...
- webpack 性能优化 -- 待续
文章 这篇文章挺不错的, 各方面优化都提到了, 有空研究下 文章 这个文章提出 , 增量打包用 webpack-watch 会让你打包速度飞快, react不参与打包, 不require, 而是放在 ...
- 浅谈webpack4.0 性能优化(转)
前言:在现实项目中,我们可能很少需要从头开始去配置一个webpack 项目,特别是webpack4.0发布以后,零配置启动一个项目成为一种标配.正因为零配置的webpack对项目本身提供的“打包”和“ ...
- H5教程:移动页面性能优化
随着移动互联网的发展,我们越发要关注移动页面的性能优化,今天跟大家谈谈这方面的事情. 首先,为什么要最移动页面进行优化? 纵观目前移动网络的现状,移动页面布局越来越复杂,效果越来越炫,直接导致了文件越 ...
随机推荐
- 图的最短路径-----------SPFA算法详解(TjuOj2831_Wormholes)
这次整理了一下SPFA算法,首先相比Dijkstra算法,SPFA可以处理带有负权变的图.(个人认为原因是SPFA在进行松弛操作时可以对某一条边重复进行松弛,如果存在负权边,在多次松弛某边时可以更新该 ...
- MD5小彩虹表
为方便日常查询,需要一个MD5小彩虹表,当然网上有比较多的这样的查询站点,但感觉最近使用起来十分不便. 因此,编写一个小程序,用来查询一些经常出现的MD5,也即弱口令MD5查询.采用python3编写 ...
- 爬虫笔记之自如房屋价格图片识别(价格字段css背景图片偏移显示)
一.前言 自如房屋详情页的价格字段用图片显示,特此破解一下以丰富一下爬虫笔记系列博文集. 二.分析 & 实现 先打开一个房屋详情页观察一下: 网页的源代码中没有直接显示价格字段,价格的显示是使 ...
- lrc歌词文件格式
一.lrc文件有什么作用 lrc文件就是一个文本文件,用来记录歌曲的歌词信息,使得播放歌曲时能够让歌词与声音同步显示,类似于电影字幕那种效果. 心情很丧时我们会听首歌陶冶一下情操,不知你是否注意过音乐 ...
- mysql修改时区
查看mysql当前时间 查看mysql时区设置 查看mysql数据库的时区 mysql修改时区的几种方法
- spring如何管理mybatis(二) ----- SqlSession的线程安全性
在之前的文章中我们了解到最终的数据库最终操作是走的代理类的方法: @Override public Object invoke(Object proxy, Method method, Object[ ...
- 转载 你不知道的super
http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...
- 非常有助于理解二极管PN结原理的资料
https://www.zhihu.com/question/60053574/answer/174137061 我理解的半导体 pn 结的原理,哪里错了? https://blog.csdn.net ...
- Dream_Spark版本定制第一课
从今天起,我们踏上了新的Spark学习旅途.我们的目标是要像Spark官方机构那样有能力去定制Spark. 一. 我们最开始将从Spark Streaming入手. 为何从Spark Streami ...
- spring-service.xml 模板
ssm模板 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:/ ...