chunk-vendors.js 优化

前言

本文介绍先拆分后压缩的方式优化 chunk-vendors.js,减少 FCP 首屏加载时常

首屏加载可以说是用户体验中最重要的环节

FCP

FCP 定义

FCP ( First Contentful Paint ) 指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容

FCP长的可能原因

  1. 网络太差
  2. 资源文件体积过大
  3. 同一个资源重复发送请求
  4. 外部js文件引入或行内js代码放在了前面,导致需要先执行js,进而引起页面渲染阻塞

优化FCP的常用手段

1. 采用路由懒加载 (已经采用)

import UserDetails from './views/UserDetails.vue'

替换成

const UserDetails = () => import('./views/UserDetails.vue')
 
const router = createRouter({
  // ...
  routes: [
    { path: '/users/:id', component: UserDetails }
    // 或在路由定义里直接使用它
    { path: '/users/:id', component: () => import('./views/UserDetails.vue') },
  ],
})

2. 静态资源本地缓存

合理利用本地缓存localStorage
HTTP缓存, 设置cache-control、Etag和Last-Modified
Service Worker缓存,它是一种利用Service Worker API实现的离线缓存功能,它可以使用户在离线的情况下访问网站内容,从而提高用户体验

3. 尽可能采取按需引入资源 (新采用)

像element UI、Ant Design、ECharts等都是支持按需引入的,不把整个库直接引进来,能有效降低项目体积

4. 避免组件重复打包

在webpack的config文件中,修改CommonsChunkPlugin的配置
minChunks为3表示会把使用3次及以上的包抽离出来,放进公共依赖文件,避免了重复加载组件

CommonsChunkPlugin:{ miniChunks: 3}

5. 对图片资源进行压缩

图片资源是http请求里比较大的一个消耗,应该进行适当的压缩,对于一些icon,可以使用在线字体图标,比如阿里巴巴的矢量图标库

6. 开启Gzip压缩

GZip压缩能把资源体积压缩到只有原本的30%左右,如果项目够大,这个优化效果是非常可观的

7. 使用SSR

服务端渲染,在服务端生成好html字符串,再发送到浏览器,服务端计算速度肯定会比浏览器快,也是减少首屏时间的一个好方法,vue2和Vue3都推荐用Nuxt来实现ssr

更全的优化方案,请参考
在这里插入图片描述

量化优化指标

安装 web-vitals

yarn add web-vitals
// 或者
npm install web-vitals

在 App.vue 加入 web-vitals 性能监控指标并打印

import {onLCP, onINP, onCLS, onTTFB} from 'web-vitals/attribution';

// Measure and log LCP as soon as it's available.
onLCP(console.log);
onINP(console.log);
onCLS(console.log);
onTTFB(console.log);

在这里插入图片描述
网页的FCP指数降到poor的水平

chunk-vendors.js 简介

chunk-vendors.js 顾名思义 chunk (块 / 包) - vendors (供应商),即为:不是自己写的模块包,也就是/node_modules项目目录的所有模块包,它们称为第三方模块或供应商模块。

chunk-vendors.js 文件大小分析

测试环境

Chrome Dev Tools的 Network 标签页请求 chunk-vendors.js 文件,大小是4.5MB
在这里插入图片描述
虽然Time显示只有793毫秒

生产环境

Chrome Dev Tools的 Network 标签页请求 ‘chunk-vendors.js’ 文件,被拆分成好几个单独的问题,最大的也占1.2MB
在这里插入图片描述

加载时间是425毫秒

总结

以上两种情况实在内网本机,访问速度相对快,如果到了外网就跟服务器带宽,性能有关了。文件这么大,加载又慢,我们在这篇文章就介绍两种方案,先拆分再压缩。

方案

1. 拆分

附带还未进行分块分包加载时,打包得到的文件目录

在这里插入图片描述
修改 vue.config.jsconfigureWebpack.optimization.splitChunks 选项如下

// 看这里:把chunk-vendors.js进行分包,提升资源加载速度,很有必要
module.exports = {
    // 其他配置
    configureWebpack: {
        plugins: [],
        optimization: {
            /**
             * runtimeChunk可选值有:true或'multiple'或'single'
             * true或'multiple'会有每个入口对应的chunk。不过一般情况下
             * 考虑到要模块初始化,设置为single就够多数情况下使用啦。
             * 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk
             * */
            runtimeChunk: 'single',
            /**
             * 以前是CommonsChunkPlugin,现在换成optimization.splitChunks。普通项目下方的配置就足够用啦
             * 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks
             * */
            splitChunks: {
                chunks: 'all', // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
                maxInitialRequests: Infinity, // 最大并行请求数,为了以防万一,设置无穷大即可
                minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
                maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
                cacheGroups: {
                    vendors: {
                        test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
                        priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
                        name(module) { // 设定分包以后的文件模块名字,按照包名字替换拼接一下
                            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                            return `npm.${packageName.replace('@', '')}`
                        },
                    },
                },
            }
        }
    }
}

打包后的目录如下:
在这里插入图片描述

2. 压缩

compression-webpack-plugin 插件压缩

安装 compression-webpack-plugin

yarn add compression-webpack-plugin --save-dev

遇到报错 "compression-webpack-plugin@11.1.0: The engine "node" is incompatible with this module."
在这里插入图片描述

安装报错解决方案
方案一:安装与当前项目的node版本适配的 compression-webpack-plugin@6.1.1,提示安装成功

在这里插入图片描述

方案二:升级node版本

未采取

方案三:忽略引擎版本检查

设置 ignore-engines=true 修复版本不兼容的问题。

yarn config set ignore-engines true

未采取

配置 compression-webpack-plugin

修改vue.config.js的configureWebpack.plugins选项,如下:

const CompressionPlugin = require('compression-webpack-plugin'); //引入gzip压缩插件

module.exports = {
    // 其他配置
    configureWebpack: {
        plugins: [
            new CompressionPlugin({ //此插件不能使用太高的版本,否则报错:TypeError: Cannot read property 'tapPromise' of undefined
                // filename: "[path][base].gz", // 这种方式是默认的,多个文件压缩就有多个.gz文件,建议使用下方的写法
                filename: '[path].gz[query]', //  使得多个.gz文件合并成一个文件,这种方式压缩后的文件少,建议使用
                algorithm: 'gzip', // 官方默认压缩算法也是gzip
                test: /\.js$|\.css$|\.html$|\.ttf$|\.eot$|\.woff$/, // 使用正则给匹配到的文件做压缩,这里是给html、css、js以及字体(.ttf和.woff和.eot)做压缩
                threshold: 10240, //以字节为单位压缩超过此大小的文件,使用默认值10240吧
                minRatio: 0.8, // 最小压缩比率,官方默认0.8
                //是否删除原有静态资源文件,即只保留压缩后的.gz文件,建议这个置为false,还保留源文件。以防:
                // 假如出现访问.gz文件访问不到的时候,还可以访问源文件双重保障
                deleteOriginalAssets: false
            })
        ]
    }
}

打包后,出现了.zip文件,目录列表如下
在这里插入图片描述

后端配置之nginx配置

server {
    listen       80;
    server_name  localhost;
    location / {
        try_files $uri $uri/ /index.html;
        root C:/nginx-1.18.0/html/gzip/dist;
        index  index.html index.htm;
    }
    location /api/ {
        proxy_pass http://localhost:6666/;
    }
    
    # 主要是下方的gizp配置哦,直接复制粘贴就可以使用啦,亲测有效哦
    gzip on; # 开启gzip压缩
    gzip_min_length 4k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩
    gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改
    gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改
    gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了
                # 压缩的文件类型 MIME类型,百度一下,一大把                                    # css             # xml             # 识别php     # 图片
    gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf;
                # text                   # 早期js                 # js        # js的另一种写法                                                                                 # .eot字体                   # woff字体  # ttf字体
    gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启       
}

和后端确认了,nginx配置是开启了gzip压缩的

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值