Several months of work to improve Core Web Vitals on the home page of Mail.ru resulted in a 60% increase in the 75th percentile in Cumulative Layout Shift (CLS), boosting average session time by 2.7% and conversion rates of core sections by more than 10%.
Where we started
Mail.ru is one of the leading e-mail services on the Russian-speaking Internet and is in the top 5 sites in Russia in terms of traffic. Mail.ru is an important resource for many people. It receives several hundred million visits per month, and is a portal from where people can access email, news, social media, performance internet searches and more.
Mail.ru wanted to provide its visitors with a high quality user experience, so work began to improve Core Web Vitals. Before discussing our optimization strategy, a few technical details of the Mail.ru home page should first be noted.
Svelte implements reactivity in a way that doesn't use Virtual DOM, which makes it less resource-intensive. Svelte's approach removes unused functions from production bundles because the code implementing them isn't generated by the compiler if the functions aren't used. Unused code is removed during compilation, resulting in smaller bundles. This may help reduce Total Blocking Time (TBT) during page startup.
Tracking performance metrics
Before optimizing Core Web Vitals, it's helpful to evaluate performance in the field. Before Core Web Vitals, we tracked other metrics, such as First Contentful Paint (FCP), in our internal performance dashboard.
Our metrics collection script was modified to collect Core Web Vitals and transmit them to our performance dashboard for visualization. In line with Google's recommendations, our script uses PerformanceObserver API to obtain metrics, which is part of the universal frontend "Platform" inside Mail.ru.
The dashboard displayed the following metrics for users (mean values for the week of 15-21 March 2021):
|Metrics group name||Core Web Vitals||Other Web Vitals|
|Share of users in accordance with Core Web Vitals thresholds||good||52%||92%||33%||35%||42%||43%|
Improving Core Web Vitals
While plenty of guidance exists for improving Core Web Vitals, every project has unique challenges. For the Mail.ru home page, the following opportunities were identified:
- Implementing placeholders for ad banners to reduce CLS.
- Using server-side rendering (SSR) to reduce Largest Contentful Paint (LCP).
- Code splitting to reduce LCP and First Input Delay (FID).
Skeletons for CLS improvement
CLS was one of the worst performing field metrics for the Mail.ru home page. Subsequent profiling of this page in the Performance panel of Chrome's DevTools revealed that ads were the source of the problem. To improve layout stability, our team decided to use placeholders to reserve space for ads before they load.
When implementing placeholders, the first step is to determine the dimensions of the content that will replace them. Luckily, the desktop version of Mail.ru home page has strictly documented sizes for ads. After talking with the design team, SVG-animated UI skeletons were used as placeholders as they reduce the perceived load time of the content.
The return of SSR
To ease the transition from Fest to Svelte, we incrementally rewrote the existing project rather than start over. By March 2021, we had migrated most of the frontend to Svelte, and eventually brought SSR to our production application after triaging and fixing backend performance issues.
After implementing SSR, the team discovered the cause of CLS regression that initially went unnoticed: the news section was not inserted at the moment of rendering the first content on the page. There was a delay between the initial painting of the page markup provided by the server and the insertion of news section on the client. This behaviour resulted in an ad skeleton shift, which worsened CLS.
Although Chrome's DevTools showed Layout Shift events, we couldn't find the reason for it at first. Though SSR itself wasn't the problem, it helped in discovering the solution later on. Fixing the code responsible for the painting delay improved layout stability of the news component.
Code splitting and unused polyfills
To improve the perceived page load speed, work was required to decrease LCP and FID values. One way to achieve this is through code splitting. In addition to the Mail.ru home page itself, our team is developing a widget for portal navigation. It is currently embedded in many of our company's projects.
For historical reasons, the widget is inserted at the very beginning of the page as a synchronously loading script. The share of polyfills in this script grew over time. To limit the negative performance effects of loading these polyfills, we implemented code splitting for both modern and legacy browsers.
We decided against the
type="module" attribute didn't target browsers that were modern enough for our needs. To address this, Mail.ru uses an in-house tool for identifying modern browser versions on the backend, and can adapt to those browsers accordingly.
In addition to bundle size reduction and positive effects on Core Web Vitals, code splitting improves the developer experience as well. Only 3.5% of our users use legacy browsers and that share is on a downward trend, so implementing code-splitting allowed our developers to use the latest browser APIs without introducing the polyfill bloat necessary for legacy browsers to all users.
After the optimization effort, we observed the mean values for the week of 24-30 May 2021 in our field data:
|Metrics group name||Core Web Vitals||Other Web Vitals|
|Share of users in accordance with Core Web Vitals thresholds||good||58% (+6%)||93% (+1%)||93% (+60%)||43% (+8%)||49% (+7%)||51% (+8%)|
The graphs below show changes in web page performance metrics values according to the "Platform". Note the two important dates on the graphs:
- 23 March 2021: the release of iteration with the last page sections migrated to Svelte;
- 19 April 2021: the release of iteration with returned SSR and layout modified to correct CLS regressions.
The decrease in values from May 1 to May 10 is due to May holidays in Russia.
Results obtained using the "Platform" are in line with the growth of metric values in Chrome UX Report (CrUX).
A comparison of mean user session duration values a week before the roll-out of initial improvements and a week after the roll-out shows 2.7% growth. Moreover, there is an overall significant increase in conversion in most sections of the page. In particular, conversions to the Mail.ru email app increased by 11.6%, the conversion of the news section increased by 13.5%.
Boost of share of good CLS threshold
Higher mean session duration
Increase of news section conversion rate
The most unexpected result we got was a 17.4% increase in the Click-Through Rate (CTR) of the marketing banner (its rendering time was significantly reduced by the introduction of SSR and preload tags).
After analyzing the rest of the sections on the page, we noticed significant performance improvement in the vast majority of them. Even for sections such as Weather and Coronavirus—which are not key on our page—we see an increase in conversion by 9.6% and 9.5%, respectively.
Improving performance is challenging in that the work involved may be prolonged. You should regularly monitor changes in metrics over time and ensure that all new product features don't cause regressions in Core Web Vitals. To achieve this, we monitor changes in Core Web Vitals in our performance budget.
Most importantly, we stressed the importance of Core Web Vitals to all members of our product team, from managers and designers to testers and QA. Each team member should be aware of performance metrics and be empowered to improve them. We also incorporate performance optimization objectives into our business processes on a regular cadence. Successfully providing a high-quality user experience is only possible through a joint effort by all team members.