【nginx】记录一次通过配置 nginx 和 webpack 来优化项目

516 阅读4分钟

前言:

当前文章的记录背景:上上周做的项目提测了,我想着终于有时间可以好好整理一下项目,正好用这个时间来学习一下;另外关于nginx,之前也没搞过,这次也顺便熟悉一下。还有webpack 的一些配置需要优化,这里就记录一下整个优化的过程。

关于nginx 中使用到的 linux 命令:链接在此

项目背景:项目是22年年初开始动工的,是一个类似官网的后台项目,起初设计稿的方向是仿照本公司的主官网做的项目,后期添加了权限功能,后期看项目的时间,如果有时间就再调研一下SSR

webpack 配置优化

首先我们需要借助 speed-measure-webpack-plugin 插件,它会帮我们分析 webpack 的总打包耗时,以及每个 pluginloader 的打包耗时,从而让我们对打包时间较长的部分进行针对性优化。

通过以下命令安装插件:

yarn add speed-measure-webpack-plugin -D

build之后就能看到各个部分的打包耗时

绿色代表优秀,黄色代表耗时在临界值范围,红色代表耗时较长,需要优化

初始化状态

初始化状态,测试3次,项目的打包速度,分别为:55s 、57s、 57s、 54s ,在这张图中,我们发现标记红色的指标还挺多的,意味着我们的项目还是有优化空间的。那么从这里开始,我们动手吧!

初始速度.png

配置 exclude 、include,减少loader 编译范围

我们在使用 loader 的时候,尽可能把 loader 应用的文件范围缩小,只在最少数必须的代码模块中去使用必要的 loader,例如 node_modules 目录下的其他依赖类库文件,基本就是直接编译好可用的代码,无须再经过 loader 处理了,

假如在excludeinclude同时配置了相同文件,谁的优先级高?

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,
      },
      
     ]
}

打开include.png

开启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,
      },
     ]
   }

添加exclude.png

配置 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],
},

使用ts loader.png

使用 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],
},

使用thread-loader.png

除了上述几个,项目中还配置了其他的优化方法,只是那些优化方法在更早之前就添加了,所以不在本次优化系列内,后面我会再出一篇关于webpack 的全面优化教程,期待就加个关注哦!

优化结果:总打包耗时从开始的56s,到优化后时间约25s,效率提升了45%左右。

nginx 配置优化

⚠️ 注意事项:如果你也想和我一样一步步来通过操作来看到你优化后的结果,那么有以下两个注意事项:

  • 每次清空cookie,再执行,disabled catch

  • 修改完ninx配置后,需要重启nginx 才会生效:sudo nginx -s reload

初始化状态:

代码打包不打gz包,nginx 不开gzip,和一系列的gzip配置。展示刷新后到页面最后一个元素展示完成所需时间相同的配置,根据网络情况,开始到最后展现时间平均 1000ms左右,白屏时间约为90ms

示例图1:

截屏2022-03-07 16.24.38.png

示例图2:

截屏2022-03-07 16.25.33.png

示例图3:

截屏2022-03-07 16.28.12.png

下面是原文件包的大小,以及总计用时:

image.png

尝试打开nginx 的gzip 配置:

gzip:on 

示例图1:

image.png

示例图2:

image.png

示例图3:

image.png

当前的文件大小,传输时间:,总计用时:

image.png

开启 nginxgzip 压缩以及gzip 的其他配置

通过打开nginxgzip压缩 和一系列的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:

image.png

示例图2:

image.png

示例图3:

image.png

当前的文件大小,传输时间:,总计用时:

image.png

通过上传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:

image.png

示例图2:

image.png

示例图3:

image.png

示例图4:

image.png

示例图5:

image.png

当前的文件大小,传输时间:,总计用时:

image.png

开启  gzip_static on;

nginx对于静态文件的处理规则,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩。

示例图1:

image.png

示例图2:

image.png

示例图3:

image.png

文件大小:

image.png

开启proxy

示例图1:

image.png

示例图2:

image.png

示例图3:

image.png

示例图4:

image.png

示例图5: image.png

image.png

image.png

文件大小:

image.png

其他细节优化

  • 小图标使用iconfont
  • 小图使用base64
  • 大图压缩再上传
  • js放在页面底部并使用异步加载,不影响html解析
  • css 放在头部,尽快去处理和解析
  • localstorage 本地存储
  • 语义化标签

示例图1:

image.png

示例图2:

image.png

示例图3:

image.png

示例图4:

image.png


优化结果:加载时间从最初的1000ms 到 最后稳定在 400ms-600ms 之间,白屏时间从开始到90ms 到优化后到14ms,一定程度上提高了网站打开速度,降低用户跳出率。

使用 lighthose 测试效果

2421678377142_.pic_hd.jpg

优化seo

  • 合理使用meta 标签,添加标题、关键字、描述等信息
  • 图片添加alt
  • tree-shaking 删除无效内容,包括下载没用到的第三方库或者冗余的图片或代码
  • 使用语义化标签
  • 添加网站外链

2481678698225_.pic.jpg

(后面的优化是非线上环境,至于best practices 为啥会低下来,我也没找到原因,大概率和环境有关吧)


优化到这里,浅浅的算个终点吧,因为这个项目是toB 项目,并不是toC 的,另一方面这个项目的静态内容偏多,整体速度感官还是蛮快的,综合以上两点,所以关于ssr暂且就放弃了,希望在其他项目中可以体验一下ssr 的使用吧