中后台想做好很难的……

2,860 阅读5分钟

被批

中后台想做好很难的……这么多年了技术水平涨没涨,有没有在认真工作?

你以为就表单表格列出来就完事了吗?

后端一页数据返回得多,就是它卡的理由吗?表单多就是它卡的理由吗?

“回去好好研究,解决不了不用回来了!!!”

思绪

“唉“

性能优化是一个永恒的话题啊。

做得再牛再好,一旦卡顿延迟,都会倒人胃口。

随着前端需求复杂度的不断升高,在项目中想始终保持着良好的性能,是一个有挑战的事情。


功课

当你点按钮或输入文字时,网页反应越快越好。理想情况是每次操作后,网页能在16.6毫秒内完成处理(相当于人眼看到的60帧动画的速度)。如果处理时间太长,用户就会觉得卡顿。

通过优化,让网页处理用户操作的速度变快了。用专业工具测量发现,优化后每帧画面的计算时间缩短了。这种流畅度直接影响用户体验,专业术语叫inp指标——反应越快的网页,这个指标就越好。

就像玩游戏要60帧才流畅,网页操作也要快速响应,用户才会觉得顺手不卡。


注释:Interaction to Next Paint(inp),是衡量网页交互性能的指标。用户与网页,交互后,浏览器完成下一次屏幕绘制,所需要的时间。

影响因素:
输入延迟:用户交互浏览器处理事件之间的时间
处理时间:事件回调运行所需的时间
呈现延迟:浏览器绘制新内容所需的时间

优化:
减少输入延迟:优化主线程任务,避免阻塞。
优化事件回调:简化回调逻辑,使用requestAnimationFramesetTimeout分散任务,避免长时间运行的任务。
缩短呈现延迟减少DOM大小,使用content-visibility延迟渲染非关键元素。

评估:
:INP ≤ 200毫秒。
要优化200毫秒 < INP ≤ 500毫秒。
:INP > 500毫秒。

测的工具:
Lighthouse:通过Chrome DevTools生成性能报告,包含INP值,下载好谷歌插件后,直接生成报告即可。 Web Vitals:动态测量INP,便于代码中监控,create-react-app中就看到有web-vitals的身影。

Lighthouse

image.png

image.png

几种优化建议,提升性能:

  1. 减少未使用的 JS 和 CSS: 使用代码分割和按需加载技术;删除无用的 CSS 和 JS 文件。
  2. 启用文本压缩:配置服务器支持 gzip 或 Brotli 压缩。
  3. 优化图片加载:使用下一代图片格式(如 WebP);启用懒加载(Lazy Loading)。
  4. 消除渲染阻塞资源:将关键 CSS 内联到 HTML 中;为非关键资源添加 async 或 defer 属性。
  5. 优化服务器响应时间:使用 CDN 缓存静态资源,减少重定向请求。

Web Vitals

通过npm包的形式用:

import {getLCP, getFID, getCLS} from 'web-vitals';
getLCP(console.log);
getFID(console.log);
getCLS(console.log);

通过安装谷歌插件:

image.png

通过cdn插入代码

<script>
  (function() {
    var script = document.createElement('script');
    script.src = 'https://unpkg.com/web-vitals';
    script.onload = function() {
      // When loading `web-vitals` using a classic script, all the public
      // methods can be found on the `webVitals` global namespace.
      webVitals.getCLS(console.log);
      webVitals.getFID(console.log);
      webVitals.getLCP(console.log);
    }
    document.head.appendChild(script);
  }())
</script>

网页性能指标报告注意事项整理

  1. 某些情况不会报告具体指标

    • FID(首次输入延迟):如果用户从未与页面交互(如点击、输入等),就不会报告。
    • FCP、FID、LCP:如果是**服务端渲染(SSR)**的页面,这些指标可能不会被记录。
  2. 部分指标的特殊情况

    • CLS(累积布局偏移)
      • 当页面从可见(visible)变成隐藏(hidden)时(如切换标签页、最小化窗口),浏览器会计算并报告 CLS。
      • 使用浏览器前进/后退导航时,可能会报告 CLS、FCP、FID、LCP
  3. 指标报告规则

    • 每次发生影响性能的变化时(如布局偏移、新内容加载),浏览器都会重新计算并报告最新值,而不是只记录第一次的数据。

也就是说

  • 不是所有指标在所有情况下都会上报,比如用户不操作就不会有 FIDSSR 页面可能缺失部分数据。
  • CLS 比较特殊,会在页面隐藏或前进/后退时计算。
  • 这些指标是动态更新的,每次变化都会重新计算并上报。

流程图解

image.png [上图:展示了:用户操作(如点击)到屏幕更新(渲染完成)的完整流程]

1. Blocking Tasks(阻塞任务)

这些是浏览器主线程必须按顺序执行的任务,如果某个任务耗时过长,就会导致卡顿:

  • Input received
    浏览器接收到用户输入(如鼠标点击、键盘输入)。
  • pointerup / mouseup / click
    触发的具体事件(指针抬起、鼠标抬起、点击事件)。这些事件可能伴随 JavaScript 事件监听器的处理。
  • Render
    浏览器计算页面布局和样式(重排 Reflow / 重绘 Repaint)。
  • Paint
    将渲染结果生成像素数据(光栅化)。
  • Frame presented!
    最终帧提交给 GPU 显示到屏幕上。

关键点:如果 RenderPaint 阶段耗时超过 16.6ms(60Hz 屏幕的单帧时间),用户会感知到卡顿。


2. Input Delay(输入延迟)

用户操作到屏幕更新的总延迟,可拆解为两部分:

  • Processing time
    • 主线程处理输入事件、执行 JavaScript、完成渲染的耗时。
    • 如果主线程被长任务(Long Tasks)阻塞(如复杂计算),会导致延迟增加。
  • Presentation delay
    • 浏览器将渲染结果提交给 GPU 并显示到屏幕的时间。
    • 受 GPU 负载、合成(Compositing)效率影响。

3. Compositing, GPU, and Raster(合成、GPU 与光栅化)

这是渲染管线的后端阶段:

  • Compositing(合成)
    浏览器将页面分层(Layers)并合并,交由 GPU 处理。优化手段:减少层数、使用 will-change 提示。
  • GPU
    负责最终画面的绘制。性能瓶颈:显存不足、复杂特效(如模糊滤镜)。
  • Raster(光栅化)
    将矢量元素(如 CSS 形状)转换为屏幕像素。大尺寸或复杂元素会增加耗时。

总说

好写,很多可二开;

难写,重难点;

要优化,分析、优化、细分,逐个击破。