I’m trying to understand why a particular page on our site seems to have a LCP that varies wildly:
This test has 3 runs from Paris/4G. It’s using a script that sets a cookie to avoid an A/B test we are performing client-side at the moment that may otherwise skew the results.
The 3rd run behaves like I’d expect : We get the FCP around 2.5s, and LCP at 2.7s once text is rendered. The LCP element is the first paragraph of text, and it only depends on the HTML, the CSS and a subset font (which is preloaded). Meanwhile JavaScript is downloaded and eventually executes, some images are downloaded, but that doesn’t change anything.
On the first 2 runs however, the LCP is 3.5 and 3.8 seconds respectively. The first run is not served from cache and we have issues with flushing that delays an important preconnect, so I’m going to focus on the second one, where the LCP is at 3.5s. That’s quite late, as if it had waited on the JavaScript execution to be finished. The LCP element is still the same paragraph, but in those runs it appears twice: once around the time of the first run, but with somehow a slightly smaller size than expected, and the other at the 3.5s mark, with the correct size. Looking at the filmstrip closely it appears that this is caused by the text being rendered without the preloaded font first (despite it seemingly being downloaded in time), and then swapping with the correct one… but very late. Something that doesn’t happen with the “good” run. Note that there is no font-display: swap on our subset, only on the full, larger font that the rest of the page needs.
How can I avoid this ? I understand why, once JavaScript is executing, the browser might delay rendering and that might delay the LCP. But I’m preloading the font, shouldn’t it appear early enough ? Would adding a defer attribute to the help ?
(I’m aware that fixing the site to serve a leaner HTML, faster, over a single domain under a CDN would help a lot in general. I’m working on this, but it’s going to take a lot of time, so I’m working on fixing all the little details I can in the meantime)