前言:
当前文章的记录背景:上上周做的项目提测了,我想着终于有时间可以好好整理一下项目,正好用这个时间来学习一下;另外关于
nginx,之前也没搞过,这次也顺便熟悉一下。还有webpack的一些配置需要优化,这里就记录一下整个优化的过程。
关于nginx 中使用到的 linux 命令:链接在此
项目背景:项目是22年年初开始动工的,是一个类似官网的后台项目,起初设计稿的方向是仿照本公司的主官网做的项目,后期添加了权限功能,后期看项目的时间,如果有时间就再调研一下
SSR。
webpack 配置优化
首先我们需要借助
speed-measure-webpack-plugin插件,它会帮我们分析webpack的总打包耗时,以及每个plugin和loader的打包耗时,从而让我们对打包时间较长的部分进行针对性优化。
通过以下命令安装插件:
yarn add speed-measure-webpack-plugin -D
build之后就能看到各个部分的打包耗时
绿色代表优秀,黄色代表耗时在临界值范围,红色代表耗时较长,需要优化
初始化状态
初始化状态,测试
3次,项目的打包速度,分别为:55s 、57s、 57s、 54s,在这张图中,我们发现标记红色的指标还挺多的,意味着我们的项目还是有优化空间的。那么从这里开始,我们动手吧!
配置 exclude 、include,减少loader 编译范围
我们在使用
loader的时候,尽可能把loader应用的文件范围缩小,只在最少数必须的代码模块中去使用必要的loader,例如node_modules目录下的其他依赖类库文件,基本就是直接编译好可用的代码,无须再经过loader处理了,
假如在exclude和include同时配置了相同文件,谁的优先级高?
exclude的优先级要高于include,当配置相同内容时,exclude会覆盖include里的配置,所以在配置时要明确是否存在交集
开启 include
include表示哪些目录中的.js文件需要 loader 进行处理。打开所有include后 ,测试4次,项目的打包速度,分别为:44s、 40s 、42s、 34s
const srcPath = path.join(__dirname, '..', 'src');
// ....
module: {
rules: [
{
test: /\.(htm|html)$/i,
use: [
{
loader: 'html-loader',
options: {
esModule: false,
},
},
],
include: srcPath,
},
]
}
开启exclude
exclude表示哪些目录中的 .js 文件不要loader进行处理。打开所有的exclude,测试4次,项目的打包速度分别为:39s 、 38s、 41s、 38s,时间分布在38s - 41s之间
const srcPath = path.join(__dirname, '..', 'src');
// ....
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
],
include: srcPath,
exclude: /\.file.js$/i,
},
]
}
配置 thread-loader 多进程打包
当项目越来越大,打包速度越来越慢,我们可以开启多进程同时处理
js文件,这样速度就比之前的单进程打包更快了。
使用ts loader测试
36s、34s、37s、36s,时间分布在34s-37s之间
const assetsPath = path.join(__dirname, '..', 'src/assets');
const utilsPath = path.join(__dirname, '..', 'src/utils');
// ....
{
test: /\.tsx?$/,
use: ['ts-loader'],
include: srcPath,
exclude: [assetsPath, utilsPath],
},
使用 thread-loader测试
26s、26s、27s、25s,时间分布在25s - 27s之间
const assetsPath = path.join(__dirname, '..', 'src/assets');
const utilsPath = path.join(__dirname, '..', 'src/utils');
// ....
{
test: /\.tsx?$/,
use: ['thread-loader'],
include: srcPath,
exclude: [assetsPath, utilsPath],
},
除了上述几个,项目中还配置了其他的优化方法,只是那些优化方法在更早之前就添加了,所以不在本次优化系列内,后面我会再出一篇关于webpack 的全面优化教程,期待就加个关注哦!
优化结果:总打包耗时从开始的56s,到优化后时间约25s,效率提升了45%左右。
nginx 配置优化
⚠️ 注意事项:如果你也想和我一样一步步来通过操作来看到你优化后的结果,那么有以下两个注意事项:
-
每次清空
cookie,再执行,disabled catch -
修改完
ninx配置后,需要重启nginx 才会生效:sudo nginx -s reload
初始化状态:
代码打包不打gz包,nginx 不开gzip,和一系列的gzip配置。展示刷新后到页面最后一个元素展示完成所需时间相同的配置,根据网络情况,开始到最后展现时间平均 1000ms左右,白屏时间约为90ms
示例图1:
示例图2:
示例图3:
下面是原文件包的大小,以及总计用时:
尝试打开nginx 的gzip 配置:
gzip:on
示例图1:
示例图2:
示例图3:
当前的文件大小,传输时间:,总计用时:
开启 nginx 的 gzip 压缩以及gzip 的其他配置
通过打开
nginx的gzip压缩 和一系列的gzip配置,整体速度明显下降了,分别测试了3次,平均为:734ms,相对之前的减少了300ms左右,示例图如下:
gzip 的其他配置:
gzip_min_length 1k;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
示例图1:
示例图2:
示例图3:
当前的文件大小,传输时间:,总计用时:
通过上传gzip文件,并开启默认使用上传的文件,减少nginx 压缩时间
页面引入:compression-webpack-plugin
webpack 中添加如下配置:
const CompressionWebpackPlugin = require('compression-webpack-plugin');
new CompressionWebpackPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: new RegExp('\\.(' + ['js', 'css', 'mp4', 'png'].join('|') + ')$'),
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: true,
})
示例图1:
示例图2:
示例图3:
示例图4:
示例图5:
当前的文件大小,传输时间:,总计用时:
开启 gzip_static on;
nginx对于静态文件的处理规则,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩。
示例图1:
示例图2:
示例图3:
文件大小:
开启proxy
示例图1:
示例图2:
示例图3:
示例图4:
示例图5:
文件大小:
其他细节优化
- 小图标使用
iconfont - 小图使用
base64 - 大图压缩再上传
js放在页面底部并使用异步加载,不影响html解析css放在头部,尽快去处理和解析localstorage本地存储- 语义化标签
示例图1:
示例图2:
示例图3:
示例图4:
优化结果:加载时间从最初的1000ms 到 最后稳定在 400ms-600ms 之间,白屏时间从开始到90ms 到优化后到14ms,一定程度上提高了网站打开速度,降低用户跳出率。
使用 lighthose 测试效果
优化seo
- 合理使用
meta标签,添加标题、关键字、描述等信息 - 图片添加
alt tree-shaking删除无效内容,包括下载没用到的第三方库或者冗余的图片或代码- 使用语义化标签
- 添加网站外链
(后面的优化是非线上环境,至于best practices 为啥会低下来,我也没找到原因,大概率和环境有关吧)
优化到这里,浅浅的算个终点吧,因为这个项目是toB 项目,并不是toC 的,另一方面这个项目的静态内容偏多,整体速度感官还是蛮快的,综合以上两点,所以关于ssr暂且就放弃了,希望在其他项目中可以体验一下ssr 的使用吧。