手机版

webpack学习教程前端性能优化总结

时间:2021-09-02 来源:互联网 编辑:宝哥软件园 浏览:

很久以前,我们以上面显示的方式引入了JS资源,但是我相信我们现在很少遇到它们。近年来,Web前端开发领域向标准化发展演进。体现在以下两点:

1.MVC研发框架。好处很多(逻辑清晰,程序注重数据和性能的分离,可读性强,有利于避免和排除问题.)

2.建筑工具层出不穷。许多好处(改善团队合作、工程操作和维护,避免手工处理琐碎和重复的工作)

模块化开发将前端性能优化理论落地,包括代码压缩、合并、缓存控制、提取公共代码等。其他包括,例如,您可以用ES 6或CoffeeScript编写源代码,然后构建浏览器支持的ES5。所以前端这么好玩,如果还有其他没有前端分离的项目,真的太老套了。

主流建筑工具

市场上有很多构建工具,包括咕噜、大口、浏览器等。这些和WebPack都是打包工具。但是,网络包也有以下特点:

与Grunt相比,WebPack不仅插件丰富,而且有Loader系统。它可以支持多种标准的加载方式,包括ES6、CommonJS、AMD等等,而Grunt和glow都没有。

从代码混乱的角度来看,WebPack更加极端

代码分片是一个处理单元(不是文件),这使得文件分片更加灵活。

P.S .在这里只做一个简单的比较,不管是好是坏。其实工具是可以满足需求的,关键是如何使用,对前端性能优化的理解是工具使用的背后。

最近,我们正在用webpack优化第一个屏幕的加载性能。通过几个插件后,我们上线前后的速度都翻倍了。我们在这里简单分享一下。首先,我们来对比一下优化前后的第一次屏幕渲染。

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

我们在使用webpack时通常选择多入口文件,以便将我们自己的源代码与第三方库代码分开。这是之前的代码,

entry : { entry : }。/src/main.js ',vendor: ['vue ',' vue-router ',' vuex ',' element-ui ',' echart ']},output : { path : config . build . asset root,filename : utils . asset path(' js/[name])。[chunkhash]。js '),Chunk文件名: utils。asset path(' js/[id])。[chunkhash]。js’)} e-charts非常大,所以打包的时候vendor.js大概是1.2MB(gzip压缩后),首页不使用e-charts,所以我用externals以cdn的形式引入第三方库。以下是优化后的代码。

Entry: {entry: '。/src/main.js ',vendor: ['vue ',' vue-router ',' vuex ',' element-ui']},//这里的输出是base中的输出。output output 3360 { path : config . build . asses root,filename:' [name]。js ',librarytarget:' UMD ',public path 3360 process . env . node _ env==' production '?config . build . assets public path : config . dev . assets public path },externals : { echart : ' echart ',_: 'lodash' },9502.163.com

这是优化前后的对比。

然后我们将在html中以脚本标签的形式引用cdn。之后,您可以将其导入相应的文件中。它的优点是,无论你在很多vue文件中引用它多少次,它都不会被打包到所有的trunk中(这里的trunk指的是按需加载,后面会详细解释)。这就是webpack-bundle-analyzer插件显示的效果。

var bundleanalyzer plugin=require(' web pack-bundle-analyzer ')。BundleAnalyzerPlugin新的BundleAnalyzerPlugin({ //可以是服务器、静态的或禁用的)。//在“服务器”模式下,分析器将启动HTTP服务器来显示包报告。//在静态模式下,将生成带有报告的单个HTML文件。//在' disabled '模式下,可以使用这个插件将' generateStatsFile '设置为' true '来生成Webpack Stats JSON文件。分析器模式:“服务器”。//用“服务器”模式使用的主机启动HTTP服务器。Analyzer host:' 127.0.0.1 ',//将在“服务器”模式下使用的端口上启动HTTP服务器。AnalyzerPort: 8888,//路径包,要在静态模式下生成的报告文件。//相对于捆绑的输出目录。默认情况下,报告文件名: ' report . html '//模块大小显示在报告中。//它应该是stat '、parsed '或gzip '之一。//有关更多信息,请参见“定义”一节。DefaultSizes: '已解析',///在默认浏览器中自动打开report openanalyzer 3360。//如果为true,则Webpack Stats JSON文件将在包输出目录中生成generateStatsFile: false。//如果generateStatsFile '为true ',将生成Webpack Stats JSON文件的名称。//相对于捆绑的输出目录。stats filename :' stats.json ',//stats.tojson()方法的选项。//例如,可以使用source:false '选项排除统计文件中模块的来源。//请在此处查看更多选项:https://github.com/web pack/web pack/blob/web pack-1/lib/stats . js # l21 statements 3360 null,log level 3360 ' info '/log level。它可以是“信息”、“警告”、“错误”或“沉默”。})

我们可以看到,像echarts和lodash这样的库,在没有使用externalss的情况下以及使用external之后,都不会出现在所有的js中(即使你导入一万次,他也不会打包一次,太神奇了~ ~)。

还有两点是外在的,——

1.1.externals中的键用于导入

从“_”导入lodash从“echart”导入echart;2.2.externals中的值在window下调用

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

Trunk:构建后的每个版本都意味着构建后的所有文件都具有相同的哈希值。例如,如果我只更改一个文件,所有文件的哈希最终都会更改,这样所有文件都不会被缓存,缓存也就失去了意义。

Trunkhash:根据每个文件生成不同的哈希值。当文件改变时,散列将改变,并且仅改变相应的文件

那么我们必须使用CommonsChunkPlugin。该插件用于提取公共代码。基本上,99%的配置都很长或相似。使用了两种不同的commonschunkPlugins,但这并没有以某种方式实现真正的持久缓存。后面我会通过webpack打包的原理详细说明原因。

新的web pack . optimize.commonchunkplugin({ name :[' vendor ',' manifest']})在使用这个插件之前,我们的main.js和vendor.js将如下所示。

您将看到我们的两个文件有共同的部分,例如vue和element-ui,因此我们需要将共同的代码提取到供应商中,这样我们就可以像这样首先进行配置

new web pack . optimize.commonchunkplugin({ name : ' vendor ',}),但在这种情况下,虽然可以提取公共代码,但我们也会将运行时(webpack runtime(webpack将在后面的打包原则中再次提到)的代码放在vendor中。它将维护一个主干文件列表,与此类似,也就是说,如果我们更改任何代码,该表中的哈希将会更改,因此供应商的哈希也会更改

因此,这并没有实现真正的持久缓存。这个哈希表是一个按需缓存的中继包,通常通过require按需加载,请确保(即与vue-router中配置的页面对应的页面)

所以我们把名字改成了names,这就是上面的配置。因为我们使用这个插件,所以我们将把公共代码提取到名字中,把运行时放在姓中,这就是我们所说的“清单”文件。

并且这个文件会比较小,通常是2kb左右,所以在构建之后会生成一个脚本标签,但是在这种情况下,会多一个http请求,所以我们可以用另一个插件(InlineManifestWebpackPlugin)内联manifest.js。会是这样的

回到我们的CommonsChunkPlugin,现在我们可以随意更改任何现有的文件,并且vendor.js的散列不会改变。是的,这似乎实现了持久缓存。但是当我们添加一个新的模块并将其导入入口文件时,我们的供应商会随着main而改变。很奇怪,不是吗?我们已经清楚地将自己的源代码与第三方库分开了,那么为什么供应商会改变呢?(到目前为止,没有博客应该详细解释这一点。).现在我将向你详细解释我的观点。如果你发现任何错误,请纠正我。

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

webpack条目对应于一个包,它包括条目文件及其相关模块。其他按需加载被打包到其他捆绑包中。还有一个重要的文件,manifest,它首先被加载,并负责打包其他包,并根据需要加载和执行它们。

清单是一个自动执行的函数。熟悉angular的同学应该熟悉第一行,因为angular.bootstrap是在anguar1.3的源代码中启动的,对,这里也是一样。里面的modules变量就是对应的module函数,它是webpack处理的基本单元,也就是说,它对应的是打包前的一个文件

这是js源文件。

这是打包的文件。

所有模块函数索引都是连续的(每个js文件都会生成一个trunkid!),像这样,/* 4 */对应的是js文件,打包后就变成了干线id。如果您仔细观察,您会发现js文件中的导出和require依赖项将在打包之前统一转换为webpack模块。我们讨论的webpackJsonp是打包清单之外的其他文件的函数体。

让我们简单谈谈主要的。这个图的曲线是连续的。我切断了用于在图表上显示的trunk3-7。

有三个参数,第一个是我当前文件的trunkide,是唯一标识符,表示main的trunkide,第二个是所有打包文件的模块函数,第三个是我想立即执行的trunkide模块函数。

好了,这就足够介绍了。

然后让我们回到过去,看看为什么我们所谓的commonschunkPlugin发生了变化。正如我前面所说,当有几个js时,有几个中继id。

因此,当我们添加一个新的js并将其引入主门户时,webpack将被再次打包,我的主文件将有一个额外的模块功能。刚才我们说trunkid是依次递增的,不再重复。因此,相应供应商的id将为1,正是这一微小的变化导致了哈希的变化。

仔细看,这两家厂商有10272行。唯一的区别是我必须自我执行这个供应商库。这里我指的是jquery,所以这个文件只有jquery。自执行必须有一个模块函数,trunkid 1,所以散列会改变。我们再回忆一下。其实这也说明了这个插件的意义。我只想把公共图书馆拉出来。好吧,这个插件做到了,但是因为webpack的打包机制,不同的文件会生成不同的turnkid,所以这是美中不足。回想一下,我们一般不会随便修改main.js,所以从另一个角度来看,这是为了实现持久缓存。但是如果我只想保持供应商的哈希不变呢?

这个代码是可以实现的。是的,如果你对vue-cli了如指掌,这就是vue-cli的官方演示。至于为什么可能,我以后再给你解释(真的很难写。)。

最后给大家介绍一个超级有用的东西,那就是cdn。我们目前的需求是让图片通过cdn和js上线,但是官方的解释是通过修改配置文件来改变cdn。如果我这样做,我的所有输出都将通过cdn,所有ajax请求都将跨域。

起初,我的解决方案是逐个替换源文件,这样会比较慢。更重要的是,cdn图片也有哈希值。以后替换图片的时候,又要换对应的哈希了。他有办法自动得到哈希吗?

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

只是提醒一下,url加载器无法检测到js中的背景,所以我们必须在js中引用的任何地址之外导入这张图片,url加载器才能解析并打包它。

让我们今天到此为止,继续新的一天。

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:webpack学习教程前端性能优化总结是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。