This is part 2 of a two-part series (part 1 is here)
In part 1 I looked at where to start when it comes to improving LCP for WordPress sites, and at some steps you can take to improve back-end performance. Part 2 looks at the front-end.
If you’ve covered the server-side and are happy with the performance there (or at least happy that the biggest issues are not there!) then it’s time to look at the front-end.
Remember LCP (Largest Contentful Paint) is defined as the time taken to render the largest block in the viewport. We can use Chrome Dev Tools to determine what that is in different scenarios. I suggest starting with the first fold of your homepage (or other significant landing page as determined by your analytics) as most people will land at the top of the page the first time they load it. But bear in mind that the largest element in the viewport could be part way down the page if the user lands there (eg by clicking an anchor link or if they have visited the page before and left at that scroll depth).
What to do
There are a lot of options on what to do next and I won’t be able to cover everything. But here are the most common issues I have come across:
Images
If your LCP element contains an image then there are several things you can do to optimise the image’s load time (which I also recommend in general, not just for LCP!). The most important are:
- Render images with the
srcset
attribute (wp_get_attachment_image
will automate this for you) to ensure the browser does not have to load larger images than are necessary. It’s important you add the relevant image sizes to WordPress to generate the alternate sizes. - Never load the fullsize image, always a thumbnail.
- Compress images as much as possible, and serve them in next-gen formats too where this is supported (most browsers do these days). We use the ShortPixel plugin to cover off on both of these.
- Use vector formats for icons and logos where possible. These tend to be smaller files and scale to any size with no distortion.
- If loading images as background images (eg
style=”background-image: url(hero.jpg);”
) this will delay the image load until all the stylesheets have been fully processed, thus delaying the paint of the element. Take a look at this thread for an explanation and some tips on fixing the problem, such as pre-loading the image in the<head>
or repeating the image in an<img>
tag. This is a particularly common problem for LCP, as we often use background images on hero elements.
Fonts
If your LCP element contains text then it may be delayed by the time taken to load any custom fonts used by your website. Here are some things to look out for:
- Make sure you are using
font-display: swap;
which will display text using the system default font and then swap it to the custom font once it becomes available. - Also make sure your fonts are not render blocking! This will impact the load time of everything on the page. Here are some techniques you can use to load fonts asynchronously.
Render Blocking Scripts
How many render-blocking scripts are loaded by the page? The optimal state is none, which would likely involve inlining Critical CSS and loading additional stylesheets in the footer. In addition all JavaScript files should be deferred or loaded in the footer too.
With WordPress it can be tricky to completely eliminate render blocking scripts, especially on an existing site that has plugins/themes which rely on these. In these cases I like to look into which plugins are generating scripts and determine if they are really necessary and if they are then try to re-enqueue the scripts in the footer checking that nothing breaks. You can also look for alternative plugins which do the same job in a more performant way.
If you are building the site from scratch I strongly suggest running regular Lighthouse scans and checking which scripts are loaded, especially after installing new plugins (we run Lighthouse in our Bitbucket Pipeline and fail the build if performance drops below standard). I also recommend dequeuing jQuery as this is not necessary in many cases and ends up slowing the site down.
Design
I wanted to briefly mention design too. I encourage engineers to loop back with the site designer where they see issues that could be fixed with a UI change. For example, it may be more efficient to redesign a high-definition image grid rather than optimise it for performance. The cost / benefit trade-off is always important to keep in mind.
Summary
Just keep pruning and questioning everything. What plugins are really necessary? What JavaScript dependencies do you really need to add to your bundle? What scripts are only needed on a handful of pages but not all?
Let’s all keep performance centre of mind, it’s so important. What tips do you have for optimising LCP on WordPress?