美文网首页
后台系统静态资源加载优化实践

后台系统静态资源加载优化实践

作者: 0月 | 来源:发表于2023-02-09 18:38 被阅读0次

前言

因为这系统之前一直在不断迭代,现在暂时告一段落了,我赶紧趁着开年工作不多的空余时间,把这个系统优化一下,不然我可能就被优化了。

优化做啥

说到优化,网上一查一大堆教你的方法,要说的话,人人都能说两句,但是做的话不一定人人都能做好。那么我们该如何运用这些知识呢?

本系统基本情况:

  • 构建工具 vite4
  • 框架 vue3
  • UI组件库 tdesign
  • 公司内部业务组件库 sutpc-charts-utils

要优化,我们首先要知道有没有问题,问题自查的途径有很多,我这里用了浏览器自带的lighthouse,得到初步结果如下

自查结果1.png 自查结果2.png

不同的系统优化关注点不一样,由于我这个系统是一个后台系统,我这里主要关注性能,也就是图中的Performance的得分51的那部分,再一看这几个指标 如 FCP\ TTI \ LCP,一看就知道不太ok了,时间都4、5秒了,再看看网络资源加载方面:


网络.png
响应标头.png

根据经验一看就会发现有的js\css存在体积过大,而且都没有gzip压缩导致加载时间比较长的问题,同时,lighthouse也有对应的诊断,以及对应的改善建议

诊断、改善建议.png

如下图,点开第一条建议,果不其然,是让你开启资源压缩,压缩方法有:gzip,deflate或者brotli,我们用常用的gzip即可,它一般压缩率在70%左右。


第一条建议.png

然后再看看其他优化建议,包括

  • 减少未使用的JavaScript并延迟加载脚本,直到需要它们, 来减少网络活动消耗的字节数
  • 资源正在阻止页面的第一次绘制。考虑内联交付关键JS/CSS,并推迟所有非关键JS/样式
  • 减少未使用的css
  • 使用http2代替目前的http1.1
  • 使用高效的缓存策略为静态资产提供服务
  • 避免昂贵的dom操作

还有一些其他小建议就不一 一列举了

由于本系统的资源都在同一个域名(IP)下,且http协议是1.1版本, 所以会有最多6个TCP连接同时创建的限制。其实最好的办法还是上http2, 但是这又要先上https证书才行,考虑到这系统公司暂时不可能花钱搞这个证书,所以http2的想法就算了。

最后,根据现有问题、优化建议和实际情况,我打算做 代码瘦身、打包时的代码分割、gzip压缩、设置合适的缓存策略

具体操作:
1、移除未使用的插件,检查代码发现有一些插件如vue3-lazy vue3-clipboard没用到,删掉
2、配置代码分割
vite默认node_modules的非公用依赖全给你打到一个vendor.js里面去,导致的问题就是太大加载慢,所以需要分割,方便并行加载。方法就是自定义打包策略,如下例子,把非源码的依赖单独提取出来,再配合强缓存策略。

build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'sutpc-charts-utils': ['sutpc-charts-utils'],
            'vue-vendor': ['vue', 'vue-router', 'pinia'],
            tdesign: ['tdesign-vue-next'],
          }
        }
      }
    },
分割前.png 分割后.png

看出来,优化前后主要变化是一个3366kb的chunk变成 两个, 分别是1037kb \ 2464kb , 在依赖不多的情况下,优化效果不大,至于其他的小chunk块变化不大。

3、配置gzip
让运维帮忙配置一下nginx,开启gzip

    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1024;
    gzip_buffers     4 16k;
    gzip_vary on;
    gzip_comp_level 5;
    gzip_static on;
    gzip_types text/plain text/css   application/json application/javascript

然后测试一下发现个问题,如下图


gzip开启的问题.png

好家伙!资源加载更慢了!如下图,随便点开某个请求一看原来是服务器响应慢,可能是啥原因呢?

耗时.png

是服务端自己的问题,仔细看了一下nginx配置找到了问题 :gzip_comp_level 5

改一下nginx配置, 把 gzip_comp_level 5改成 gzip_comp_level 2,因为level越高越占用cpu资源,现在改低应该可以把服务响应耗时短一点

    gzip_comp_level 2;
gzip_comp_level 2.png

看起来 “请求-响应” 时间确实从平均1.3s 降低到 700ms左右,约有4、50%的提升

优化完了,重新从lighthouse测试看一下成果


优化后1.png 优化后2.png

从效果上来看,Performance从51 到 78分,几个相关指标时间也进入了2s左右,感觉效果还行。

能不能再快点?

从上面的几个关键资源加载情况来看,基本都要700ms左右,能不能再快点的?其实是可以的。因为上面的nginx的gzip设置都是实时压缩的,就是说每次请求资源,服务器都要把该文件压缩完再返回,这里是存在浪费时间的,由于这些静态资源每次打包生成之后就不会变化了,我们可以直接把它压缩好,这样子请求时直接把压缩好的资源返回就行了,省去每次请求都去压缩的时间开销,网络io就会更快!怎么做呢?装个压缩插件即可。

pnpm i vite-plugin-compression2 -D

vite.config.js配置

import { compression } from 'vite-plugin-compression2'

    plugins: [
       ...其他插件
      compression({
        threshold: 1024,
        include: [/\.css$/, /\.js$/]
      })
    ],

上面配置对只对打包后大于1k的css、 js压缩,发现会多了一份后缀名是.gz的文件,然后把dist目录部署到服务上,nginx响应这些资源请求时会直接把对应.gz的文件返回。


压缩.png gzip压缩后.png 指标得分.png

重新部署查看网络瀑布流,发现从请求耗时从700ms降低到100ms左右,提速明显,但是lighthouse重新测试发现 FCP \ LCP \ SI 指标得分并没有提升多少,Performance总得分也还是70多,这就奇怪了,从官方的建议来看,现在应该是GOOD阶段范围了

LCP scope.png
点击LCP指标下方的“查看原始追踪记录”按钮,进去查看: 原始追踪记录.png

从图中可以看到LCP也就在1.2s左右的位置,哪里是lighthouse写的2.2s ? 不知道它是怎么算的,你知道吗?欢迎留言讨论。

4、 静态资源设置强缓存、协商缓存
在我另外一篇文章《彻底弄懂强缓存与协商缓存》说过缓存的原理,这里直接用上结论:index.html设置协商缓存,其他的设置强缓存。由于我这环境的nginx默认是有协商缓存的,所以我只配置需要强缓存的资源,如下,js|css|png|jpg 等资源强缓存30天,即2628000秒

location ~.*\.(js|css|png|jpg)$ {
    add_header Cache-Control "max-age=2628000, private";
}

设置这些缓存只是对二次打开页面有用,对第一次打开测试效果没意义。截止目前来看最大的问题还是代码问题,如下最新的测试结果,查看优化建议如下图所示只剩下 3条建议

  1. 减少未使用的js\css
  2. 考虑内联脚本样式
  3. 推迟所有非关键js\css


    剩下建议.png

    5、增大代码覆盖率
    其实要减少未使用的代码,我们得先了解一个概念:代码有个指标是代码覆盖率;代码覆盖率 = 使用的部分 / 全部;代码覆盖率越大说明你的代码用到的刀刃上的越多,而不是下载一大堆,只用一小部分功能。比如你引入了整个loadsh,只用到了深拷贝功能,其他没用到的功能代码也被打包部署,导致用户请求资源时浪费带宽,浪费时间,阻塞渲染。


    view Treemap.png
    代码覆盖率.png

根据上图的代码覆盖率来看,图中底部的表格中Coverage列里面的柱子,其中红色的部分表示是未使用的,所以我这里还是需要继续代码瘦身,把不用到的部分剔除。而且大头是前面两个js,体积大,而未使用部分又占比大。根据上文列举的剩下的3条优化建议,内联脚本样式不太现实,所以按照建议去

  1. 减少未使用的js\css
  2. 推迟所有非关键js\css

我的具体做法就是 把在main.ts全量引入sutpc-charts-utils这个组件库的代码删掉,改成在局部页面去按需引入具体的组件、配合defineAsyncComponent异步组件实现按需加载,也就实现了“减少未使用的js\css、推迟所有非关键js\css”

main.ts变化.png

局部页面异步方式按需引入MatrixEditor组件的例子

const MatrixEditor = defineAsyncComponent(() => import('sutpc-charts-utils/dist/matrix-editor').then(({MatrixEditor}) => MatrixEditor))
import 'sutpc-charts-utils/dist/matrix-editor/style.css';

export default defineComponent({
  render(){
    return <div>
      <MatrixEditor />
    </div>
  }
})

再次打包,发现原来最大的chunk: sutpc-charts-utils-[hash].js没了, 多了几个几百k的js,因为这些独立组件本来就比较大。至于tdesign-[hash].js暂时不变,没改按需引入。

按需引入后打包.png
最后再部署测试一次 , Performance 90+分,FCP \ SI \ LCP \ TTI 几乎进入秒级!
最后测试结果.png

总结

本次优化主要是通过移除未使用的代码、代码分割、gzip压缩设置、按需引入等手段,降低了首屏资源请求时的“请求-响应”时间,从而达到资源加载优化的目的。

相关文章

  • NGINX优化

    Nginx性能优化实践 1.性能优化概述 2.系统性能优化 3.代理服务优化 4.静态资源优化 4.1 静态资源缓...

  • 浅谈前端js面试--运行环境(性能优化)

    优化策略 多使用内存、缓存或其他方法 减少CPU计算、减少网络 入手 加载页面和静态资源 页面渲染 加载资源优化 ...

  • 性能优化

    优化的思路 加载的优化体验的优化 加载的优化 网络越快越好(服务器网速要好,接口要多,静态资源放cdn,在不同地区...

  • 页面性能优化

    加载资源优化 1,静态资源的压缩合并,减少HTTP请求 资源的合并,可以减少http请求数量。资源的压缩,可以减少...

  • 系统优化!! 吞吐量??

    一、jvm 堆内存大小 (减少full gc) 二、静态资源分离将静态资源数据加载至nginx或者其他服务提升系统...

  • selenuim和phantonJs处理网页动态加载数据的爬取

    一.图片懒加载 什么是图片懒加载? 图片懒加载是一种网页优化技术。图片作为一种网络资源,在被请求时也与普通静态资源...

  • 加载资源

    @(javascript)[页面xrr] 加载资源 加载资源的形式 输入url(或跳转页面)加载html 加载静态...

  • SPA优化

    常见的几种SPA优化方式: 减小入口文件体积(路由懒加载) 静态资源本地缓存(缓存,PWA:Service Wor...

  • 前端性能优化:静态资源加载与优化

    css和js的装载与执行-HTML 页面加载渲染的过程 一个网站在浏览器端是如何进行渲染的呢? HTML渲染过程的...

  • 简单性能优化思路

    原则 减少 CPU 的运算、减少网络的使用、多使用内存、多使用缓存及其他方法。 加载资源优化静态资源的压索合并多个...

网友评论

      本文标题:后台系统静态资源加载优化实践

      本文链接:https://www.haomeiwen.com/subject/xobqkdtx.html