fayeah / blogs

方法论、问题驱动、总结
6 stars 0 forks source link

Web Performance 杂谈 #60

Open fayeah opened 2 years ago

fayeah commented 2 years ago

性能的重要性我就不说了,都是老生常谈的话题了。直入主题。

影响性能的两大原因

  1. 资源加载。
  2. 单线程。

两个角度

  1. 客观的度量如加载时间,每秒帧数和到页面可交互的时间。
  2. 用户的对页面内容加载时间的主观感觉。

性能指标

  1. 首字节时间(TTFB)
    • 0-1秒:用户体验最好
    • 1-2秒:用户可以容忍
    • 2-3秒:用户不能容忍
  2. DNS时间
    • 进行域名解析所需要的时间
    • 0-50毫秒 100分
    • 50-500毫秒 一般,可能会影响用户体验,从50毫秒开始,每增加10毫秒则减去2分
    • 500毫秒以上,严重影响⽤用户的网页体验,从50毫秒开始,每增加10毫秒则减去2分
  3. 页面加载时间:从页面开始加载到页面onload事件触发的时间。一般来说onload触发代表着直接通过HTML引用的CSS,JS,图片资源已经完全加载完毕。
  4. TCP时间:客户端建立连接的时间
    • 0-100毫秒 100分
    • 100-500毫秒,一般,可能会影响用户体验,从100毫秒开始,没增加10毫秒,减去1分
    • 500毫秒以上,严重影响⽤用户的网页体验,从100毫秒开始,每增加10毫秒,减去1分
  5. 资源利用率,web服务器的资源利用率:CPU限制 、磁盘I/O限制、应用磁盘限制、CPU占用率等等。
  6. 首次内容绘制:测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。对于该指标,"内容"指的是文本、图像(包括背景图像)、元素或非白色的元素。

    import {getFCP} from 'web-vitals';
    
    // 当 FCP 可用时立即进行测量和记录。
    getFCP(console.log);
  7. 最大内容绘制:会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。
    new PerformanceObserver((entryList) => {
     for (const entry of entryList.getEntries()) {
       console.log('LCP candidate:', entry.startTime, entry);
     }
    }).observe({type: 'largest-contentful-paint', buffered: true});

性能优化手段

  1. TTFB:是web服务响应的测量指标,发出页面请求到接收到应答数据第一个字节所花费的毫秒数。使用CDN,较快的web服务,可靠的DNS提供商能极大减少TTFB的时间。 image

  2. Gzip:(资源从服务器端返回客户端之前的压缩技术) WeChatWorkScreenshot_f651e311-c95e-4b9c-afbe-a615877819e6

  3. HTTP缓存 HTTP 缓存是一种提高负载性能的有效方式,因为它减少了不必要的网络请求。所有浏览器都支持该功能,并且不需要太多设置。缓存API包括:Cache-ControlETagLast-Modified

  4. 使用HTTP2.0:只用于https协议,http协议继续使用HTTP1.0。

  5. 图片:优化图片大小、替换掉矢量图(像logo等较小的图片可用矢量图绘制)。

  6. 请求数量:越多越慢,尽可能减少,使用CSS Sprites等方式。

  7. 提供合适的图片:例如,你上传的图片400px,但它所占用的位置只有300px,通过CSS技术将图片缩小到300px以匹配视觉大小。其实最好的办法是按比例上传图片。

  8. 字体,自定义字体需要额外的HTTP请求,也是会阻塞渲染的。

  9. 硬件:考量因素包括且不限于,CPU、内存利用率、磁盘空间,总的来说,web 服务器要用好的。

  10. CDN :依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。【百度百科】

  11. JS

    • preload/prefetch/lazy load/code splitting
    • preconnect: 允许浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析,TLS 协商,TCP 握手,这消除了往返延迟并为用户节省了时间。 <link href='${url}' rel='preconnect' crossorigin>
  12. CSS,减少重绘

    • 减少CSS规则
    • 减少DOM层级
    • 使用CSS animations,而非JS实现动画效果
  13. 避免301:重定向是性能杀手,会产生额外的RTT(round trip times),使得初始HTHML文档加载时间加倍,尽可能避免。

  14. DB的优化,一般是后端同学来维护,但也需要关注数据库是否有优化的空间。

  15. 优化关键渲染路径:所有可能阻碍页面渲染的资源。

  16. 浏览器从获取 HTML 到最终在屏幕上显示内容需要完成以下步骤:

    1. 处理 HTML 标记并构建 DOM 树。
    2. 处理 CSS 标记并构建 CSSOM 树。
    3. 将 DOM 与 CSSOM 合并成一个 render tree。
    4. 根据渲染树来布局,以计算每个节点的几何信息。
    5. 将各个节点绘制到屏幕上。

CSSOM 会阻塞渲染,只有当 CSSOM 构建完毕后才会进入下一个阶段构建渲染树。

通常情况下 DOM 和 CSSOM 是并行构建的,但是当浏览器遇到一个script标签时,DOM 构建将暂停,直至脚本完成执行。但由于 JavaScript 可以修改 CSSOM,所以需要等 CSSOM 构建完毕后再执行 JS。

  1. 优化关键渲染路径途径:
    • 首屏内容可以优先加载,非首屏内容采用滚动加载。
    • 如果 JavaScript 代码没有 DOM 或者 CSSOM 的操作,则可以改成 sync 或者 defer 属性。
    • 压缩 CSS 和 JavaScript 资源。
    • 移除 HTML、CSS、JavaScript 文件中一些注释内容,treeshaking技术。
    • 通过减少关键资源的个数和减少关键资源的大小搭配来实现。
    • 使用 CDN 来减少每次 RTT 时长。(RTT:往返时延。)
    • 像缓存/预加载/懒加载等技术也属于优化关键渲染路径的手段。
    • 不同框架也有自己的技术实现,e.g. React.Memo等。
  2. 满足业务的情况下尽可能使用新的框架,例如Vue3相比于Vue2的性能提升,提升了1.2 ~ 2 倍.。

Tools

  1. Google performance

  2. React developer tools: Profile performance-react

以上。