全面解析:系统化的页面性能优化指南

152 阅读13分钟

页面性能优化是一个系统性工程,涵盖了从 URL 输入到页面渲染完成的各个环节。通过从 DNS 解析、TCP 连接、网络传输、服务器响应、到页面渲染等多方面的优化,可以显著提升页面的加载速度。更重要的是要建立完整性能监控体系,才能持续发现和改进性能瓶颈,为用户带来更好的体验。

目录

  1. 发现问题
  2. 分析
    • DNS 解析
    • 资源加载
      • 关键资源
      • 网络宽带限制
      • 利用好 CDN
      • 服务端响应
    • 页面渲染卡顿
      • 查找耗时任务
      • 解决长任务
      • 处理老代码
    • 优化原则
      • 加载阶段
      • 交互阶段
    • 优化思路
  3. 解决
    • 如何系统性进行性能优化?
    • 如何持久化地保持系统性能优化?
    • 性能优化常用工具
      • 公司内部监控平台
      • Chrome DevTools — Lighthouse
      • Chrome DevTools — Performance
      • WebPageTest
      • PageSpeed Insights
      • SpeedCurve

一、发现问题

用户是页面性能的最终体验者,因此,用户反馈是发现性能问题的重要途径之一。当用户体验到页面加载缓慢、交互卡顿等问题时,这会直接影响用户的使用满意度,甚至会导致流失。

  • 常见反馈
    • 页面加载时间过长。
    • 页面滚动不流畅,卡顿明显。
    • 点击按钮后,响应时间过长。
    • 图片或视频资源加载缓慢。

二、分析

页面性能优化是一个系统工程,涵盖从用户输入 URL 到页面完整展示的所有步骤。要想系统性地提升页面性能,首先需要了解整个流程的关键环节,主要包括 DNS 解析、TCP 建立连接、服务器响应、网络传输和页面渲染,分析各阶段影响性能的因素,然后逐步优化每个阶段。此过程会涉及很多的点和面,下面我们一一解析。

1. DNS 如何解析?

当需要发送请求时,首先需要将 URL 中的域名转换为 IP 地址,这涉及到 DNS 解析 过程,如下:

image.png

DNS 解析时间若比较长,会出现网络延迟,通常的优化手段有域名预解析dns-prefetch、启用 DNS 缓存、域名加速等

需要注意的是,对于 URL 的解析,热启动(即二次打开),浏览器首先会查找本地缓存,看是否存在该 URL 对应的资源。若存在且缓存未过期,浏览器直接从缓存中读取资源,跳过后续步骤。

2. 资源加载为何会一直 loading ?

页面的静态资源加载一直处于加载中(loading)的状态,通常是由多个因素引起的。网络带宽限制、DNS解析时间过长、第三方资源服务的响应缓慢、性能监控SDK上报不当,抢占大量的请求资源等,这些都会影响到页面资源的加载。

造成这些的根本原因,是由于没有实现资源优先级的划分,优先加载关键资源。

2.1 什么是关键资源?

在网页渲染过程中,关键资源(Critical Resources)是指那些对页面的初始渲染至关重要的资源。这些资源的加载和处理直接影响了页面的首屏渲染速度和用户体验,比如HTML、CSS、JavaScript 文件就是关键资源。

相对的其他资源,如图片、视频、第三方sdk等,称为非关键资源

但也不绝对,需要视情况而定,比如有个活动页面,它的首屏最大内容就是一个活动视频,那么这个视频也能称为关键资源。

通常情况下,视频都会很大,不能直接加载,否则会导致请求线程资源一直被占用。因此,这时候我们需要视频的分片加载技术,只加载第一个视频分片,通常只有10几K。

若想了解更多的视频分片加载技术,可以自行网上查询,方法有很多,笔者之前使用的是 ffmpeg + hls,这里不再赘述。

同时,由于网络请求资源是有限制的,一般浏览器最大的并行请求数量是6个到8个。

因此,首先需要做的是梳理和拆分首屏和次屏、细分优先级、切割模块,哪些资源属于首屏,哪些资源属于次屏,首屏资源优先加载,次屏资源延迟加载。

image.png

2.2 网络宽带限制怎么办?

若用户在网络不好的偏远地区,即便区分首屏和次屏资源,有了资源的优先级,依然会出现一直加载的状况。这个时候,就需要做好资源的品质和大小划分,比如同一图片有3个对应的资源x1,x2,x3,分别对应高中低品质,然后根据网络实时状态加载不同品质的资源,做好降级渲染的方案。

至于如何实时检测网络状态,可看我之前写过的一篇文章,前端如何判断网络带宽和弱网环境

2.3 如何利用好 CDN ?

CDN(Content Delivery Network,内容分发网络)是一种通过分布式服务器加速内容传输的技术,其主要目的是提高网站和应用的加载速度、减少延迟、提高可用性。我们一起看下它的工作原理,如下:

cdn.jpg

本质上,CDN 减少了用户与源服务器之间的距离,从而加速了内容的传输速度。

充分利用 CDN 不仅仅是简单地部署静态资源,而是需要根据网站或应用的特点,设计合适的缓存策略、优化文件大小、资源域收敛、提前静态化预热、边缘计算等,利用 CDN 各种功能进行优化。

2.4 服务端响应慢 ?

Node.js 服务端的响应速度影响因素有很多,比如数据库查询慢、中间件、组件处理长任务、BFF 接口复杂聚合多个上下游数据源、SSR 渲染逻辑复杂等等。

因此要提高 Node.js 服务端的响应速度,可以从以下几方面入手:

  • 梳理首屏和次屏接口,分优先级
  • 减少首屏 BFF 聚合接口,拆分细化
  • 提升数据库查询性能,如建立索引、读写分离、分表等
  • 调整 HTTP 缓存时间
  • 启用 redis 缓存
  • 优化 SSR 渲染逻辑

3. 页面渲染为什么会出现卡顿?

页面渲染卡顿涉及的方面很多,但最重要的其实只有一个,那就是页面渲染的核心。

在此之前,我们先了解一个概念 FPS(Frames Per Second,帧率),它是指每秒钟屏幕上渲染的画面帧数,通常以帧/秒为单位。常见的目标是达到 60 FPS,即每秒渲染 60 帧,意味着每一帧的渲染时间等于 1000 毫秒 / 60 约为 16.67 毫秒

浏览器渲染的每一帧主要经历输入事件处理定时器RAF布局计算绘制合成显示RIC,如图:

image.png

我们都知道浏览器渲染线程,它是一个单线程。其中除了 requestIdleCallback(RIC) 是利用浏览器空闲时间执行的任务以外,其余各阶段,如果有耗时任务或长时间执行的脚本,线程资源被抢占,最终会导致页面卡顿。

3.1 如何查找耗时长任务?

若我们需要找到这些耗时的长任务,方法有很多,比如Lighthouse、Performance、Chrome Trace Viewer、使用 console.time()console.timeEnd()等,最直接的手段就是直接使用Performance,有标记为黄色或灰色的就是 长任务,如图:

image.png

3.2 什么样的任务才算长任务?需要介入优化?

这个其实并没有准确的答案,但一般来讲,超过 300 ms 的任务,用户就会明显感知得到,这种网络任务就属于长任务。对于这种长任务,通常就需要介入优化。

3.3 如何优化长任务(即问题代码)?

我们都知道,之所以要做性能优化,就说明当前项目必定存在一定的问题,在绝大多数的情况下,不可避免要处理项目的历史包袱,偿还技术债务。

这时候程序猿一般都会抓狂,一边骂骂咧咧,一边揪着头发含泪修改……

其实,若只是性能问题,一般情况下并不需要大刀阔斧地修改,只需要小改,甚至不改。

它的核心必定是耗时长,因此想方设法将它的长耗时任务优化即可。

比如与动画相关的,可以尝试使用 requestAnimationFrame 替换 setTimeout 和 setInterval,使用 WebAssembly 模块替换复杂的计算逻辑。

因此这种场景下,优化的手段通常有Web Workers、计算逻辑下沉、requestAnimationFrame、WebAssembly、优化事件处理,如防抖、节流等

若是遇到第三方的依赖包的代码,可能会麻烦一些。比如第三方 NPM 包,就需要对它进行改造,以达到性能优化效果。

4. 优化原则

尽管优化方式多种多样,但也有迹可循,我们在优化的过程中只需要遵循两个原则:

  • 一是快:在加载阶段尽可能减少用户看到内容的等待时间,减少资源大小和请求数量,确保关键资源优先加载。

  • 二是顺:在交互阶段让页面在用户交互时始终保持流畅,减少主线程阻塞、重排重绘和事件延迟,优化 JavaScript 执行效率。

5. 优化思路

要系统性地解决页面性能问题,必须分析从输入 URL 到页面显示的整个过程。每个环节都可能影响页面性能,因此优化需要覆盖所有关键点。

  1. Web容器加载:客户端加载 Webview 容器。

  2. DNS 解析:将域名转换为 IP 地址,确定服务器位置。

  3. TCP 连接:与服务器建立连接,如果是 HTTPS,还需进行 TLS 握手。

  4. 服务器响应:服务器处理请求并返回 HTML、CSS、JS 等资源。

  5. 网络资源加载:浏览器下载并解析 HTML,发送新的请求获取资源。

  6. 页面渲染:构建 DOM 和 CSSOM 树,生成渲染树,绘制页面。

因此,在 hybrid 开发框架中,首屏的时间 = 容器加载时间 + DNS 解析时间 + TCP 连接时间 + 服务器响应时间 + 网络传输时间 + 页面渲染时间

image.png

三、解决

如何系统性进行性能优化?

首屏的时间 = 容器加载时间 + DNS 解析时间 + TCP 连接时间 + 服务器响应时间 + 网络传输时间 + 页面渲染时间。因此从这六个阶段,可以总结出各阶段的优化方法,如图:

image.png

image.png

方法通常是直接有效的,但效果不一定有很大的提升,有时候从架构上优化会比所有方法来得更有效果,比如从 SSR 直接改成 ESR 渲染模式,但随之而来的是项目复杂度的提升,因此需要提前考虑投入产出比,即 ROI 究竟值不值得?

如何持久化地保持系统性能优化?

要处理好一个项目的性能优化其实不难,遇到了相同问题,重复上述方案即可。

但这其实并不是一个聪明的处理方案,难道遇到了一个新的项目,我们又要重复一遍吗?显然不科学,更重要的是我们需要从根本上解决问题。

通过建立完善的性能监控生态链,组织能够实现更加系统和高效的性能优化,确保系统长期稳定和高效运行。

比如代码审查平台、自动化测试平台、性能检测系统、定时巡检服务等,及时发现模块的图片未压缩、资源域名未收敛、js文件过大等性能量化指标。

性能优化常用工具

1. 公司内部监控平台

通过公司内部的性能监控系统,采集客户端页面的渲染数据,量化页面的性能表现。

  • 常见的关键指标
    • 首屏时间(FCP, First Contentful Paint) :首次内容渲染的时间,有的要求指标是 LCP,它与 FCP 都跟首屏渲染有关,FCP 是首先出现的内容,LCP 关注的是最大的内容渲染,后者更能反映用户的整体体验。
    • 交互时间(TTI, Time to Interactive) :页面完全可交互的时间。
    • 稳定性 CLS (Cumulative Layout Shift) :页面布局偏移的稳定性,反映了页面内容加载过程中的视觉稳定性。
    • 总阻塞时间(TBT, Total Blocking Time) :从首次内容渲染到完全可交互之间页面被阻塞的时间。

2. Chrome DevTools — Lighthouse

Lighthouse 是 Google 提供的开源工具,集成在 Chrome DevTools 中,也可以独立运行。它会根据用户输入的 URL 自动评估站点性能,并给出改进建议。

  • 综合评分:对性能、可访问性、PWA(Progressive Web App)、SEO 等进行评分。
  • 详细的性能报告:提供如 TTI(Time to Interactive)、LCP、FCP 等关键性能指标,并分析加载时间和卡顿点。
  • 优化建议:根据页面分析结果给出优化建议,便于开发者参考和改进。

image.png

3. Chrome DevTools — Performance

Chrome DevTools 是前端开发中最常用的调试工具,提供了强大的性能监控功能。它可以监控网络请求、页面渲染时间、内存使用情况、JavaScript 执行时间等。

  • Performance 面板:记录页面加载和交互的性能数据,包括页面渲染、布局计算、事件处理等。

  • Network 面板:查看页面加载时的 HTTP 请求,了解资源加载的时间、大小、优先级等信息。

image.png

4. WebPageTest

WebPageTest 是一个开源工具,可以从全球多个位置、不同的浏览器和网络环境下测试网站的加载性能,生成详细的报告。

  • 模拟全球各地:对出海项目特别友好,尤其是那些新项目。

  • 多次加载测试:可进行多次加载,生成瀑布图和视频来可视化加载过程。

  • 性能指标报告:提供 TTFB(Time to First Byte)、LCP(Largest Contentful Paint)、FCP(First Contentful Paint)、Speed Index 等重要性能指标。

image.png

image.png

5. PageSpeed Insights

PageSpeed Insights 是 Google 提供的一款免费的网页性能分析工具,帮助开发者评估和优化网站性能。它的核心在于给出页面加载的性能评分,并提供优化建议,尤其针对移动设备和桌面设备分别给出报告。

image.png

6. SpeedCurve

SpeedCurve 是基于 WebPageTest 的高级性能监控工具,专注于可视化地展示网站的性能趋势和变化。SpeedCurve 可以持续监控网站的性能,生成长时间段的趋势图,展示页面加载的不同阶段性能指标的变化,如 LCP、FCP、TTFB 等。

竞争对手对比:SpeedCurve 允许开发者将自己的网站与行业竞争对手进行性能对比,查看竞争对手的性能表现,从而制定有针对性的优化策略。

image.png