DH
4 min read

Lazy Loading CSS in Next.js with a Custom Hook and Component

Boost Your Next.js Lighthouse Score with Lazy CSS Loading.

nextjsperformancecss

Performance optimization is crucial for creating user-friendly web applications. One effective technique for improving page load times is lazy loading CSS, which helps mitigate the negative effects of render blocking CSS on page rendering. Let’s explore how to implement this in Next.js, and how it can significantly boost your Google Lighthouse score.

Why Lazy Load CSS Files?

Lazy loading CSS defers the loading of non-critical styles until their needed. Inlining critical CSS for improving Core Web Vitals, especially under slow network conditions, can lead to substantial positive performance impact on First Contentful Paint (FCP) and can outperform apps that do not inline their critical CSS in bad network conditions. This technique can dramatically improve initial page load times, especially for larger applications with multiple stylesheets. By prioritizing critical CSS and deferring the rest, you enhance the perceived performance and user experience of your application.

Impact of Critical CSS on Google Lighthouse Scores

Implementing lazy loading for CSS positively impacts several Lighthouse metrics:

  • Faster First Contentful Paint (FCP) and Largest Contentful Paint (LCP)
  • Improved Time to Interactive (TTI)
  • Reduced Total Blocking Time (TBT)

Strategically using inline styles in Next.js applications can further optimize performance by isolating critical CSS for immediate application, avoiding the pitfalls of indiscriminate use.

These improvements lead to a higher overall performance score, contributing to better SEO rankings and user satisfaction.

Implementing the useLazyCSS Hook

Let’s create a custom hook to handle lazy loading of CSS. Create useLazyCSS.ts:

import { useEffect } from 'react';

const useLazyCSS = (href: string) => {
useEffect(() => {
let linkElement: HTMLLinkElement | undefined;

const existingLink = document.querySelector(`link[href="${href}"]`);
if (!existingLink) {
linkElement = document.createElement('link');
linkElement.rel = 'stylesheet';
linkElement.href = href;
document.head.appendChild(linkElement);
}

return () => {
if (linkElement) {
linkElement.remove();
}
};
}, [href]);
};

export default useLazyCSS;

This hook adds the CSS link if it doesn't exist and removes it on cleanup if it was added by this instance.

Creating the LazyCSS Component

Now, let's create a reusable component using our hook. Create LazyCSS.tsx:

import { FC } from 'react';
import useLazyCSS from './useLazyCSS';

interface LazyCSSProps {
href: string;
}

const LazyCSS: FC<LazyCSSProps> = ({ href }) => {
useLazyCSS(href);
return null;
};

export default LazyCSS;

Using the LazyCSS Component

To use the LazyCSS component in your Next.js 14 app, import it into any component or page:

import { FC } from 'react';
import LazyCSS from './LazyCSS';

const MyPage: FC = () => {
return (
<div>
<h1>My Page</h1>
<p>This is my page content.</p>
<LazyCSS href="/path/to/my-styles.css" />
</div>
);
};

export default MyPage;

Best Practices and Considerations

When implementing lazy loading for CSS, keep these best practices in mind:

  1. Prioritize critical CSS: Load essential styles immediately and defer non-critical styles.
  2. Use with moderation: Lazy loading too many small CSS files can lead to unnecessary HTTP requests.
  3. Only lazy load below the fold or on certain pages to avoid unstyled text from appearing early on.
  4. Monitor performance: Regularly check your Lighthouse scores to ensure your optimizations are effective.
  5. Test across devices: Ensure that lazy loading works well on various devices and network conditions.

To measure the impact of lazy loading CSS, use tools like Google Lighthouse or Chrome DevTools. Compare your performance metrics before and after implementation to gauge the effectiveness of your optimizations.

Conclusion

Lazy loading CSS is a powerful technique for improving the performance of your Next.js applications. By implementing the useLazyCSS hook and LazyCSS component, you can easily defer loading of non-critical styles, leading to faster initial page loads and improved Google Lighthouse scores. Remember to always measure the impact on your application's performance for best results.

Damian Hodgkiss

Damian Hodgkiss

Senior Staff Engineer at Sumo Group, leading development of AppSumo marketplace. Technical solopreneur with 25+ years of experience building SaaS products.

Creating Freedom

Join me on the journey from engineer to solopreneur. Learn how to build profitable SaaS products while keeping your technical edge.

    Proven strategies

    Learn the counterintuitive ways to find and validate SaaS ideas

    Technical insights

    From choosing tech stacks to building your MVP efficiently

    Founder mindset

    Transform from engineer to entrepreneur with practical steps