一次webpack小规模优化经历
这标题一点营销号味道都没有,怎么会有人看啊!(笑)
没人看也无所谓的文章背景:
八月份入职了新公司,是个好几年的老项目了,公司产品是存在很久了,但我接触到的代码版本保守估计应该是有个三年到四年这样的历史,所以期间应该是换工具重构了一遍。公司最开始没前端,然后不知道哪位大哥建项目的时候选择建成多页面应用,分功能模块打包,后来被招我进来的大哥(也是前端的负责人)改成了单页面应用,但因为改造不完整,导致留下了些后遗症,表面上主要体现在热重载速度极慢,以及打包体积巨大、编译耗时长,jenkins完整推一次包要差不多半小时;在这种优化已经成为刚需的前提下,虽然组里有三四个前端同事,但他们好像都没想过去搞这种事情,在我加入后不久,前端的负责人就离职了...没有形式上的领导,更不会有人想着去做这种耗时不确定的还不一定会有效果的事情。公司对新人的期待并没有那么迫切,所以前期基本上除了日常安排的功能开发之外基本上是放养状态,进公司一个月后,按惯例经理跟前端负责人(彼时前端大哥还没离职)要找新人做个谈话,了解一些融入状态以及这段时间内的工作内容,我就提到了公司项目目前的这些硬伤和优化的想法,在得到授意之后,日常开发之余,就进行优化工作。
基本配置(优化前): 前端框架vue2.5.x+element-ui,构建工具webpack1.x+gulp, express+中间件实现der-server
正文:
前面说了那么多无关紧要的,可没打算跑题,本文意为抛砖引玉,从个人的实践触发,通过具体的一些优化操作,总结一下优化思路,期待能与各位同道交流学习。
那么我们现在开始。
既然已经存在问题,而需求则是提高开发体验、减小打包体积与编译耗时,那么在这个前提下,个人认为做优化的第一步,是分析问题,大体上来说,评估一个前端包质量的多种维度中,打包速度跟包体积这些指标是比较直观的,所以接下来我打算介绍两个插件speed-measure-webpack-plugin与webpack-bundle-analyzer,量化分析打包耗时和前端包体积,用来帮助我们找到优化的正确方向。
那么我先拿入职时候接手的项目代码开始做可视化的分析。
(多图警告)
首先我们在管理生产模式的配置文件webpck.prod.conf的代码中添加这两个插件:

然后跑一遍打包命令,项目打包后,资源的视图关系是这样类似echarts的treemap的结构:

而负责速度分析的插件speed-measure-webpack-plugin也在控制台输出了他的统计情况:

dist目录50M,耗时约270s,前端页面其实不是特别多,所以这个成绩可以说惨不忍睹,那么接下来我们单纯从视图上来分析,看看能不能找出一些异常。
webpack-bundle-analyzer的分析结果有三个维度,stat\parsed\Gzipped;
对于这三个维度,官方的解释为
stat
This is the "input" size of your files, before any transformations like minification.
It is called "stat size" because it's obtained from Webpack's stats object.
parsed
This is the "output" size of your files. If you're using a Webpack plugin such as Uglify, then this value will reflect the minified size of your code.
gzip
This is the size of running the parsed bundles/modules through gzip compression.
可以理解为分别对应着webpack从入口文件打包递归到的所有模块体积、解析与代码压缩优化后输出到dist目录的体积、开启Gzip之后的体积,后两个维度的值一般来说接近真实的前端包体积,但不会跟他们占用的硬盘空间完全一致,随优化手段不同也有所差异。
现在这个项目的stat状态下体积为: ……接近400M

同时,我们可以发现有多个bundle存在结构相似的情况,比如:

查询一个被多个文件引用的普通页面组件,能看到这个源文件被打包进多个bundle:

而之前的另一份截图也表示用于压缩css代码的extract-text-webpack-plugin与用于压缩js代码的UglifyJsPlugin,在打包过程中的大部分时间里保持着运作,总结以上几个现象,可以得出这么一个观点:有一部分公共模块,没有正确地被提取出来;
而在webpack4以下,官方提供的负责提取公共模块的插件为:webpack.optimize.CommonsChunkPlugin,而这是我当前的CommonsChunkPlugin配置:

第一个commons chunk的含义是从根目录下的node_modules目录去抽取所有被引用的js文件,这个chunk被命名为vendor,无引用次数限制;
第二个commons chunk的含义是从刚刚定义vendor的chunk中抽取公共模块,默认minChunk是2
这两个chunk都是针对node_modules的第三库进行公共模块抽取,而缺少了对项目自建公共模块的管理,因此我们尝试着添加一个新的commons chunk:
new webpack.optimize.CommonsChunkPlugin({
name: 'index',
async: true,
children: true,
}),
加上这段配置后,重新打包,这回看起来就比较正常了:

速度虽然还是比较慢,但相比之前,也不是那么难以接受:

到这里体积跟编译时间这两个痛点就算是解决了,我在做完这个版本的优化后,项目暴露出来比较明显的还有一些问题:
1.浏览器首屏加载速度一般,单个文件体积过大,常导致单个资源请求耗时较长
2.开发环境下项目启动/热重载还是很慢,我对中间件+本地起服务那一套不怎么熟,个人在短时间内没找到突破口
第一个问题关系到业务需求、以往业务代码写法还有webpack拆包,而由于以上的第二个问题,开发体验还是没有得到提升,单个文件改动触发的热重载耗时动辄十多秒,着实有些折磨,所以在完成第一个版本不久,我决定在这个基础之上升级构建工具,webpack1.x升级到4.x的过程中也遇到了很多坑,这些我打算整理一下再更新到下期的内容中。
关于可视化分析的工具,还有多种选择,比如:
webpack自己的可视化分析工具(线上):https://webpack.github.io/analyse/
仪表盘形式的webpack-dashboard: https://github.com/Exodia/webpack-dashboard
同样是仪表盘形式,但视觉效果更出色,下载量也在慢慢增长的:https://github.com/zouhir/jarvis
ok,我们有机会——当然有机会——所以我们下期内容再见——下周开始出差,希望目的地那边不会那么忙。
——“虽然我在经济舱”!
一次webpack小规模优化经历的更多相关文章
- 记一次真实的webpack优化经历
前言 公司目前现有的一款产品是使用vue v2.0框架实现的,配套的打包工具为webpack v3.0.整个项目大概有80多个vue文件,也算不上什么大型项目. 只不过每次头疼的就是打包所耗费的时间平 ...
- webpack性能优化——DLL
Webpack性能优化的方式有很多种,本文之所以将 dll 单独讲解,是因为 dll 是一种最简单粗暴并且极其有效的优化方式. 在通常的打包过程中,你所引用的诸如:jquery.bootstrap.r ...
- SQL 优化经历
一次非常有趣的 SQL 优化经历 阅读本文大概需要 6 分钟. 前言 在网上刷到一篇数据库优化的文章,自己也来研究一波. 场景 数据库版本:5.7.25 ,运行在虚拟机中. 课程表 #课程表 cr ...
- sql优化经历(转存+记录)
sql优化经历 补充:看到这么多朋友对sql优化感兴趣,我又重新补充了下文章的内容,将更多关于sql优化的知识分享出来, 喜欢这篇文章的朋友给个赞吧,哈哈,欢迎交流,共同进步. 2015-4-30补充 ...
- 一次mysql优化经历
某日运维突然说无线终端的频道页接口訪问量非常大,memcache缓存扛只是来.导致mysql并发查询量太大,导致server不停地宕机,仅仅能不停地重新启动机器.遗憾的是运维并没有告诉mysql查询量 ...
- Webpack 打包优化之速度篇
在前文 Webpack 打包优化之体积篇中,对如何减小 Webpack 打包体积,做了些探讨:当然,那些法子对于打包速度的提升,也是大有裨益.然而,打包速度之于开发体验和及时构建,相当重要:所以有必要 ...
- Webpack 打包优化之体积篇
谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...
- webpack 性能优化 dll 分包
webpack 性能优化 dll 分包 html-webpack-externals-plugin DLLPlugin https://www.webpackjs.com/configuration/ ...
- webpack打包优化点
目录 1. noParse 2. 包含和排除目录 3. IgnorePlugin 4. happypack 5. DllPlugin动态链接库 6. 热更新 7. 开发环境 tree-shaking ...
随机推荐
- day34 Pyhton 网络编程
一今日内容 # 函数 # 面向对象 # 进阶 # 网络编程 4 # 并发编程 6-7 # 概念 # 网络基础 # 局域网的概念 # 交换机和路由器的工作流程 # ip地址 # mac地址 # 子网掩码 ...
- go 继承
package main import "fmt" type Animal struct { Color string } // 继承动物结构体 type Dog struct { ...
- 详解GaussDB(DWS) explain分布式执行计划
摘要:本文主要介绍如何详细解读GaussDB(DWS)产生的分布式执行计划,从计划中发现性能调优点. 前言 执行计划(又称解释计划)是数据库执行SQL语句的具体步骤,例如通过索引还是全表扫描访问表中的 ...
- 正式班D14
2020.10.23星期五 正式班D14 9.5 文件处理三剑客(支持|) 9.5.1 sed流式编辑器 事先制定好编辑文件的指令,让sed自动完成对文件的整体编辑(同一时间内存中只有文件中一条) # ...
- 线程池FixedThreadPool
可重用线程池,只有核心线程,并发无阻塞, public class MainActivity extends AppCompatActivity { @Override protected void ...
- APP后台架构开发实践笔记
1 App后台入门 1.1 App后台的功能 (1)远程存储数据: (2)消息中转. 1.2 App后台架构 架构设计的流程 (1) 根据App的设计,梳理出App的业务流程: (2) 把每个业务流程 ...
- 如何安装一个高可用K3s集群?
作者介绍 Janakiram MSV是Janakiram & Associates的首席分析师,也是国际信息技术学院的兼职教师.他也是Google Qualified Developer.亚马 ...
- 联考day7 C. 树和森林 树形DP
题目描述 样例 样例输入 8 5 BBWWWBBW 1 2 2 3 4 5 6 7 7 8 样例输出 84 2 1 4 样例解释 分析 首先,我们要预处理出一个点到该联通块内所有点的距离之和 \(f\ ...
- Luogu P4643 阿狸和桃子的游戏
题解 传送门 既然题目要求的是差值 所以对于减数和被减数同时加上一个相同的数是毫无影响的 (详情参考人教版六年级上册数学教材) 所以不妨把边权分成两半 分别加给两个顶点 然后,直接每次选最大的点就好了 ...
- JVM详解(二)-- 第2章 类加载器子系统
一.JVM内存结构 1.1 内存结构---概略图 1.2 内存结构--详细图 二.类加载器子系统的作用 类加载器子系统负责从文件系统或网络中加载.Class文件,文件需要有特定的标识(cafe bab ...