经过数月努力,Mail.ru 的首页 Core Web Vitals 指标得到了提升,Cumulative Layout Shift (CLS) 的 75 分位数提高了 60%,平均会话时长提高了 2.7%,核心版块的转化率提高了 10% 以上。
我们的起点
Mail.ru 是俄语互联网上领先的电子邮件服务之一,在俄罗斯的流量排名中位列前 5 位。Mail.ru 对许多人来说都是一项重要的资源。该网站每月吸引数亿次访问,用户可通过该门户访问电子邮件、新闻、社交媒体、效果出色的互联网搜索等内容。
Mail.ru 希望为访问者提供优质的用户体验,因此开始着手改进核心网页指标。在讨论优化策略之前,我们先来了解一下 Mail.ru 首页的一些技术细节。
虽然该项目长期以来一直使用我们的内部模板引擎 Fest 进行开发,但我们在 2019 年开始迁移到 Svelte 3。
Svelte 以不使用虚拟 DOM的方式实现了响应能力,因此其资源占用较少。Svelte 的方法会从生产 bundle 中移除未使用的函数,因为如果这些函数未使用,编译器不会生成实现它们的代码。系统会在编译期间移除未使用的代码,从而减小软件包的大小。这可能有助于缩短页面启动期间的总阻塞时间 (TBT)。
跟踪性能指标
在优化核心网页指标之前,最好先评估实际效果。在 Core Web Vitals 之前,我们在内部性能信息中心跟踪其他指标,例如 First Contentful Paint (FCP)。
我们修改了指标收集脚本,以收集 Core Web Vitals 指标并将其传输到性能信息中心进行可视化呈现。按照 Google 的建议,我们的脚本使用 PerformanceObserver API 获取指标,该 API 是 Mail.ru 内通用前端“平台”的一部分。
信息中心会显示用户的以下指标(2021 年 3 月 15 日至 21 日这一周的平均值):
指标组名称 | 核心网页指标 | 其他 Web Vitals | |||||
---|---|---|---|---|---|---|---|
指标名称 | LCP | FID | CLS | 首次内容渲染 (FCP) | TBT | TTI | |
符合 Core Web Vitals 阈值的用户所占的比例 | 好 | 52% | 92% | 33% | 35% | 42% | 43% |
needs-improvement | 19% | 5% | 23% | 38% | 16% | 25% | |
差 | 29% | 3% | 44% | 27% | 42% | 32% |

提升 Core Web Vitals 指标
虽然有许多有关如何改进 Core Web Vitals 的指南,但每个项目都面临着独特的挑战。我们为 Mail.ru 首页发现了以下优化机会:
- 为广告横幅植入占位符,以降低 CLS。
- 使用服务器端呈现 (SSR) 来缩短 Largest Contentful Paint (LCP) 时间。
- 代码分块以缩短 LCP 和 First Input Delay (FID)。
用于改进 CLS 的框架
CLS 是 Mail.ru 首页表现最差的实测指标之一。在 Chrome 开发者工具的性能面板中对此网页进行后续性能分析后,发现广告是问题的根源。为了提高布局稳定性,我们的团队决定在广告加载之前使用占位符为广告预留空间。
实现占位符时,第一步是确定将替换占位符的内容的尺寸。幸运的是,Mail.ru 首页的桌面版严格记录了广告尺寸。与设计团队沟通后,我们决定使用 SVG 动画界面框架作为占位符,因为它们可以缩短内容的实际加载时间。
SSR 的回归
为了从 Fest 顺利过渡到 Svelte,我们增量重写了现有项目,而不是从头开始。到 2021 年 3 月,我们已将大部分前端迁移到 Svelte,并在排查和修复后端性能问题后,最终将 SSR 引入了正式版应用。
实现 SSR 后,该团队发现了最初未注意到的 CLS 回归的原因:系统未在网页上呈现第一项内容时插入新闻版块。服务器提供的网页标记的初始绘制与客户端上插入新闻版块之间存在延迟。此行为导致广告框架发生偏移,从而降低了 CLS。
虽然 Chrome 的开发者工具显示了布局偏移事件,但我们起初找不到导致出现这种情况的原因。虽然 SSR 本身不是问题所在,但它有助于我们日后发现解决方案。修复了导致绘制延迟的代码,从而提高了新闻组件的布局稳定性。


SSR 对 CLS 的另一个影响是组件在水合前后移动,这可能会导致进一步的布局偏移。我们在移动版上尤其遇到了这个问题,因此需要特别注意已注水的组件标记。解决此问题的一个好方法是,尽可能将尽可能多的显示逻辑从 JavaScript 转移到 CSS。
代码分块和未使用的 polyfill
为了提高网页感知加载速度,我们需要降低 LCP 和 FID 值。实现此目的的一种方法是通过代码分块。除了 Mail.ru 首页本身之外,我们的团队还在开发一个用于门户导航的微件。它目前已嵌入到我们公司众多项目中。
由于历史原因,该微件会作为同步加载的脚本插入到网页的开头部分。此脚本中的 polyfill 比例随时间推移而增加。为了限制加载这些 polyfill 对性能产生的负面影响,我们为新式浏览器和旧版浏览器实现了代码分块。
我们决定不使用 module
/nomodule
模式为现代浏览器或旧版浏览器加载 JavaScript 软件包,因为 <script>
元素的 type="module"
属性没有定位到足够现代且符合我们需求的浏览器。为解决此问题,Mail.ru 使用内部工具在后端识别新型浏览器版本,并能相应地适应这些浏览器。
在后端能够识别浏览器后,我们便针对新式浏览器和旧版浏览器实现了代码分块。结果是,适用于现代浏览器的同步加载 JavaScript 微件的大小缩减了 43.3%。我们还将此做法应用于一些其他门户脚本。
除了减小软件包大小并对 Core Web Vitals 产生积极影响之外,代码分块还可以改进开发者体验。只有 3.5% 的用户使用旧版浏览器,而且这一比例呈下降趋势,因此通过实现代码分块,我们的开发者无需向所有用户引入旧版浏览器所需的大量 polyfill,即可使用最新的浏览器 API。
结果
优化后,我们在实地数据中观察到 2021 年 5 月 24 日至 30 日这一周的平均值:
指标组名称 | 核心网页指标 | 其他 Web Vitals | |||||
---|---|---|---|---|---|---|---|
指标名称 | LCP | FID | CLS | 首次内容渲染 (FCP) | TBT | TTI | |
符合 Core Web Vitals 阈值的用户所占的比例 | 好 | 58% (+6%) | 93% (+1%) | 93% (+60%) | 43% (+8%) | 49% (+7%) | 51% (+8%) |
needs-improvement | 18% | 4% | 3% | 34% | 17% | 24% | |
差 | 24% | 3% | 4% | 23% | 34% | 25% |

以下图表显示了网页性能指标值随“平台”的变化情况。请注意图表中的两个重要日期:
- 2021 年 3 月 23 日:发布了迭代版本,其中最后的页面部分已迁移到 Svelte;
- 2021 年 4 月 19 日:发布了迭代版本,其中返回的 SSR 和布局已修改以更正 CLS 回归问题。
5 月 1 日至 5 月 10 日的值下降,是因为俄罗斯的五一节假期。



使用“平台”获得的结果与 Chrome 用户体验报告 (CrUX) 中指标值的增长一致。



将初始改进发布前一周的平均用户会话时长值与发布一周后的平均用户会话时长值进行比较,结果显示增长了 2.7%。此外,网页的大多数部分的转化次数总体上也大幅增加。具体而言,Mail.ru 电子邮件应用的转化次数增加了 11.6%,新闻版块的转化次数增加了 13.5%。
181%
提高了良好 CLS 阈值的占比
2.7%
平均会话时长较长
13.5%
提高新闻版块转化率
我们获得的最意外的结果是,营销横幅的点击率 (CTR) 提高了 17.4%(由于引入了 SSR 和预加载标记,其呈现时间显著缩短)。
分析网页上的其余部分后,我们发现其中大多数部分的性能都得到了显著提升。即使是页面上不太重要的“天气”和“新冠”等版块,转化次数也分别增加了 9.6% 和 9.5%。
总结
提高性能是一项具有挑战性的工作,因为所涉及的工作可能会持续很长时间。您应定期监控指标随时间的变化,确保所有新产品功能不会导致核心 Web Vitals 出现回归问题。为此,我们会在效果预算中监控 Core Web Vitals 指标的变化。
最重要的是,我们向产品团队的所有成员(从经理和设计师到测试人员和质量检查人员)强调了 Core Web Vitals 的重要性。每个团队成员都应了解效果指标,并有权采取措施来提升指标。我们还会定期将效果优化目标纳入业务流程。只有所有团队成员通力合作,才能成功提供优质的用户体验。