前端性能优化思路

143 阅读3分钟

前端性能优化思路

一、网络性能优化

1、网络请求个数优化

a)异步引用资源
i).vue文件中
defineAsyncComponent(() => import("vue文件地址"))
ii).js/.ts文件中
  • import()异步加载
  • 2、import.meta.glob("地址",{eager:false})
  • 3、vue-router中的component自带defineAsyncComponent解析功能,可以直接传入import()
b) 异步插入
i)插入script:通过onMounted调用函数,函数中判断当前script中是否存在指定资源的url,存在则不请求,不存在则动态插入script
ii)插入link css:与插入script相同
c)文件优化
i)上传功能优化
  • 上传队列控制
/**
 * @class QueueLoader
 * @classdesc 图片加载队列
 */
export class QueueLoader {
  // 私有静态实例,用于实现单例模式
  private static instance: QueueLoader;

  // 任务队列,存储回调函数
  private taskQueue: Array<() => Promise<boolean>> = [];

  // 当前活跃任务数
  private activeTasks: number = 0;

  // 最大并发请求数
  private maxConcurrentRequests: number = 4;

  // 私有构造函数,防止实例化
  private constructor() {}

  /**
   * 获取单例实例的方法
   * @returns {QueueLoader} 单例的 QueueLoader 实例
   */
  public static getInstance(): QueueLoader {
    if (!QueueLoader.instance) {
      QueueLoader.instance = new QueueLoader();
    }
    return QueueLoader.instance;
  }

  /**
   * 向任务队列添加任务
   * @param {() => Promise<boolean>} callback - 包含回调函数的任务
   * @returns {void}
   */
  public addTask(callback: () => Promise<boolean>): void {
    this.taskQueue.push(callback);
    this.runTasks();
  }

  /**
   * 执行任务队列中的任务
   * @returns {Promise<void>} 返回一个表示任务执行完成的 Promise
   */
  private async runTasks(): Promise<void> {
    while (this.activeTasks < this.maxConcurrentRequests && this.taskQueue.length > 0) {
      const task = this.taskQueue.shift()!;
      this.activeTasks++;
      const result = await task();
      this.activeTasks--;
      if (result) {
        this.runTasks();
      }
    }
  }
}

  • 文件切片上传 eg:参考广告机 加载功能优化 1、预加载 a)通过link preload预加载文件

b)通过script async/defer独立下载文档和解析

<script async></script>
<script defer></script>

c)通过symbol处理icon的复用和可维护

<svg aria-hidden="true" style="position: absolute; width: 0px; height: 0px; overflow: hidden;">
<symbol id="icon-keliu" viewBox="0 0 1024 1024">
<path d=""></path>
</symbol></svg>

d)在内容快要出现在浏览器窗口中时预先加载src资源 2、懒加载 a)当内容出现在浏览器窗口时才加载资源 eg:

<img loading="eager" /> <!-- 立即加载 -->
<img loading="lazy" /> <!-- 懒加载 -->

2、网络请求资源大小优化 d)分包

// 控制node_modules分包    
manualChunks(id: string | string[]) {
    if (id.indexOf("node_modules") != -1) {
      return id.toString().split("node_modules/")[1].split("/")[0].toString();
    }
}
//控制src目录下的资源分包
chunkFileNames: (chunkInfo) => {
    if (chunkInfo.facadeModuleId?.indexOf("src") != -1) {
          return "assets/[name]-[hash].js";
    }
    return "[name]-[hash].js";
}
// 控制资源名称和目录
assetFileNames: (chunkInfo:any)=> {
	return '[name]-[hash].[ext]'
}

e)切片 使用ajax请求+ArrayBuffer加载大文件显示 i)文件上传切片 一般用于上传文件 ii)文件加载切片 一般用于加载大文件,例如:Threejs加载大模型控制加载队列 3、首页优化 f)index.html中不写script立即加载请求 g)加载动效 h)减少请求个数,参照1、网络请求个数优化 i)网络请求资源大小优化,参照2 4、页面加载和性能 j)watch监听过多/切换页面未卸载 5、GZIP/Brotli压缩优化

vitePluginCompress({
		verbose: true, //是否开启gzip压缩
		disable: false,
		deleteOriginFile: false,
		threshold: maxSplitFile,
		algorithm: "gzip",
		ext: ".gz",
})

二、打包性能优化思路

1、src目录打包分包

2、node_modules打包分包

三、排查优化思路

加载需要优化的重点:

- 页面加载时长:超过1秒
- 网络请求文件时间:超过1秒
- 网络请求个数:列表页超过15个、首页超过20个【非绝对指标,具体看页面功能】
- CPU使用情况长时间占用
- 页面切换后JSdom和堆长时间未卸载
    - 警告过多/错误未处理
    - 初次加载/每一次切换tab和页面都有多个相同请求

1、搜集每个页面/弹窗的情况和统计,针对情况进行优化

a)统计页面网络请求个数、请求资源大小、过大文件请求时长、总渲染时间和加载时间

b)统计哪些页面的按钮没有使用loading,导致用户可以频繁点击

c)相同网络请求可以重复频繁发送

2、排查【1】中每个指标哪些可以优化,特别标记页面以及对应的功能

3、排查方法

chrome检查 -> 网络
chrome检查->更多->性能监视器