{
  "$type": "site.standard.document",
  "canonicalUrl": "https://johnnyreilly.com/posts/docusaurus-improve-core-web-vitals-fetchpriority",
  "description": "By using `fetchpriority` on your Largest Contentful Paint you can improve your Core Web Vitals. This post implements that with Docusaurus.",
  "path": "/posts/docusaurus-improve-core-web-vitals-fetchpriority",
  "publishedAt": "2023-01-18T00:00:00.000Z",
  "site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
  "tags": [
    "docusaurus"
  ],
  "textContent": "By using fetchpriority on your Largest Contentful Paint you can improve your Core Web Vitals. This post implements that with Docusaurus v2. There is a follow on post that details migrating this plugin to Docusaurus v3.\n\n\n\nAvoiding lazy loading on the Largest Contentful Paint\n\nAt the weekend I wrote a post documenting how I believe I ruined the SEO on my blog. That post ended up trending on Hacker News. People made suggestions around things I could do that could improve things. One post in particular caught my eye from Growtika saying:\n\n> Page speed: It's one of the most important ranking factor. You don't have to get 100 score, but passing the core web vitals score and having higher score on mobile is recommended.\n>\n> https://pagespeed.web.dev/report?url=https%3A%2F%2Fjohnnyreilly.com%2F&form_factor=mobile\n>\n> A cool trick to improve the result fast is by removing the lazy load effect from the LCP:\n\nAnother person chimed in with:\n\n> Indeed. Even better, making it high priority instead of normal: https://addyosmani.com/blog/fetch-priority/\n\nfetchpriority\n\nI hadn't heard of fetchpriority before this, but the linked article by Addy Osmani carried this tip:\n\n> Add fetchpriority=\"high\" to your Largest Contentful Paint (LCP) image to get it to load sooner. Priority Hints sped up Etsy’s LCP by 4% with some sites seeing an improvement of up to 20-30% in their lab tests. In many cases, fetchpriority should lead to a nice boost for LCP.\n\nI was keen to try this out. Somewhat interestingly, I was the person responsible for originally contributing lazy loading to Docusaurus. For what it's worth, lazy loading is a _good thing_ to do. It's just that in this case, it was causing the LCP to be lazy loaded. I wanted to change that.\n\nSwizzling the image component\n\nSince my initial contribution, the implementation had been tweaked to allow user control via Swizzling. By the way, swizzling is a great feature of Docusaurus. It allows you to override the default implementation of a component. In this case, I wanted to override the Img component and opt out of lazy loading. I did this by running the following command:\n\nThis created a file at src/theme/MDXComponents/Img.js. I then made the following change:\n\nGetting rid of the loading=\"lazy\" attribute was all I needed to do. This gets us to the point where none of our images are lazy loaded anymore. Stage 1 complete!\n\nAdding fetchpriority=\"high\" to the LCP with a custom plugin\n\nThe next thing to do was to write a small Rehype plugin to add fetchpriority=\"high\" to the LCP. I did this by creating a new JavaScript file called image-fetchpriority-rehype-plugin.js:\n\nThe above plugin runs over the AST of the MDX file and adds fetchpriority=\"high\" to the first image. It also adds loading=\"eager\" to the first image and loading=\"lazy\" to all other images.\n\nInterestingly, when I was writing it I discovered that the visitor is invoked multiple times for the same elements. I'm not quite sure why, but the logic in the plugin uses a Map to keep track of which images have already been processed. TL;DR it works!\n\nI then added the plugin to the docusaurus.config.js file:\n\nWhat does it look like when applied?\n\nNow we have this in place, if we run the same test with pagespeed we have different results:\n\nWe're now _not_ lazy loading the image and we're also making it a high priority fetch. Great news!\n\nI'd like for this to be the default behaviour for Docusaurus. I'm not sure if it's possible to do this in a way that's straightforward. I've raised an issue on the Docusaurus repo to see if it's possible.",
  "title": "Docusaurus: improving Core Web Vitals with fetchpriority"
}