I run a small Next.js site (free browser-based file conversion tools). Yesterday I ran PageSpeed Insights on mobile and got a 69 — “needs improvement,” with First Contentful Paint at 4.0s and Largest Contentful Paint at 5.6s under slow-4G throttling. Today it’s 96.
The fix took about five minutes once I found the actual cause.
The setup
Like a lot of small sites trying to monetize, I have a Google AdSense script in my root layout. It was added as a plain tag:
<script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-xxxxx"
crossOrigin="anonymous"
/>
Enter fullscreen mode Exit fullscreen mode
async looks like it should be enough. It isn’t — for what actually matters here.
What PageSpeed was actually flagging
The diagnostics called out “Reduce unused JavaScript — Est. savings of 186 KiB.” That’s a big number for a lightweight site. The twist: my AdSense account is still pending approval, so the script was loading its full weight and doing nothing — no ads were rendering yet. Pure cost, zero benefit, and it was still competing with my actual page content for parsing priority during initial load.
The fix
Next.js ships a purpose-built <Script> component specifically for this situation, with a strategy prop:
import Script from "next/script";
<Script
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-xxxxx"
strategy="lazyOnload"
crossOrigin="anonymous"
/>
Enter fullscreen mode Exit fullscreen mode
lazyOnload defers loading until the browser is idle, well after your actual content has painted. The script still loads — ads will still work once approved — it just stops competing with your page for the critical early-loading window.
Result
- Performance: 69 → 96
- The 186 KiB “unused JavaScript” flag: gone
- Zero change to how AdSense actually functions
The takeaway
If you’re running any third-party script (ads, chat widgets, analytics beyond the basics) as a raw <script> tag in a Next.js app, it’s worth auditing. next/script‘s strategy prop has four options (beforeInteractive, afterInteractive, lazyOnload, worker) and picking the right one for non-critical scripts is close to a free performance win — no functionality lost, no removed features, just better loading priority.
For anything genuinely optional to the initial render — ads, chat bubbles, feedback widgets — lazyOnload is usually the right call.
답글 남기기