百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

项目构建分析和 webpack 优化实践

cac55 2024-11-20 12:54 12 浏览 0 评论

项目构建分析和 webpack 优化实践

最近接手在做一个chrom浏览器插件的项目,开发过程中发现项目打包的时间很长,足足有30多秒,这是让人很难接受的,而且构建的显示了几条包体积过大的提示信息:

[image:073CB50B-06EB-4779-84FE-D11087B12BD7-47140-0000087E666F3C39/1967FDC4-F9FA-44F3-922E-5406A46415FB.png]

可以看到,打包后有三个包超过了建议的体积,是什么导致了打包时间长和包的体积过大呢?下面通过一些具体方法来分析原因和解决这个问题。

什么原因导致构建包变得这么大?

为了分析是什么导致构建包为什么会变得这么大,可以安装 webpack-bundle-analyzer 插件,通过它可以直观地查看构建包中所有项目的大小。

npm install —save-dev webpack-bundle-analyzer

对应的需要在webpack 中做如下配置:

webpack.config.js

const { BundleAnalyzerPlugin } = require(‘webpack-bundle-analyzer’)
plugins: [
 ...,
 new BundleAnalyzerPlugin({
 analyzerPort: 8081,
 }),
]

配置完成后再次运行构建 npm start,浏览器会自动打开 127.0.0.1:8001,在网页上可以看到每个依赖的详细信息。从图中可以找出影响体积的罪魁祸首有:

  • jquery
  • Moment
  • xlsx
  • mammoth
  • html2canvas
  • dexie

那么这些体积庞大的依赖库都需要打到项目的运行包里面吗?当然不是的。那我们逐步来优化这些依赖。

减少 moment 大小

moment 在包中占用了 545k 的体积,查看分析图可以看到,库文件中主要是各种用于支持语言版本的的locale文件,但是项目中并不需要这部分功能,因此这部分数据是应该优化的。

[image:88A706F4-B93A-4E35-B0F1-1B01CA3F9E9B-47140-000008AD50A28B13/Screen Shot 2019-08-05 at 11.13.07 AM.png]

查看项目中引入moment 的方式

import moment form ‘moment’;

这样会将整个 moment 包都导入到文件中,为了避免导入不必要的文件,可以这么写:

import moment from ‘moment/src/moment’

但是这么写会有个问题,如果项目中有新成员加入,极大的可能他不会这样写,而是像原来一样导入了整个 moment 包,因此为了避免这样的问题,可以考虑在 webpack 中创建一个别名,这样每次导入 moment 的时候就默认只导入文件夹下面的 moment.js 文件了,如下:

Alias: {
 moment: 'moment/src/moment',
}

好了,重新启动服务进行打包,报错提示无法找到 ./locale,

[image:BBCBFA75-E5E1-4110-A22B-8D98C3D110BD-47140-00000DA8C3052930/Screen Shot 2019-08-05 at 1.31.58 PM.png]

查看 moment 的官方 issue 发现这是一个存在已久的问题:moment.js 总是会加载 locales,还假定 locales 存在。你不能让 moment 只加载日期操作函数。

[image:795841EB-7214-4530-B2F1-7804B23DE6C7-47934-0000ADDDAF534A3D/Screen Shot 2019-08-14 at 2.24.15 PM.png]

官方提供的解决方案是把 package.json 中的 Moment 的版本改成 2.18.1,不过在 Stack Overflow 上找到了另一种解决方案,就是直接忽略这个报错:

[image:39119BD5-E067-47F0-B6FD-5760F4417818-47934-0000AE002AE61EFB/69AE8969-0014-40E4-AA34-955676B4D3AD.png]

  • IgnorePlugin
  • 这是webpack内置插件
  • 这个插件的作用是:忽略第三方包指定目录,让这些指定目录不要被打包进去

尝试一下:

plugins:[
 new Webpack.IgnorePlugin(/\.\/locale/,/moment/),
 //moment这个库中,如果引用了./locale/目录的内容,就忽略掉,不会打包进去
]

按照上面的方法,减小了moment的打包体积,同时也避免了报错,但是如果项目中需要用到语言包该怎么办呢?很简单,手动引入一下就可以了:

import moment from 'moment'
//设置语言
//手动引入所需要的语言包
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
let r = moment().endOf('day').fromNow();
console.log(r);

Ok,这么一来能够显示中文,又把不必要的语言包都忽略打包了,重新构建一下,看一下体积有没有变化:

[image:B998DDA8-62AD-4FD1-9953-A03BDE08310D-47140-00000DF75A4BFE04/4D8F9D51-4DAE-4274-A3B2-73A2B6D50448.png]

可以看到包已经缩减到了1.67M,打包时间缩短了29s(减少了4s),对应的观察网页上的显示结果,moment 包的大小也从 545k 变成了 155.32k,小了很多,不是吗?

[image:DE659EDD-8AE4-4DA8-932C-55D9ECE12866-47140-000008B0769A7E9C/Screen Shot 2019-08-05 at 11.21.55 AM.png]

使用 DllPlugin 加快打包速度

在用 Webpack 打包的时候,对于一些不经常更新的第三方库,比如 react,lodash,vue ,可以将这些库同项目代码分离开来,提前打包,从而每次只打包项目自身的代码,节省了打包时间。

如何使用 DllPlugin | webpack 中文网 呢?

首先在 webpack 文件夹下新建 webpack.dll.conf.js文件

配置如下:

const webpack = require('webpack')

const path = require('path')

module.exports = {

entry: {

// manifest 的前缀名,这里会在webpack 文件下生成一个dll.manifest.json 文件

dll: [

'react',

'react-dom',

'antd',

'classnames',

'jquery',

'xlsx',

'mammoth',

'html2canvas',

'dexie',

'cheerio', // 这些都是比较稳定,不常做修改的库文件

],

},

output: {

// 指定在 dist/static 下生成一个 dll.min.js 文件

path: path.join(__dirname, '../dist/static/'),

filename: '[name].min.js',

library: '[name]',

},

plugins: [

new webpack.DllPlugin({

// 指定在当前文件夹下生成 manifest 文件

path: path.resolve(__dirname, './dll.manifest.json'),

name: '[name]',

context: __dirname,

}),

// 压缩,让包更小一点

new webpack.optimize.UglifyJsPlugin({ minimize: true }),

],

}

配置完成后对应的需要在 webpack.config.js 中做如下修改:

 const manifest = require('./dll.manifest.json')
 plugins: [
 new webpack.DllReferencePlugin({
 context: __dirname,
 manifest,
 })
 ]

然后在入口文件中引入 dll.min.js

<script src=“./dist/static/dll.min.js”></script>

对应的,为了方便启动,在 package.json 中添加快捷命令:

"scripts": {
 "dll": "webpack —config webpack/webpack.dll.js",
}

到这里,DllPlugin 的相关配置就完成了,打包的时候执行 npm run dll 会在webpack 目录下生成 dll.manifest.json 文件,在 dist/static 目录下会生成 dll.min.js 文件,在打包过程中, webpack 会将 webpack.dll.js 中配置包含的库做一个索引,并写在 manifest 文件中,而引用 dll 的代码在打包的时候,只要读取这个 manifest 获取对应的库就可以了。

最后执行 npm run build 测试打包速度:

[image:C682B1B1-1C7E-4DC4-B999-39B5758D0564-47934-0000B256C82EE788/boundle info after.png]

发现现在的打包时间不到19秒,相比于原来的33s减少了将近一半,对应两个比较大的包体积也各自减少了2/3 还多。所以使用了 DllPlugin 之后,对项目的打包效率的提升还是很明显的。

[image:D11BD337-2369-4498-8D11-E12D087CE884-47934-0000B28971579A82/summary after.png]

总结

项目最开始开始构建,打包后需要将近 4M 的空间,通过手动修改 moment 库的引入方式和引入 webpack 的 DllPlugin 进行优化,打包后最终体积减少到了 1.2M,压缩了一半多,对应打包时间也缩短了将近一半,所以通过 webpack 进行打包优化还是很有效果的。这给我的启发式,在实际开发和打包上线过程中,需要细致地评估项目的构建体积和打包时间,通过 webpack-bundle-analyzer 可以直观的观察构建包的构成和体积分布,并且根据分析的结果有针对性地进行优化,以此来精简项目体积,提升应用效率。当然,打包优化的方式不仅限于此,还可以通过 HappyPack 利用 Node 的多线程充分使用电脑多核来提升构建速度(但是实际效果不一定会变快),此外,还可以使用 webpack 的 externals 不打包某些文件,而在其他地方通过 cdn 引入,利用缓存下载 cnd 文件达到减少打包时间的目的,有兴趣可以在项目中尝试,相信你会有很多收获。

相关推荐

无力吐槽的自动续费(你被自动续费困扰过吗?)

今天因为工作需要,需要在百度文库上下载一篇文章。没办法,确实需要也有必要,只能老老实实的按要求买了个VIP。过去在百度文库上有过类似经历,当时为了写论文买了一个月的VIP,后面也没有太注意,直到第二个...

百度文库推出“文源计划”创作者可一键认领文档

11月7日,百度文库发布了旨在保护创作者权益的“文源计划”。所谓“文源计划”,即为每一篇文档找到源头,让创作者享受更多的权益。据百度文库总经理李小婉介绍,文源计划分为三部分,分别是版权认证、版权扶持和...

有开放大学学号的同学,百度文库高校版可以用了。

还在网上找百度文库的下载方式,只要从身边的朋友在读开放大学的,那他(她)的学号就可以登陆到国家开放大学图书馆,还使用百度文库高校版来下载。与百度文库稍有不同,但足够使用了。现转国图链接如下:htt...

搜索资源方法推荐(搜索资源的方法)

今天msgbox就要教大家如何又快又准的搜到各类资源,第一点,排除干扰百度搜索出来啊经常前排展示它的产品以及百度文库,如何去除呢?很简单,后面输入空格减号百度文库,比如你搜高等数学百度文库很多,只要后...

一行代码搞定百度文库VIP功能(2021百度文库vip账号密码共享)

百度文库作为大家常用查资料找文档的平台,大多数文档我们都可以直接在百度文库找到,然而百度文库也有让人头痛的时候。好不容易找到一篇合适的文档,当你准备复制的时候他却提示你需要开通VIP才能复制~~~下载...

百度文库文档批量上传工具用户说明书

百度文库文档批量上传工具用户说明书1、软件主要功能1、批量上传文档到百度文库,支持上传到收费、VIP专享、优享以及共享。2、支持自动分类和自动获取标签3、支持多用户切换,一个账户传满可以切换到...

百度文库现在都看不到文档是否上传成功,要凉了吗?

打开知识店铺,百度文库文档里显示都是下载这一按键,上传的文档也看不到是否成功?咋情况,要取消了吗?没通过审核的也不让你删除,是几个意思,想通吃吗?现在百度上传文档也很费劲,有时弄了半天的资料上传审核过...

微信推广引流108式:利用百度文库长期分享软文引流

百度文库相对于百度知道、百度百科来说,操作上没那么多条条框框,规则上也相对好把握些。做一条百度知道所花费的精力一般都会比做一条百度文库的要多些,老马个人操作下来觉得百度文库更好把握。但见仁见智吧,今天...

职场“避雷”指南 百度文库推出标准化劳动合同范本

轰轰烈烈的毕业季结束了,众多应届生在经过了“职场海选”后,已正式成为职场生力军的一员。这一阶段,除了熟悉业务,签订劳动合同、了解职场福利也迅速被提上日程。而随着国人法律意识的增强,百度文库内《劳动合同...

《百度文库》:素材精选宝库(百度文库官网首页)

《百度文库》:独特功能助力选择高质量素材在当今信息爆炸的时代,如何高效地获取并利用有价值的素材成为了许多人面临的挑战。而《百度文库》作为百度公司推出的一款在线文档分享平台,凭借其丰富的资源、强大的功能...

深度整合和开放AI能力 百度文库和网盘推出内容操作系统「沧舟OS」

【TechWeb】4月25日消息,Create2025百度AI开发者大会上,百度文库和百度网盘推出全球首个内容操作系统——沧舟OS。基于沧舟OS,百度文库APP全新上线「GenFlow超能搭子」...

女子发现大二作业被百度文库要求付费下载,律师:平台侵权,应赔偿

近日,28岁的黎女士在百度百科搜索家乡的小地名时,发现了自己在大二完成的课题作业。她继续搜索,发现多个平台收录了该文,比如豆丁网和文档之家等,有的还设置了付费或积分下载。2月15日,九派新闻记者以用户...

2016杀入百度文库的新捷径,只有少数人才知道的喔

百度的产品在SEO优化中的分量真不用多说,其实很多人都像我一样一直在找捷径。但是我经常发现很多人都是在用死方法。比如发贴吧发帖而不知道去申请一个吧主,知道自问自答而不知道去申请一个合作资格。口碑和贴吧...

百度文库付费文档搜索方法(百度文库付费文档搜索方法有哪些)

一直以来,百度文库中无论是个人中心还是个人主页,都没有像淘宝一样的店内搜索功能,连最近新开的知识店铺也没有设计店内搜索功能,这无论是对上传用户还是下载用户都不方便,上传用户想要搜索自己的文档无法办到...

供读者免费使用!泰达图书馆机构版百度文库新年上新啦

在泰达图书馆读者使用百度文库数字资源不需要VIP,免-费-用!惊不惊喜?快来了解一下吧……新年伊始,为满足区域企业、高校、科研院所以及居民群众在教学、科研及学习过程中,对各类文献资源的需求,泰达图书馆...

取消回复欢迎 发表评论: