写点什么

Webpack 优化技巧,构建效率提升 50%

2019 年 8 月 02 日

Webpack优化技巧,构建效率提升50%

在本文中,谷歌开发者专家 Jennifer Bland 介绍了如何应用 Webpack 减少 Vue.js 包大小的技巧,希望能给大家带来一些启发。


我在史丹利百德公司(Stanley Black&Decker,主营工业工具及安全方案)的工业 4.0 团队任职。我们的团队最近为史丹利公司分布在全球的制造工厂开发了一款相当于 App Store 的产品。我们的工厂可以访问这个软件商城并根据他们在各地生产的产品需求选择所需的应用程序。这个过程会创建一个自定义的构建,将他们选择的这些应用程序打包在一起供厂方使用。由于打包的应用程序太多了,我们生产环境上的版本 Vue 构建触发了很多体积超限警告。


我们构建的初始大小

我们处理一个构建时收到了以下两条错误消息:



Vue 建议包大小不超过 244 KiB。我们一共有 14 项 assets 的大小超限了。此外还有四个入口点的大小也超过了建议值。以下是我将构建的大小减半的具体方法。


是什么让构建包变得这么大?

首先我需要了解构建包为什么会变得这么大。为此我安装了 webpack-bundle-analyzer。它能提供包中所有项目大小的可视指南。


npm install --save-dev webpack-bundle-analyzer
复制代码


接下来我对 webpack 做了些配置,然后就能在 vue.config.js 文件中使用它了。我的 vue.config.js 文件现在是这个样子:


const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {configureWebpack: {plugins: [new BundleAnalyzerPlugin()]}};
复制代码


插件装好后我再次运行构建,可以看到构建包的大小是 2.48MB。从图中可以找出影响体积的罪魁祸首有:


  • vue-echarts

  • vuetify

  • moment

  • lodash



减少 Lodash 的大小

Lodash 占用了 70.74KB 的空间。我们框架中的所有应用只有两处用到了 Lodash,才两个方法就占这么多空间不太划算。



我们加载的还不止是 lodash,而且还加载了 vue-lodash。所以第一步就是从 package.json 中删除 vue-lodash,本来就用不着它。


下一步是只从 lodash 中导入我们需要的两个项目,不再加载整个库。我们使用的是 cloneDeep 和 sortBy。我换掉了之前会导入整个 lodash 库的调用:


import _ from 'lodash';
复制代码


新的调用应该只导入我们需要的两个项目。为此我把导入目标从 lodash 改成了 lodash/core:


import { cloneDeep, sortBy } from 'lodash/core';
复制代码


改动完成后,构建包大小从 2.48MB 减少到了 2.42MB。下图显示了构建的当前大小。



在这里,我们可以看到构建包中 lodash 的部分有多大。



减少 moment.js 的大小

Moment.js 在我们的包中占用了 234.36KB 的空间。查看分析视图可知,这部分数据中绝大部分是国际化语言环境,用来支持一大堆语言版本。我们根本不会使用 moment.js 的这部分功能,所以它就算是包里的无用数据了。


还好我们可以直接删除它。原来的调用会导入所有 moment.js 内容:


import moment form 'moment';
复制代码


我们可以改成只导入日期操作代码,如下所示:


import moment from 'moment/src/moment'
复制代码


做这种替换可能会出现一个问题,至少在我们的代码库中遇到了这个问题。有 18 处代码会导入 moment.js,我本可以在代码中执行全局搜索和替换的。但是如果我们向框架添加一个新的应用程序,开发人员很可能会使用默认调用来导入 moment.js,那样的话我们又会导入所有国际化语言环境了。


所以妥协方案是在 webpack 中创建一个快捷方式别名。该快捷方式将用’moment/src/moment’替换所有导入’moment’的调用。我们可以使用 resolve 在我们的 vue.config.js 文件中添加该别名并进行设置。我的 vue.config.js 文件现在变成这样。



现在运行我们的构建,可以看到包大小已经缩减到 2.22MB。



观察视图中的 moment.js,可以看到国际化区域设置完全没有加载。



删除 moment.js 中的语言环境后,每当我启动服务器运行我的代码时都会发生错误,说它无法找到./locale。经过一些研究我发现这是 moment.js 的一个存在多年的已知问题:moment.js 总是会加载 locales,还假定 locales 存在。你不能让 moment 只加载日期操作函数。


为了解决这个问题,我使用内置的 webpack IgnorePlugin 忽略了这个消息。下面是我添加到 vue.config.js 文件中的插件代码:


new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
复制代码


减少 Vuetify.js 的大小

下一个目标是 Vuetify.js。Vuetify 占用 500.78KB 空间。一个产品就占这么多空间实在不是个小数字。



Vuetify 提供了一种他们称之为“点菜”的功能,允许你仅导入你要使用的 Vuetify 组件,从而减小 Vuetify 的体积。这里的挑战在于我们有如此多的应用程序,找出来哪些组件是完全不会被用到的也不是容易的事情。


在当前版本的 Vuetify(当我写这篇文章的时候版本为 1.56)中,他们提供了一个名为 vuetify-loader 的产品。它将遍历你的代码并找出你正在使用的所有组件,然后只将这些组件导入你的构建包。注意:vuetify v2 将内置此功能。在 v2 版本发布之前,你必须使用 vuetify-loader 来按需导入组件。Vuetify 文档提到,我们要获得所有所需的样式就要在 stylus 中导入它们。


这时我发现我们还在用旧版 vuetify.js。所以我决定先把 vuetify 升级到最新版本。我还同时安装了样式和 vuetify-loader:


npm install vuetify vuetify-loader stylus stylus-loader style-loader css-loader --save
复制代码


我用来导入 Vuetify 的插件代码有一些自定义主题,可以使用我们公司的调色板。以下是我目前使用的 Vuetify 插件:



我需要将“从 Vuetify 导入”更改为“从 vuetify/lib 导入”。我还会导入 stylus 以获得所有样式。然后插件代码会变成:



最后一步是告诉 webpack 使用 vuetify-loader 插件,让它只导入我们需要的组件。我得把插件添加到插件数组里。现在 vue.config.js 文件变成这样:



之后运行构建,包大小减少为 2MB。



减少 vue-echarts 的大小

Vue-echarts 不是我包中最大的项目。Vue-echarts 运行在 echarts 之上。和 Vuetify 一样,我用的这两种产品都还是旧版本。运行下面的命令将它们升级到最新版本:


npm install echarts vue-echarts --save
复制代码


我对 vue-echarts 的 GitHub repo 做了一些研究,查看了所有已解决的问题,发现最新版本的 vue-echarts 允许你通过更改导入的内容来加载较小的包。以前我使用下面的命令导入它:


import ECharts from 'vue-echarts';
复制代码


现在我改成了这样:


import ECharts from 'vue-echarts/components/ECharts.vue';
复制代码


然后运行构建,应用包大小降至 1.28MB。



结论

我的目标是精简生产环境上的应用包体积。一开始构建包需要 2.48MB 空间。通过一系列改动优化,构建包大小最后减少到了 1.28MB,几乎压缩了一半。


如果你要创建生产环境上的 Vue 应用程序,则应该花些时间来评估构建的体积。使用 webpack-bundle-analyzer 来确定哪些项目占用的空间最多,然后采取必要步骤来减少这些项目的大小。我通过这种方式精简了包中的四个项目。


希望你能够按照这些步骤减少构建的空间占用。非常感谢你的阅读。


英文原文:https://www.jenniferbland.com/how-to-reduce-your-vue-js-bundle-size-with-webpack/


2019 年 8 月 02 日 18:312911

评论

发布
暂无评论
发现更多内容

公安大数据分析系统开发,情报研判系统搭建

t13823115967

智慧公安

架构师训练营 12 周笔记

郎哲158

Learun FrameWork,.Net Core3.1工作流引擎平台

力软.net/java开发平台

.net core 工作流引擎

有道逻辑英语-时态新发现笔记

Leo

学习 前端进阶训练营 笔记 时态

深入浅出理解视频编解码技术

拍乐云Pano

音视频 RTC 拍乐云 视频编解码 视频算法

智慧公安大数据分析研判系统开发,合成作战平台建设

WX13823153201

三金本体挖矿模式系统开发丨三金本体平台源码设计

系统开发咨询1357O98O718

三金本体挖矿模式源码

TRONex波场智能合约系统开发详解丨TRONex波场链系统开发(源码)

系统开发咨询1357O98O718

系统开发 TRONex波场智能合约 APP开发

年终盘点 | 七年零故障支撑双11的消息中间件 RocketMQ,怎么做到的?

阿里巴巴中间件

消息中间件 双十一

COMP矿池矿机系统开发案例分析

系统开发咨询1357O98O718

COMP矿池矿机系统开发介绍

ETH场外交易系统开发流程丨ETH场外交易开发源码案例

系统开发咨询1357O98O718

ETH场外交易系统开发

使用Angular8和百度地图api开发《旅游清单》

徐小夕

Java angular.js 前端 angular

vivo 全球商城:从 0 到 1 代销业务的融合之路

vivo互联网技术

架构 分布式 商城项目 商城

第12周总结

饭桶

第12周作业

饭桶

智天下APP系统开发|智天下软件开发

开發I852946OIIO

系统开发

OKO疯矿链系统开发案例(源码)

系统开发咨询1357O98O718

OKO疯矿链系统开发

5分钟完成业务实时监控系统搭建,是一种什么样的体验?

阿里巴巴中间件

体验 监控

产品推荐 | 还在自研?快来解锁拍乐云互动白板

拍乐云Pano

音视频 在线教育 RTC 互动白板

喜讯 | 拍乐云荣登2020「年度最具投资价值创新企业TOP20」榜单

拍乐云Pano

音视频 实时音视频 音视频算法 拍乐云

Java并发编程:多线程并发内存模型

码农架构

Java并发

区块链钱包系统开发方案丨多币种钱包系统开发详情

系统开发咨询1357O98O718

区块链钱包开发

Forsage系统开发(模式分析)

系统开发咨询1357O98O718

Forsage系统开发案例介绍

如何降低微服务测试成本?我的经验之谈

阿里巴巴中间件

投行工作的本质 | 读《投行职业进阶指南:从新手到合伙人》

邓瑞恒Ryan

读书笔记 投资 金融 投行 职业第二曲线

架构师训练营 12 周作业

郎哲158

LeetCode题解:433. 最小基因变化,BFS,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

BMEX交易所系统软件开发|BMEX交易所APP开发

开發I852946OIIO

系统开发

构建一张音视频全球大网究竟需要多少个节点?Pano Backbone技术探秘

拍乐云Pano

音视频 RTC 实时音视频 音视频算法 拍乐云

看到Mybatis源码就感到烦躁,怎么办?

田维常

mybatis

《微信小程序开发入门与实践》.pdf

田维常

演讲经验交流会|ArchSummit 上海站

演讲经验交流会|ArchSummit 上海站

Webpack优化技巧,构建效率提升50%-InfoQ