当前位置: 首页 > 科技观察

我用这些技巧把页面加载速度提高了90%

时间:2023-03-20 21:27:02 科技观察

前言之前用vuecli做过博客。这是一个单页项目,大约有十条路线。直接通过npmrunbuild打包。有一个巨大的1M的js文件。首先,将其挂载到服务器上并尝试一下。好家伙,加载时间好像过了半个世纪。第一个屏幕页面已加载9秒。仅加载大文件就需要8秒。这个必须优化。没有用户能忍受不关闭页面的9s白屏。我也把项目从vuecli2.x迁移到了vuecli3,所以我会介绍一些优化的异同点。自带分析工具,所以只需要运行npmrunbuild--report。如果是vuecli3,先安装插件cnpmintallwebpackbundleanalyzersavedev然后在vue.config.js中配置webpackchainWebpack:(config)=>{/*添加分析工具*/if(process.env.NODE_ENV==='production'){if(process.env.npm_config_report){config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin).end();config.plugins.delete('prefetch')}}}然后运行??npmrunbuild--report这时候会在浏览器中打开一个项目打包图,方便直观比较每个bundle文件的大小。可以看到项目中所有的依赖,所有的Routing,都打包到了同一个文件中。另外,在浏览器中,还可以使用converge查看代码的使用情况。红色部分是已下载但未使用的部分。路由延迟加载在包中构建应用程序时,JavaScript包可能会变得非常大,从而影响页面加载。如果我们能把不同路由对应的组件分成不同的代码块,然后在路由访问时加载相应的组件,效率会更高。一开始就把路由对应的组件文件都下载下来,显然是不合适的。这就好比下载一个app,所以我们需要在router.js文件中使用路由进行懒加载。原静态引用方法importShowBlogsfrom'@/components/ShowBlogs'routes:[path:'Blogs',name:'ShowBlogs',component:ShowBlogs]改成routes:[path:'Blogs',name:'ShowBlogs',component:()=>import('./components/ShowBlogs.vue')以函数的形式动态引入,这样就可以将各自的路由文件单独打包,只有在给定的路由被解析的时候,才将其所在的文件需要在首屏加载的路由组件才会被下载。橙色部分被小弟们分流出去了。如果是在vuecli3中,我们还需要多做一步,因为vuecli3默认开启了prefetch(预加载模块),提前获取用户以后可能访问的内容。首屏会一次性下载这几十个路由文件,所以我们要关闭这个功能,在vue.config.js中设置参考官网:设置后首屏只会加载当前的页面路由组件element-ui按需加载首屏需要加载的依赖包,element-ui占用足足568k。原来的导入方式引入了整个包:importElementUIfrom'element-ui'Vue.use(ElementUI)但实际上我用到的组件只有按钮、分页、表格、输入和警告,所以需要按需引用:import{Button,Input,Pagination,Table,TableColumn,MessageBox}from'element-ui';Vue.use(Button)Vue.use(Input)Vue.use(Pagination)Vue.prototype.$alert=MessageBox.alert注意MessageBox注册方式的区别,虽然我们使用了alert,但是不需要引入Alert组件来添加在.babelrc文件(vue-cli3需要先安装babel-plugin-component):plugins:[["component",{"libraryName":"element-ui","styleLibraryName":"theme-chalk"}]]element-ui小了很多,但是看到显眼的table.js后,以为table组件只是后台管理页面使用,不需要全局注册,所以我们删除了main.js中Table和TablColumn的引用,并注册import{Table,本地在后台组件TableColumn}from"element-ui";components:{"el-table":Table,"el-table-column":TableColumn},表拆分到路由文件和组件重复打包。可以看到上图,有两个路由文件都引用了codemirror.js,导致重复下载。我们可以在webpack的config文件中修改CommonsChunkPlugin的配置minChunks:3,把3改成2,那么会把使用过两次以上的包提取出来放到公共依赖文件中,但是因为首页也有复用了组件,所以首页也会下载这个公共依赖文件。黄色和灰色部分在首页下载。拆了半天,又回到了原点。当然我们可以继续折腾CommonsChunkPlugin的配置来解决这个问题。但是在新版本的webpack中,CommonsChunkPlugin被更自由更高级的SplitChunksPlugin所取代,这也是我为什么要将项目迁移到vuecli3(使用webpack4)的原因,因为默认优化了,首页只会下载灰色的part(235K)gzip解压后,我们用gzip压缩安装compression-webpack-plugincnmpicompression-webpack-plugin-D在vue.congig.js引入修改webpack配置constCompressionPlugin=require('compression-webpack-plugin')configureWebpack:(config)=>{if(process.env.NODE_ENV==='production'){//修改生产环境的配置...config.mode='production'return{plugins:[newCompressionPlugin({test:/\.js$|\.html$|\.css/,//匹配文件名threshold:10240,//压缩超过10k的数据deleteOriginalAssets:false//是否删除原文件})]}}可以请参阅超过200k的文件被压缩到小于100k。我们还需要相应地配置服务器。如果发送请求的浏览器支持gzip,则将文件以gzip格式发送给它。我的服务器是用express框架构建的。只要安装compression就可以使用constcompression=require('compression')app.use(compression())注意后一句要放在所有其他中间件注册之前。最终效果是首屏加载资源198k,加载时间1s,比原来快了90%后记:vuecli3和vuecli2.x是否要拆分css另一个区别是vuecli3会开一个css默认分离插件ExtractTextPlugin,每个模块的css文件都会分离出来,一共13个css文件,而我们的首页请求有4个,占用资源请求时间比较多。我们可以在vue.config.js中关闭css:{//是否使用css分离插件ExtractTextPluginextract:false,//开启CSSsourcemaps?sourceMap:false,//css预设配置项loaderOptions:{},//enableCSSmodulesforallcss/pre-processorfiles.modules:false},打包后的文件中,直接没有css文件夹,而是集成了一个js文件,开头负责注入所有样式。首屏加载的文件数量减少了,但体积变大了,最终测得的速度也相差不大。因此,是否拆分css见仁见智,具体项目具体分析。综上所述,性能优化是一个很愉快的过程,但也是一个深坑,东西太多。这篇文章是开篇,希望能对大家有所帮助。