Skip to content

性能优化


一、加载性能优化

  1. 代码分割与懒加载

    • 原理:利用 Webpack 动态导入 (import()) 或框架路由懒加载(如 React.lazy、Vue 异步组件)。 【把代码分离到不同的bundle中,然后按需加载或并行加载文件 用于获取更小的bundle,控制资源加载优先级 ● 入口起点:使用 entry 配置手动地分离代码。 ○ 如果入口 chunk 之间包含一些重复的模块,那些重复模块都会被引入到各个 bundle 中。 ○ 这种方法不够灵活,并且不能动态地将核心应用程序逻辑中的代码拆分出来。 ● 防止重复:使用 Entry dependencies 或者 SplitChunksPlugin 去重和分离 chunk。 ● 动态导入:通过模块的内联函数调用来分离代码。动态导入一个模块时,模块会分离到一个单独的bundle 】
    • 场景:例如首页仅加载首屏模块,其他详情页通过路由懒加载拆分,降低首屏体积。
    • 效果:首屏加载时间从 3s → 1.5s,FCP(首次内容渲染)提升 40%。
  2. 资源压缩与 CDN 加速

    • 实践:使用 Webpack 的 Terser 压缩 JS,imagemin 压缩图片,CSS 提取为独立文件并压缩 使用到webpack的打包优化,参考webpack优化的文章 TODO 减少请求数、减小请求资源体积、提升网络传输速率 压缩html,js,css 服务器上开启Gzip传输压缩(比如 vue打包后支持压缩体积,nginx可以开启gzip传输),它能将我们的文本类文件体积压缩至原先的四分之一 有时候ui提供的字体资源文件过大,高达几M,这时可以结合字体属性,使用字体分包,将字体文件分成按需加载的小份包,技术内幕【https://chinese-font.netlify.app/post/font_split_turbo/】

      nginx开启gzip,来压缩文本资源(HTML/CSS/JS),可以减少传输体积

    • 场景:官网项目静态资源非常多包括字体文件,图片等,静态资源上传至 CDN(如阿里云 OSS),通过 dns-prefetch 预解析域名。

    • 指标:资源体积减少 60%,CDN 加速后全球访问延迟降低 30%。

  3. HTTP/2 与预加载

    • 策略:开启 HTTP/2 多路复用(和HTTP/1的区别和现象,nginx开启多路复用),使用 preload 加载关键字体/CSS,preconnect 预连接第三方域名。 详细可以查看nginx优化配置 ● preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源; ● prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源。预测会加载指定资源,如在我们的场景中,我们在页面加载后会初始化首屏组件,当用户滚动页面时,会拉取第二屏的组件,若能预测用户行为,则可以 prefetch 下一屏的组件。
    • 案例:新闻网站预加载首屏文章字体,避免 FOIT(字体未加载时的空白)。vue框架中是怎么做预加载preload
  4. index.html中可以指定独立脚本文件

  5. 路由中可以设置路由懒加载

  6. webpack配置哪些资源可以预加载或者懒加载(默认的配置可能会造成一些资源浪费,比如默认开启prefetch,而prefetch会加载将来可能不会使用到的资源,造成开屏很慢,如果你的应用很大且有很多 async chunk,而用户主要使用的是对带宽较敏感的移动端,那么你可能需要关掉 prefetch 链接并手动选择要提前获取的代码区块。) vue打包后js脚本默认为defer,原因如下:

  7. 优化加载性能:defer 可以让 JavaScript 文件异步加载,避免脚本阻塞页面的渲染。Vue 使用 Webpack 或 Vite 等构建工具打包时,会自动在打包后的 index.html 中为 JavaScript 文件添加 defer 属性,以提高页面加载性能。

  8. 避免阻塞渲染:如果没有 defer,浏览器会阻塞渲染,直到所有的脚本都下载并执行完毕,这会导致页面的首次渲染时间变长。使用 defer 可以确保页面渲染不会因为 JavaScript 文件的加载而延迟。

  9. 提高用户体验:通过延迟 JavaScript 的执行,Vue 可以更快地呈现页面的内容,用户可以更早看到页面的结构和样式,尽管某些动态行为(如交互)会稍后加载。


二、渲染性能优化

  1. 减少重排与重绘

    • 技巧:使用 transform 替代 top/left 实现动画,通过 will-change 提示浏览器优化。 技巧补充(在css方面的优化):
      1. 图片在渲染前指定大小:因为img元素是内联元素,所以在加载图片后会改变宽高,严重的情况会导致整个页面重排,所以最好在渲染前就指定其大小
      2. 多使用伪元素
      3. 字体图标? 考点:重排和重绘的区别 重绘和重排 重排是由CPU处理的,而重绘是由GPU处理的,CPU的处理效率远不及GPU,并且重排一定会引发重绘,而重绘不一定会引发重排。所以在性能优化工作中,我们更应当着重减少重排的发生。
    • 场景:轮播图动画使用 transform: translateX(),避免频繁触发重排。
    • 工具:Chrome DevTools 的 Performance 面板分析渲染耗时。
  2. 虚拟列表 (Virtual List)

    • 原理:仅渲染可视区域内的列表项(如 react-windowvue-virtual-scroller)。
    • 场景:后台管理系统渲染 10,000 条数据时,DOM 节点从 10k → 20 个,内存占用减少 80%,遇到系统崩溃的情况,交易管理系统每个层级的数据级多达到千级甚至万级,比如账户级
  3. 防抖与节流

    • 应用:搜索框输入使用防抖(300ms 延迟请求),滚动事件监听使用节流。
    • 代码
      javascript
      const debounceSearch = _.debounce(() => fetchData(keyword), 300);
      input.addEventListener('input', debounceSearch);

三、缓存策略

  1. 强缓存与协商缓存

    • 配置:Nginx 设置 Cache-Control: max-age=31536000(JS/CSS 强缓存),Etag 验证文件变更。
    • 效果:重复访问页面时,90% 的静态资源命中缓存,减少服务器压力。
  2. Service Worker 离线缓存

    • 实现:使用 Workbox 预缓存关键资源,实现离线访问(PWA 应用)。
    • 场景:资讯类 App 离线缓存最新 10 篇文章,提升弱网用户体验。

四、框架级优化

  1. React 优化

    • MemoizationReact.memo 缓存组件,useMemo/useCallback 避免重复计算。
    • 场景:表格组件在 props 未变化时跳过渲染,性能提升 50%。
  2. Vue 优化

    • v-once:静态内容标记 v-once,避免重复编译。
    • Object.freeze:冻结大数据列表,避免 Vue 响应式劫持。

五、监控与分析

  1. 性能指标
    • Core Web Vitals:优化 LCP(最大内容渲染时间)、CLS(累积布局偏移)、FID(首次输入延迟)。
    • 工具:Lighthouse 评分从 60 → 85,使用 PerformanceObserver 监控真实用户数据。

关于性能指标的补充:可参考https://web.dev/articles/vitals?hl=zh-cn#其他-web-指标,有非常详细的研究,时效性也很强 一般关注这三个特性:加载速度、互动性和视觉稳定性 Largest Contentful Paint (LCP):衡量加载性能。为了提供良好的用户体验,应在网页首次开始加载的 2.5 秒内完成 LCP。 Interaction to Next Paint (INP):衡量互动性。为了提供良好的用户体验,网页的 INP 应不超过 200 毫秒。 Cumulative Layout Shift (CLS):衡量视觉稳定性。为了提供良好的用户体验,网页的 CLS 应保持在 0.1 或更低。

FP(First Paint)是 Web 性能监测指标之一,指的是页面的首次渲染时间,即浏览器首次将任何内容渲染到屏幕上的时间点。FP 是用户感知页面加载速度的第一个关键指标,通常用来评估页面的加载速度和用户体验。 FCP:首次内容绘制,浏览器首次绘制DOM的时间,这是用户第一次看到的内容。最佳用户体验的FCP建议在2秒以内,如果超过4秒则表示页面首次内容绘制很慢。(哪些调整会影响该指标) 案例分析:https://juejin.cn/post/7208451786964598841

  1. 代码拆分分析
    • 工具Webpack Bundle Analyzer 分析产物,合并重复依赖(如 lodash 按需引入)。

这里补充一个点 开发过程中的性能优化

  1. 构建优化,omp模块化构建优化的例子
  2. 框架升级

高频面试问题

  1. Q:如何从 6s 降到 2s 的首屏加载时间?

    • A:分析关键路径 → 压缩首屏资源 → 懒加载非关键组件 → CDN 加速 → 服务端渲染(SSR)。
  2. Q:优化无限滚动列表卡顿?

    • A:虚拟列表 + 骨架屏占位 + 防抖加载数据。
  3. Q:如何减少白屏时间?

    • A:SSR 服务端渲染 + 内联关键 CSS + 预加载字体。