likes
comments
collection
share

首屏加载优化实测——按需加载、分包

作者站长头像
站长
· 阅读数 25

最近做了一个首屏加载优化的工作,一直有听说各种方式,从来没有实际操作过,借这次机会来记录一下优化全过程。

network面板查看资源请求列表

首先打开network面板查看资源请求列表,发现vendor.xxx.js这个文件占大头,3.5MB的大小,且有1s的时间是它独自占用的:

首屏加载优化实测——按需加载、分包

那我们就得去看看这个东西为什么这么大:

下载可视化插件 rollup-plugin-visualizer

npm install rollup-plugin-visualizer --dev

然后在vite.config.ts配置一下

import { visualizer } from "rollup-plugin-visualizer";

export default defineConfig({
  plugins: [
    visualizer({
      emitFile: true,
      filename: "stats.html",
    }),
  ]
})

npm run dev后就会在根目录生成一个stats.html文件,打开发现antdvue组件库的体积占大头:

首屏加载优化实测——按需加载、分包

于是就想着怎么优化组件库的体积;

优化:使用unplugin-vue-components将组件库按需加载

项目目前是在main.ts全局引入的组件库,现在需要将它注释掉,并在vite.config.ts按需引入:

// main.ts

// import Antd from 'ant-design-vue'
// import 'ant-design-vue/dist/antd.less'

import '@/styles/index.less'

plugins: [
    visualizer({
      emitFile: true,
      filename: "stats.html",
    }),
    Components({
      resolvers: [AntDesignVueResolver({
        importStyle: 'less' // 同时引入组件库样式
      })],
      dts: true,
    })
  ],

注意坑位:

以上会导致 antd.lessindex.less引入顺序变化,相关issue:github.com/unplugin/un…

于是我按需导入时不导入样式,手动加载全部样式:

plugins: [
    visualizer({
      emitFile: true,
      filename: "stats.html",
    }),
    Components({
      resolvers: [AntDesignVueResolver()],
      dts: true,
    })
],
// main.ts

// import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.less'

import '@/styles/index.less'

将组件库按需加载后,vendor.xxx.js的体积从3.5MB减少到了3.1MB

首屏加载优化实测——按需加载、分包

但这还远远不够,它还是有很长一段时间在在独自请求,阻塞了页面的渲染,于是采用分包策略,将vendor.xxx.js拆分为多个依赖包:

优化:分包

使用rollupoutput选项对包手动处理:

// vite.config.ts
build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString()
          }
        }
      }
    }
},

这个配置的目的是自动将所有从node_modules目录引入的依赖分割到各自的代码块中。每个依赖库都会被分到一个以库名称命名的单独chunk中。

那它有没有减少包总体积呢? 其实没有

那为什么能优化首屏加载时长呢?因为它可以让多个依赖包异步加载,不再是独占一个时间线了:

首屏加载优化实测——按需加载、分包

从上图中可以看到,比较密集的线段是多个依赖包在异步加载,而占用时间最长的是ant-design-vue.xxx.js这个包,并没有vendor.xxx.js这个文件。

除了可以提供首屏加载速度外,分包的方式,也可以让常用库(如React, Vue等)不会因为应用代码的改变而重新打包,利用浏览器缓存可以提高加载速度。

总结

以上内容就是按需加载分包这两种方式对优化首屏加载时长的实测内容。当然还有其他手段,如Gzip压缩、HTTP/2 的使用、利用 CDN 分发资源、延迟加载非关键资源、预加载关键资源等。

  • Gzip压缩:通过服务器配置,使用Gzip或Brotli等压缩方法可以显著减少传输的数据量,从而加快加载速度和提高性能。

  • HTTP/2:利用HTTP/2多路复用功能,可以在一个连接上并行请求多个文件,减少请求延迟。此外,HTTP/2还支持服务器推送,能够进一步优化资源的加载策略。

  • 利用CDN:通过将静态资源部署到全球的CDN节点,用户可以从最近的服务器获取数据,这样可以显著降低延迟并提高网站的访问速度。

  • 延迟加载非关键资源:对于非首屏显示的图片、视频等大型文件,可以采用延迟加载(Lazy Loading)技术,这样只有在用户滚动到页面的相关部分时,才开始加载这些资源。

  • 预加载关键资源:使用<link rel="preload">标签预加载首屏关键资源,如CSS、JavaScript文件、字体等,可以确保这些资源在HTML文档解析时就已经开始加载,从而减少渲染阻塞时间。

如果后续有机会实操也会补充进来。

转载自:https://juejin.cn/post/7382768099252715520
评论
请登录