10 秒 到 2秒 超简单的Vue项目首屏优化实践

10 秒 到 2秒 超简单的Vue项目首屏优化实践

摘要

性能优化是一个比较大的知识点,包含但不限于性能优化的工具,技术手段和流程,本文主要从压缩文件体积,减少请求次数方面入手,优化Vue项目的首屏加载时间,实现首屏加载10秒到2秒的提升。主要技术栈如下:Vue cli3 Element UI

首屏优化

Vue 是典型的单页应用,首次加载耗时多,因此优化Vue项目首屏加载对于提升用户体验非常重要。下图展示了一个糟糕的首屏加载案列,白屏时间长达10余秒,简直让人无法忍受!

糟糕的额体验

如何优化

方法一: 压缩文件体积
  • 压缩文件体积操作简单粗暴,效果却非常明显。常见的压缩文件体积的方法如下:
  1. 压缩图片体积,设置合适的图片尺寸
  2. 多图页面采用雪碧图(尤其是小图片)
  3. 开启GZIP压缩
  4. 关闭源码视图,清除console.log 日志

上述方案可根据具体情况考虑,比如我手下的项目主要是Vue+Element UI搭建的后台管理系统,并未涉及图片,因此只需采取方案3和方案4即可。

开启GZIP压缩
  • Vue项目前端配置GZIP
  1. 安装CompressionPlugin
npm i compression-webpack-plugin -D
  1. vue.config.js中进行配置

vue cli3 将webpack配置和vue配置都集中在vue.config.js中管理,这一点需要注意和vue cli2 的区别.如果没有vue.config.js文件可自行在项目根目录下创建\

const CompressionPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;

/** 开发环境 */
const DEV = process.env.NODE_ENV !== 'production';


module.exports = {
	/* vue.config.js支持webpack-chain写法 */
	chainWebpack: config =>{
		/* *******************************************
		 *  
		 * 开启GZIP压缩
		 * 压缩前:4.4MB
		 * 压缩后:1.7MB
		 * @Author: mingyong.g
		 * @Date: 2020-09-02 19:55:13
		 * 
		 ********************************************/
		 if(!DEV){
		 	config.plugin('compressionPlugin')
		 	.use( new CompressionPlugin({
		 		filename: "[path].gz[query]",
				algorithm:"gzip",
		 		test:productionGzipExtensions,  //所有匹配此{RegExp}的资产都会被处理
		 		threshold:512,   //	只处理大于此大小的资产。以字节为单位
		 		minRatio:0.8,    //只有压缩好这个比率的资产才能被处理
				deleteOriginalAssets:false //是否删除原资源
		 	}))
		 }
}

CompressionPlugin的主要配置和说明如上,此外需要特别注意的是deleteOriginalAssets是否删除原资源,这里建议设置为false即压缩资源和原始资源共存,以保证当客户端或者服务端不支持gzip压缩时能够返回原始资源,保障应用正常运行.否则可能出现404错误.更多配置请参见
🚀CompressionPlugin中文文档

  1. 查看压缩效果
    在这里插入图片描述

未配置gzip在这里插入图片描述

  • 服务器开启GZIP压缩

    光是前端进行gzip压缩是不够的,同时需要开启服务端gzip共嫩,下面介绍下nginx和IIS服务器如何开启gzip压缩功能.

    • nginx服务器下开启gzip压缩

      	gzip on;
      	gzip_static on;
      	gzip_min_length 1k;
      	gzip_buffers 4 32k;
      	gzip_http_version 1.1;
      	gzip_comp_level 2;
      	gzip_types text/plain application/x-javascript text/css application/xml;
      	gzip_vary on;
      	gzip_disable "MSIE [1-6].";
      

      配置说明:

      	gzip on
      
        on为启用,off为关闭
      
        gzip_min_length 1k
      
        设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。默认值是0,不管页面多大都压缩。建议设置成大于1k的字节数,小于1k可能会越压越大。
      
        gzip_buffers 4 16k
      
        获取多少内存用于缓存压缩结果,‘4 16k’表示以16k*4为单位获得
      
        gzip_comp_level 5
      
        gzip压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值;
      
        gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php
      
        对特定的MIME类型生效,其中'text/html’被系统强制启用
      
        gzip_http_version 1.1
      
        识别http协议的版本,早起浏览器可能不支持gzip自解压,用户会看到乱码
      
        gzip_vary on
      
        启用应答头"Vary: Accept-Encoding"
      
        gzip_proxied off
      
        nginx做为反向代理时启用,off(关闭所有代理结果的数据的压缩),expired(启用压缩,如果header头中包括"Expires"头信息),no-cache(启用压缩,header头中包含"Cache-Control:no-cache"),no-store(启用压缩,header头中包含"Cache-Control:no-store"),private(启用压缩,header头中包含"Cache-Control:private"),no_last_modefied(启用压缩,header头中不包含"Last-Modified"),no_etag(启用压缩,如果header头中不包含"Etag"头信息),auth(启用压缩,如果header头中包含"Authorization"头信息)
      
      	gzip_disable msie6
      
    • IIS服务器配置GZIP( win server 2008R2 / IIS 7.5)

    1. 进入IIS管理器,点击图中压缩按钮
      IIS 开启GZIP
    2. 勾选压缩功能并应用
      IIS 开启GZIP
关于IIS服务器的特别说明

经实践证明,对于IIS服务器无需前端额外设置gzip压缩 也就是无需安装CompressionPlugin并进行相关配置

GZIP 优化效果

在这里插入图片描述
通过gzip压缩资源大小从4.4M压缩至1.7MB finish load时间降到了3.8s效果显著

方法二: 减少请求次数

通过上图发现首屏加载过程中总共发起了291次请求,这显然是不友好的.减少首屏加载请求次数可考虑从以下几方面入手:

  • 使用SplitChunks分离代码并实现相同模块共享,从而减少请求次数
  • vue-router使用懒加载
  • 尽量避免组件库,UI库全局注入,最好是按需引用
使用SplitChunks分离代码并实现相同模块共享,从而减少请求次数
  1. 安装BundleAnalyzerPlugin插件生成依赖包可视化分析图谱,帮助开发者分析项目结构
npm install --save-dev webpack-bundle-analyzer
  1. vue.config.js中进行BundleAnalyzerPlugin插件配置
/** 开发环境 */
const DEV = process.env.NODE_ENV !== 'production';

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
	publicPath : './'  // 若要自动生成可视化分析页面,请将publicPath设置为相对路径
	configureWebpack: config => {
	
  /* **********************************************
   *
   * @description webpack 依赖包可视化分析
   * 仅在性能分析的时候启用
   * @Author: mingyong.g
   * @Date: 2020-09-02 21:24:31
   * 
   ***********************************************/
	 //if(DEV){
		 config.plugins.push(new BundleAnalyzerPlugin())
	 //}
	}
}

3. 运行npm run build --report 生成分析页面

npm run build --report

在这里插入图片描述
4. 配置SplitChunks对注意模块进行分离

chainWebpack: config =>{
	if (!DEV) {
      config.optimization.splitChunks({
        cacheGroups: {
          common: {
            name: 'chunk-common', // 打包后的文件名
            chunks: 'all', // 
            minChunks: 2,
            maxInitialRequests: 5,
            minSize: 0,
            priority: 1,
            reuseExistingChunk: true
          },
          vendors: {
            name: 'chunk-vendors',
            test: /[\\/]node_modules[\\/]/,
            chunks: 'all',
            priority: 2,
            reuseExistingChunk: true,
            enforce: true
          },
          ElementUI: {
            name: 'chunk-element-ui',
            test: /[\\/]node_modules[\\/]element-ui[\\/]/,
            chunks: 'all',
            priority: 3,
            reuseExistingChunk: true,
            enforce: true
					},
					xlsx: {
						name:"chunk-xlsx",
						test: /[\\/]node_modules[\\/]xlsx[\\/]/,
						chunks: 'all',
            priority: 4,
            reuseExistingChunk: true,
            enforce: true
					}
				}
			})
		}
	},
  1. 再次运行运行npm run build --report 查看结果
npm run build --report

在这里插入图片描述
已经好很多了,这时通过F2打开控制面板可以看到请求数已经只有130多次了,相比原始的291次,已经好很多了.同时请求资源降到了1.3Mb,load加载时间降到了1.56,finish时间仅1.77s(平均值在2s左右),
在这里插入图片描述
再来感受下首屏加载效果(ctrl+F5)并非本地刷新

在这里插入图片描述

路由懒加载

作为一个后台管理系统,路由较多使用路由懒加载是优化首屏加载的重要手段.路由懒加载设置比较简单,这里简单提及一下.在router.js文件中,原来的静态引用方式改为以函数的方式动态引入,这样就可以把各自的路由文件分别打包,只有在解析给定的路由时,才会下载路由组件

{
    path: '/Login',
    name: 'Login',
    component: () = >import( /* webpackChunkName: "Login" */  '@/view/Login')
}

更细致的优化

本文到这里通过配置gzip / splitChunks / 路由懒加载已经实现了首屏加载10s到2s的性能提升,那么还有没有更进一步的优化空间呢?答案是有的,正如前面所说性能优化是一门很大的学问.以本项目为例,其实仍有很大的优化空间.下面先给出几张性能评估图再分析应该从那些方面着手进一步优化

1. webpack-bundle-analyzer分析图
在这里插入图片描述
2. lighthouse分析图
在这里插入图片描述
3. Coverage分析图
在这里插入图片描述
lighthouse分析图显示当前性能仅35%😭而其它项评分都还不错,继续分析 Coverage分析图可知再首页加载过程中约66% 的资源未被使用,也就是说可以通过优化这66% 的资源做到更好的首屏加载效果.
进一步优化主要思路在于减少全局注入

  1. Element 组件 按需引入
    很多时候为了图方便将整个第三方库全局注入到项目中,比如Element UI, 其实更好的做法是按需应用,比如说项目仅用到了Button组件/select组件/table组件则仅在项目中引入这些组件即可,关于Element 按需引入可以参考🚀Element 按需引入

由于当前系统使用的Element 组件过多,可能本项优化暂不予考虑避免引起全局性,破坏性的错误

  1. 优化暂未使用的文件
    首当其冲的就是webpack-bundle-analyzer分析图中显示的xlsx.js ,这个文件当时是参考element-admin 引入用于处理excel文件的第三方库,该库本身资源就很大,又由于我将其封装到全局组件中,故而首页加载时将其一并请求到客户端,这里也是一个主要的优化点,随着业务和需求变更,这个第三方库目前来看已经没有存在价值了,后续将考虑将其从代码从剥离,从而实现更好的加载体验.

  2. 结合webpack-bundle-analyzer分析图SplitChunks插件对代码作更细致的拆分
    需要注意的减少请求数必然使得单个文件体积变大,二者是矛盾的,最佳实践是取得一个中庸的值平衡优劣.


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mingyong.g

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值