Improving Lighthouse scores and performance in Nuxt projects

Though there’s plenty of advice scattered around the internet on improving speed, performance and lighthouse scores for Nuxt apps, I thought I’d summarise a few things I’ve found especially helpful in a short post.

Note – though I’ve personally only applied these techniques to Nuxt apps, they should work with any SSR Vue projects.

1) Lazy Hydration. It turns out that hydration is surprisingly expensive! Taking your Server-Side-Rendered page and turning it back into a dynamic DOM in the browser which Vue has control of takes a bit of work. What’s more, there’s often plenty of content in a site which doesn’t need to be hydrated. There might be elements that are simply visible and don’t change once rendered, or things that only need to be hydrated if clicked on or scrolled into view.

I found that vue-lazy-hydration was the best way to quickly improve performance. Just use the <LazyHydrate> tag with one of the following options.

Whilst you can’t get with hydrating nothing on your page (otherwise what’s the point of using Vue at all?), you might be able to shave 10/20% off your TTI within a few minutes.

2) Code splitting/chunking. As a webpack noob, I’d heard a lot about this and thought it sounded awesome, and the message I generally received was that it was something that more or less happened automatically. Whilst this is true, you have to structure your imports in a certain way for it to happen.

This is how I was initially importing my components:

However, then I changed my imports to this format:

This resulted in webpack chunking my Javascript far better, producing lots more bundles that were smaller and more optimised. I’m not a webpack expert, but with the default Nuxt setup, this approach led to better results.

But how do you examine the results? How can you track what’s going on behind the scenes? This is the third tip, and I suspect if you’re reading this post you’re probably using it already, but it’s so important that I have to mention it regardless!

3) Use webpack-bundle-analyser. Webpack bundle analyser is awesome. It makes it super easy to figure out what’s taking up space. Setting analyse: true in the build section of nuxt.config.js will open a tab in your browser when you run nuxt build, showing you graphically what the cause of your grief is.

Naturally there are things which are essential to your application. I couldn’t imagine deploying an application without Sentry, even though it takes up ~20% of my vendors bundle.

This leads me to my last point (rant?):

4) Don’t use Vuetify. It will fuck you up. Its default quickstart page (essentially without any content) has an abysmal lighthouse score out of the box. It has terrible optimisation and coverage – even with A la carte enabled, over 90% of the CSS you ship to the browser is unused. Despite a healthy outcry from users about its bloat, nothing is being done, despite offers of help etc.

Hope you found these useful, let me know if you have anything I should add!

One thought on “Improving Lighthouse scores and performance in Nuxt projects

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s