微信小程序手刺制造_webpack学习教程之前端性能优化总结

  • 栏目:公司新闻 时间:2021-01-11 11:25 分享新闻到:
<返回列表

webpack学习教程之前端性能优化总结       webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。这篇文章主要给大家总结介绍了关于webpack学习教程之前端性能优化的相关资料,需要的朋友可以参考下。

曾几何时,我们是如上图的方式引入JS资源的,相信现在很少遇见了。近年来Web前端开发领域朝着规范开发的方向演进。体现在以下两点:

1、MVC研发构架。多多益处(逻辑清晰,程序注重数据与表现分离,可读性强,利于规避和排查问题...)

2、构建工具层出不穷。多多益处(提升团队协作,以及工程运维,避免人工处理琐碎而重复的工作)

模块化开发 将前端性能优化理论落地,代码压缩,合并,缓存控制,提取公共代码等 其他的还包括比如你可以用ES 6 或CoffeeScript写源码,然后构建出浏览器支持的ES5

所以,前端这么好玩,如果还有项目没有前后端分离的话,真的是守旧过头了。

主流构建工具

市面上有许多构建工具,包括Grunt、Gulp、browserify等,这些和WebPack都是打包工具。但WebPack同时也具备以下特点:

相比Grunt,WebPack除了具备丰富的插件外,同时带有一套加载(Loader)系统。使它支持多种规范的加载方式,包括ES6、CommonJS、AMD等方式,这是Grunt、Gulp所不具备的。

从代码混淆的角度来看,WebPack更加的极致

代码分片为处理单元(而不是文件),使得文件的分片更为灵活。

P.S.此处只做简单的比较,不论孰优孰劣。其实工具都能满足需求,关键是看怎么用,工具的使用背后是对前端性能优化的理解程度。

引言

最近在用webpack优化首屏加载性能,通过几种插件之后我们上线前后的速度快了一倍,在此就简单的分享下吧,先上个优化前后首屏渲染的对比图。

可以看到总下载时间从3800ms缩短到1600ms。

我们在用webpack时一般都会选择多入口文件吧,为的就是将自己的源码跟第三方库代码分离。这是之前的代码,

entry: {
 entry: './src/main.js',
 vendor: ['vue', 'vue-router', 'vuex', 'element-ui','echarts']
output: {
 path: config.build.assetsRoot,
 filename: utils.assetsPath('js/[name].[chunkhash].js'),
 chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
}

echarts非常大,所以打包时的vendor.js大概为1.2MB(经过gzip压缩之后),而且首页没有用到echarts,所以我之后使用了externals将第三方库以cdn的方式去引入,下面是优化过的代码

entry: {
 entry: './src/main.js',
 vendor: ['vue', 'vue-router', 'vuex', 'element-ui']
 // 这里的output为base中的output,不是生产的output
 output: {
 path: config.build.assetsRoot,
 filename: '[name].js',
 libraryTarget: "umd",
 publicPath: process.env.NODE_ENV === 'production' 
 config.build.assetsPublicPath : config.dev.assetsPublicPath
 externals: {
 echarts: 'echarts',
 _: 'lodash'
 },

这就是优化前后的对比。

然后我们要到html中以script标签的形式去引externals中的cdn。之后就可以在相应的文件中import了,他的好处是不管你在多少vue文件中引用多少次,他都不会打包到所有的trunk(这里的trunk'指的是按需加载,一会详细说明)中,这是用webpack-bundle-analyzer插件展示的效果。

var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
new BundleAnalyzerPlugin({
 // 可以是`server`,`static`或`disabled`。
 // 在`server`模式下,分析器将启动HTTP服务器来显示软件包报告。
 // 在“静态”模式下,会生成带有报告的单个HTML文件。
 // 在`disabled`模式下,你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats JSON文件。
 analyzerMode: 'server',
 // 将在“服务器”模式下使用的主机启动HTTP服务器。
 analyzerHost: '127.0.0.1',
 // 将在“服务器”模式下使用的端口启动HTTP服务器。
 analyzerPort: 8888, 
 // 路径捆绑,将在`static`模式下生成的报告文件。
 // 相对于捆绑输出目录。
 ',
 // 模块大小默认显示在报告中。
 // 应该是`stat`,`parsed`或者`gzip`中的一个。
 // 有关更多信息,请参见“定义”一节。
 defaultSizes: 'parsed',
 // 在默认浏览器中自动打开报告
 openAnalyzer: true,
 // 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成
 generateStatsFile: false, 
 // 如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。
 // 相对于捆绑输出目录。
 statsFilename: 'stats.json',
 // stats.toJson()方法的选项。
 // 例如,您可以使用`source:false`选项排除统计文件中模块的来源。
 // 在这里查看更多选项:htt凡科抠图: ///webpack/webpack/blob/webpack-1/lib/Stats.js#L21
 statsOptions: null,
 logLevel: 'info' //日志级别。可以是'信息','警告','错误'或'沉默'。
 })

我们会看到,没用externals和用了externals后所有的js中都不会出现类似echarts和lodash的库出现(就算你import一万次他都不会打包一次,厉害吧~~)。

对于externals再说两点——

1.externals中的key是import中使用的

import lodash from "_";
import echarts from "echarts";

2.externals中的value是window下调用的

然后我们再来聊聊为什么output使用trunkhash不用trunk,这是为了持久化缓存。简单说下两者的区别——

trunk:每次build之后的版本,就是说所有的build之后的文件hash值一致,比如我只改了一个文件,最后所有的文件hash都会变,这样所有的文件都不会走cache,这样缓存就失去了意义。

trunkhash:根据每个文件生成不同的hash值,当文件变化时hash会改变且只会改变相应的文件

然后我们肯定是要用到CommonsChunkPlugin,这个插件是用来抽取公共代码的,monschunkPlugin,但这从某方面来说并没有实现真正意义上的持久化缓存,这个一会我会通过webpack打包原理来详细解释其中的原因。。。。。。

new webpack.optimize.CommonsChunkPlugin({
 names: ['vendor','manifest']
})

在没用这个插件之前,我们的main.js和vendor.js会是这样子。。。

大家会看到我们这两个文件会有公共的部分,比如vue和element-ui,所以我们要抽取公共代码到vendor中,所以我们可以先这样配置

new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
}),

但这样的话虽然可以提取公共代码,但我们会把runtime(webpack运行时的代码,一会在打包原理中会再次提到)也放到vendor中,这里面会维护一个trunk的文件列表,类似于这样,就是说我们改任意的代码,这个table里面的hash会变,所以vendor的hash也会变

,所以这没有实现真正的持久化缓存。这个hash table是按需缓存的打包出来的trunk包,一般都是通过require.ensure(就是vue-router中配置的page对应页面,按需加载)

所以我们就把name改为names,就是上面那个配置。因为使用这个插件,我们会把公共代码抽到第一个name中,把runtime放到最后一个name中,也就是我们所谓的“manifest”文件。

并且这个文件会比较小,通常都是2kb左右,所以build后会生成一个script标签,但这样的话就多了一个http请求,所以我们可以用另外一个插件(InlineManifestWebpackPlugin)将manifest.js内联进去。就会长这样子

再回到我们的CommonsChunkPlugin,现在我们随便改任何已存在的文件,vendor.js的hash都不会变,是的,貌似这就实现了持久化缓存。但是当我们新增一个模块,并且在入口文件中import一下,我们的vendor就会跟main一起变。很奇怪对吧,我们明明已经做了自己的源码跟第三方库分离,为什么vendor还会变(到现在应该没有任何一篇博客对此进行详细的说明)。下面我就详细的给大家解释下我的看法,如果大家发现有不对的地方还请指正。

再解释为什么之前,我们先简单了解下webpack的打包规则。

webpack一个entry对应一个bundle,这个bundle包括入口文件和其依赖的模块。其他按需加载的则打包成其他的bundle。还有一个比较重要的文件时manifest,它是最先加载的,负责打包其他的bundle并按需加载和执行。

manifest是一个自执行函数,熟悉angular的同学看第一行应该很了解,因为anguar1.3版本的源码中启动就是angular.bootstrap,对,这里也是一样。里面的modules变量就是对应模块函数,它是webpack处理的基本单位,就是说对应打包前的一个文件

这是js源文件,

这是打包后的文件,

所有的模块函数索引都是连续的(每个js文件生成一个trunkid!!!!!),像这种 /* 4 */ 对应的就是js文件,他通过打包就变成了一个个trunkid,仔细看会看到咱们打包前js文件里的export和require依赖都会统一转换成webpack模块。咱们说的webpackJsonp就是除manifest之外打包其他的文件的函数体。

简单说下main吧,这个图的trunkid是连续的,为了在一张图上显示,我截掉了trunk3-7.

这里面一共有三个参数,第一个是我当前文件的trunkid,它是唯一标识符,就是指main的trunkid,第二个就是打包的所有文件的模块函数,第三个是我要立即执行的trunkid模块函数。

ok,介绍这些就足够了。

所以当我们新加一个js并引入到main入口时,webpack再次打包,我的main文件会多一个模块函数,刚刚说过trunkid是依次递增的而且不会重复。所以对应的vendor的id会+1,就是这么细微的变化导致hash变了。

大家仔细看,这两个vendor都是10272行,唯一的不同就是我要自执行这个vendor库,这里我引用的jquery,所以这个文件只有jquery,自执行肯定要有模块函数,trunkid+1,所以hash会变。我们再好好回忆一下,其实这也说明了这个插件的意义,我就是要抽出公共的库,OK,这个插件做到了,但是因为webpack打包机制,不同文件生成不同turnkid,所以这是美中不足的一点。再回想一下,我们一般是不会随便修改main.js的,所以从另一角度上来说这就是实现了持久化缓存。但我如果就是想保持vendor的hash不变要怎么办呢?

这段代码就可以实现,没错,如果你对vue-cli了如指掌,这就是vue-cli的官方demo,至于为什么可以,这个我后续会跟大家解释(实在是写不动了。。。)。

最后再给大家介绍一个超级好用的东西,就是cdn。我们现在的需求是想让图片走cdn,让js走线上路径,但官方的解释是通过修改config文件做cdn变化,这样做的话我的所有输出都会走cdn,那所有的ajax请求就跨域了呀。

一开始我的解决方案是,在源文件中挨个替换,这样会比较慢,更重要的是,cdn图片也是有hash值的,当我以后替换图片时,还得重新改相应的hash。有什么方法能让他自动去获取hash呢。

没错,我们需要在url-loader中单独配置cdn,做到js访问线上路径,静态资源使用cdn,两者互不影响。

简单提醒一下,url-loader不能检测到js中的background,所以我们凡是在js中引用的地址,必须在外面先import这张图片,url-loader才会解析并打包。

今天就先到这里吧,改天继续。。。。。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对凡科的支持。


分享新闻到:

更多阅读

微信小程序手刺制造_webpack学习教程之前

公司新闻 2021-01-11
webpack学习培训实例教程以前端特性提升小结 webpack是最近最红的一款控制模块载入器兼装...
查看全文

广州凡科互联网科技股份有限公司招聘电

公司新闻 2021-01-11
招聘人数:25职位信息岗位职责:1、负责微信小程序商城相关产品的上下架;2、负责微信小程...
查看全文

广州凡科互联网科技股份有限公司招聘京

公司新闻 2021-01-11
招聘人数:24职位信息岗位职责:1、负责挑选相关产品;2、负责产品的上架和数据跟踪;3、负...
查看全文
返回全部新闻


区域站点: 南丰县网页开发   南宫市网页ui   囊谦县网页设计与制作   南和县学生个人网页优秀模板   南华县网页开发   南江县网页ui   南京市网页设计与制作   南靖县学生个人网页优秀模板   南康市网页开发   南乐县网页ui   南陵县网页设计与制作   南宁市学生个人网页优秀模板   南平市网页开发   南皮县网页ui   南市区网页设计与制作   南通市学生个人网页优秀模板   南投县网页开发   南雄市网页ui   南溪县网页设计与制作   南阳市学生个人网页优秀模板   南漳县网页开发   南召县网页ui   南郑县网页设计与制作   那坡县学生个人网页优秀模板   那曲县网页开发   纳雍县网页ui   讷河市网页设计与制作   内黄县学生个人网页优秀模板   内江市网页开发   内丘县网页ui   内乡县网页设计与制作   嫩江市学生个人网页优秀模板   聂荣县网页开发   尼玛县网页ui   尼木县网页设计与制作   宁安市学生个人网页优秀模板   宁波市网页开发   宁城县网页ui   宁德市网页设计与制作   宁都县学生个人网页优秀模板   宁国市网页开发   宁海县网页ui   宁化县网页设计与制作   宁晋县学生个人网页优秀模板   宁陵县网页开发   宁明县网页ui   宁南县网页设计与制作   宁强县学生个人网页优秀模板   宁陕县网页开发   宁武县网页ui   宁乡市网页设计与制作   宁阳县学生个人网页优秀模板   宁远县网页开发   农安县网页ui   磐安县网页设计与制作   盘锦市学生个人网页优秀模板   盘山县网页开发   磐石市网页ui   盘州市网页设计与制作   蓬安县学生个人网页优秀模板   澎湖县网页开发   蓬莱市网页ui   彭山县网页设计与制作   蓬溪县学生个人网页优秀模板   彭阳县网页开发   彭泽县网页ui   彭州市网页设计与制作   偏关县学生个人网页优秀模板   平安县网页开发   平昌县网页ui   平定县网页设计与制作   屏东县学生个人网页优秀模板   平度市网页开发   平果县网页ui   平和县网页设计与制作   平湖市学生个人网页优秀模板   平江县网页开发   平乐县网页ui   平凉市网页设计与制作   平利县学生个人网页优秀模板   平罗县网页开发   平陆县网页ui   屏南县网页设计与制作   平泉市学生个人网页优秀模板   屏山县网页开发   平顺县网页ui   平塘县网页设计与制作   平潭县学生个人网页优秀模板   平武县网页开发   萍乡市网页ui   平乡县网页设计与制作   平阳县学生个人网页优秀模板   平遥县网页开发   平阴县网页ui   平邑县网页设计与制作   平远县学生个人网页优秀模板   平舆县网页开发   皮山县网页ui   普安县网页设计与制作   浦北县学生个人网页优秀模板   浦城县网页开发   普洱市网页ui   普格县网页设计与制作   浦江县学生个人网页优秀模板   普兰县网页开发   普宁市网页ui   莆田市网页设计与制作   迁安市学生个人网页优秀模板   乾安县网页开发   潜江市网页ui   潜山市网页设计与制作  

友情链接: 永久免费手机建站 网页建站 网站建设制作 手机网站建设 手机版

Copyright © 2002-2020 网页设计与制作_学生个人网页优秀模板_网页开发_网页ui_网页设计大作业 版权所有 (网站地图) 备案号:粤ICP备10235580号