前端性能优化
最近有用nuxt开发商城的经验,nuxt是为了解决SEO的一个服务端渲染框架,他的渲染方式跟vue不同的是:nuxt首先经过服务端渲染之后再到客户端渲染,也因为如此,它对服务端的运行内存要求较高,容易出现内存溢出的情况,为此,前端对代码的要求以及打包都需要尽量优化。具体优化的方案有以下:
一、从前端角度
1、资源按需加载
script资源的加载方式有三种,分别是同步模式、异步模式(async),延迟模式(defer)
- 同步模式下的资源加载和执行会阻塞页面的解析和渲染,使用过程中应注意
script标签所放置的位置,需放置到body后面,以防止阻塞页面解析; - 异步模式下的资源加载是异步的,执行是同步的,加载完成后会立马执行,执行过程中,浏览器处于阻塞状态,无法响应任何请求;
- 延迟模式下的资源加载是异步的,执行是同步的,但它加载完不会立马执行,而是等到
DOM ready之后才执行。该模式也称为惰性加载,这种模式可以应用于图片懒加载、路由懒加载等,该模式即将资源切片成多个模块,当应用到哪个模块再对应去加载;
2、图片资源的处理
- 压缩图片资源,
webpack可以使用插件实现:imagemin-webpack-plugin - 图片资源缓存到
CDN上,通过CDN来压缩、裁剪一定尺寸、格式转换、缩放、旋转图片、添加水印等,同时,前端对于图片的加载应使用懒加载,具体配置方法可上oss上查看,点击跳转至oss官网文档 - 分清不同场合分别使用哪种图片格式的资源,目前前端开发过程使用频率高的图片格式如下:
webp: 由google推出,支持无损压缩和有损压缩,且压缩效率、压缩后的图片体积也很可观,目前支持度(如下图),它不支持IE;jpg: 有损压缩,压缩后的图片体积减小,但需以图片分辨率为代价的,适用于列表页中的产品小图等;png: 无损压缩,压缩后的图片体积比jpg大,但图片分辨率保持,适用于产品详情中的大图等;gif: 支持动图,只能支持256色索引颜色;svg: 矢量图,可自由缩放,不会有图片质量损失的情况。
3、静态资源的压缩
- 静态资源的
gzip和broti压缩:
gzip和broti是两种压缩算法,性能上,broti的压缩效率会比gzip高,其在ng上的配置方法也复杂的多,需要去额外下载插件;这两种压缩在ng那边都可以配置,前端在webpack打包时也可以配置上,前端的打包配置方法如下:
以nuxt.js为例,需要安装nuxt-precompress插件,之后再nuxt.config.js中配置相关参数:
// 配置代码压缩 https://www.npmjs.com/package/nuxt-precompress
nuxtPrecompress: {
enabled: true, // Enable in production
report: false, // set true to turn one console messages during module init
test: /\.(js|css|html|txt|xml|svg)$/, // files to compress on build
// Serving options
middleware: {
// You can disable middleware if you serve static files using nginx...
enabled: true,
// Enable if you have .gz or .br files in /static/ folder
enabledStatic: true,
// Priority of content-encodings, first matched with request Accept-Encoding will me served
encodingsPriority: ['br', 'gzip']
},
// build time compression settings
gzip: {
// should compress to gzip?
enabled: true,
// compression config
// https://www.npmjs.com/package/compression-webpack-plugin
filename: '[path].gz[query]', // middleware will look for this filename
threshold: 10240,
minRatio: 0.8,
compressionOptions: { level: 9 }
},
brotli: {
// should compress to brotli?
enabled: true,
// compression config
// https://www.npmjs.com/package/compression-webpack-plugin
filename: '[path].br[query]', // middleware will look for this filename
compressionOptions: { level: 11 },
threshold: 10240,
minRatio: 0.8
}
},
- 打包时的资源压缩:通过
webpack插件compression-webpack-plugin可实现,具体实现方法如下: 以nuxt.js框架为例:
// build构建参数
build: {
plugins: [
new CompressionPlugin({
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10kb的数据进行压缩
deleteOriginalAssets: false // 是否删除原文件
})
]
}
- 资源切片:项目开发过程中,发现配置了以上之后,还是不足够,页面加载
vendor.app.js还是加载了挺长时间,于是引入资源切片,再配合h2,多个资源的请求可以并发执行,页面资源加载解析速度提高了不少,下面是配置方法,同样以nuxt为例:
build: {
plugins: [
new CompressionPlugin({
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10kb的数据进行压缩
deleteOriginalAssets: false // 是否删除原文件
})
],
optimization: {
splitChunks: {
minSize: 10000,
maxSize: 250000
}
}
}
4、最后一点是最简单也是最重要的
- 代码多审查,防止全局变量占用空间、注意监听事件的取消、定时器的
- 去除无用、冗余代码
- 精简样式表
- 事件的触发注意节流防抖
二、从服务端角度
1、http2(简称:h2)
开启h2后,浏览器支持并发下载资源,且一旦某个资源下载中断浏览器会自动下载下一个资源,不会阻塞着,这极大的提高了页面的渲染速度。
2、利用http缓存机制
具体的文章可以看下我的上一篇关于浏览器缓存一说