Hacking Next.js for better PageSpeed scores

Ali N.
MEDWING Engineering, Product & Design
3 min readMar 10, 2020

We launched MEDWING’s new website in late 2019 with a lot of media content and animations on landing page. Thanks to Next.js’ ease of use and out-of-the-box optimizations, we received lots of positive feedback. However our marketing team were not so impressed with our below average PageSpeed score.

So, we set a goal to improve our PageSpeed Insights score and get it to the maximum achievable while keeping an acceptable UX.

And here are the results:

After optimzations

Previously it looked something like this:

Before optimizations

Breaking it down

Key PageSpeed factors that affected the score drastically

  1. First contentful paint — Animations & images were the main culprits
  2. First CPU Idle — Without chunking enabled and minification there was a lot of JS for browser to parse and execute on page load.
  3. Time to Interactive — Main thread was busy handling JS and making it slow for the user

Things we investigated first

  1. CDN —We did setup CDN to decrease load on our application server — interestingly it lowered the score initially
  2. Chunking/code splitting — Applied multiple babel plugins to get better chunking and code splitting, dynamic imports helped. Granular chunking caused more harm than good.
  3. Webpack sideEffects Setting side-effects to false caused the app to break/behave inconsistently. We kept it unchanged.
  4. Google Tag Manager — Staging env had a relatively better score than production, so GTM seemed to have an effect. Eventually, delaying GTM initialization worked.

Continued improvements

  • Delaying non-critical JS
  • Disabling animations on “above the fold content” to improve First Contentful Paint
  • Bringing back CDN with all other tweaks — improved score this time

As Disabling animations and brining back CDN parts are self explanatory. I will instead expand on Delaying non-critical JS in the next section.

Hacking Next.js

I am sure you are wondering when I would bring up actually hacking Next.js. Well the moment has come.

Granular chunks and code splitting generate too many JS files. So, we decided to delay the load of as many of them as possible to free up browser resources (and to do better on PageSpeed score).

Find the clever hack below:

nextScriptCustom.js
headCustom.js

Add the customized NextScript and Head to your _document.js to enable the hacks.

NextScriptCustom overrides methods to enable delayed injection of non app breaking script tags. And HeadCustom removes (or just returns nothing) preload link tags for javascript and css.

Wrapping up

PageSpeed score does reflect real world stats. With increased PageSpeed score, mobile experience improved significantly. Generally, I assumed preloading JavaScript and CSS was a good idea for better user experience, but on mobile browsers that is not the case and is reflected in the PageSpeed score.

Edited by Eran Peer

--

--

Ali N.
MEDWING Engineering, Product & Design

Software engineer having experience in crafting ambitious web apps, with seasoned skills of React & Ruby.