前端性能优化方案

855 阅读4分钟

背景

随着项目的迭代开发,页面的loading时间,访问白屏等待时间,speedIndex,TTL,FCP...各种指标推进着我们优化前端项目的脚步。

如果有用户在反馈我们网站卡,迟钝, 那是时候优化我们的代码了!

工具

我们要优化一个网站的性能,首先需要学会如何衡量一个网站的性能。

1.lighthouse

Lighthouse 是一个开源的自动化工具,用于改进网络应用的质量。 您可以将其作为一个 Chrome 扩展程序运行,或从命令行运行。 您为 Lighthouse 提供一个您要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告。

我们常用的网页性能分析指标,在lighthouse中基本都可以拿到。

image.png

点击生成报告👇👇👇👇。看下chrome的友好提示

image.png

image.png

(按这个提示,是不是优化一下就能赚好多钱钱~)

我们看一下执行的结果:

image.png

掘金的性能分是:83分。。还好。 还有一些指标,看下这些指标是什么意思:

指标解释
First Contentful Paint首次内容渲染时间标记了渲染出首个文本或首张图片的时间。了解详情
Time to Interactive可交互时间是指网页需要多长时间才能提供完整交互功能。了解详情
Speed Index(重要)速度指数表明了网页内容的可见填充速度。了解详情
Total Blocking Time首次内容渲染 (FCP) 和可交互时间之间的所有时间段的总和,当任务用时超过 50 毫秒时,该数值以毫秒表示。了解详情
Largest Contentful Paint标记了渲染出最大文本或图片的时间。了解详情
Cumulative Layout Shift“累积布局偏移”旨在衡量可见元素在视口内的移动情况。了解详情

下面有一些优化的建议:

image.png

2.webpagetest

“WebPage Test 测量真实浏览器中的 Web 性能指标,具有高度可编程性,并且可以扩展到每天测试数百万个站点。”

填写完要测试的网站,如下配置就行,记得选china节点,tencent的节点太火爆了一直有排队的,等不及可以试试别的china节点,不登陆也会保存你的测试结果 image.png

3.webpack-bundle-analyzer

webpack-bundle-analyzer是webpack包分析的神器插件,安装 webpack-bundle-analyzer 插件,打包后会生产一个本地服务,清楚的展示打包文件的包含关系和大小。

install之后,配置下package.json

"report": "vue-cli-service build --report"

执行npm run report,包里面有个report.html,打开是这样的:

image.png

可以看到,和我们的包文件是对应的,能看到分包后包的大小,我们可以针对对应包做优化处理。

优化方案

准备好工具,就可以开始优化了----和医院开完检查单,去做完检查一样。。。我们拿着单子去分析是不是优化的更准确一些。

1. 看下未优化前的项目包情况:

1)JS部分: image.png

  • 可以看到,项目中echarts,elementui,xlsx,threejs是我们占包的主要对手。stat size 在2M以上~ 处理方法采用了externals, 可以看下这篇文章:juejin.cn/post/700113…

    主要提取node_modules中echarts xlsx的包, 改为cdn方式,cdn这里我采用了静态资源:

    vue.config.js  configureWebpack下
    externals: {
        echarts: 'echarts',
        xlsx: 'XLSX'
    }
    
    index.html
    <script type="text/javascript" src="<%=BASE_URL%>static/js/echarts@5.3.2.min.js"></script>
    <script type="text/javascript" src="<%=BASE_URL%>static/js/xlsx.core.min.js"></script>
    
  • threejs 好久就从项目中拿掉了,不用了,删掉就好。资源中不用的包也剔除掉了。~

  • 分包:splitChunks(减少单包大小,之前优化过的。这里就看到的分包好的chunks)

config
    .optimization.splitChunks({
      chunks: 'all',
      cacheGroups: {
        libs: {
          name: 'chunk-libs',
          test: /[\\/]node_modules[\\/]/,
          priority: 10,
          chunks: 'initial' // only package third parties that are initially dependent
        },
        elementUI: {
          name: 'chunk-elementUI', // split elementUI into a single package
          priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
          test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
        },
        commons: {
          name: 'chunk-commons',
          test: resolve('src/components'), // can customize your rules
          minChunks: 3, //  minimum common number
          priority: 5,
          reuseExistingChunk: true
        }
      }
    })
  • 开启GZIP压缩

    vue.config.js  configureWebpack下
    
     plugins: [
       new CompressionWebpackPlugin({
         filename: '[path].gz[query]',
         algorithm: 'gzip',
         test: new RegExp('.(' + productionGzipExtensions.join('|') + ')$'),
         threshold: 10240,
         minRatio: 0.8
       })
     ]
    

    压缩后打包结果这样的,可以看到,2.2M的压缩完为0.68M,效果还是很理想的。

image.png

记得配置nginx.conf,打开gzip压缩。部署完之后去看看线上的是不是压缩完的包 👇👇👇

http {}


  #gzip  on;
  gzip on;
  gzip_min_length 1k;
  gzip_buffers 4 16k;
  #gzip_http_version 1.0;
  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 off;
  gzip_disable "MSIE [1-6].";

这里是怎么看是压缩gzip的资源

image.png

2)CSS部分

先看看优化前的包

image.png

有个1.4M的包,发现是有张bg的大图在assets里面

把他提取到静态资源static中,压缩后包大小如下👇 image.png

优化结果

1.优化前

lighthouse跑分

image.png

image.png

2.优化后

lighthouse跑分

image.png

image.png