dinocode logodinocode
Back to Resources

Web Performance Optimization Guide

Andrew McMillanNov 15, 202512 min read
Web Performance Optimization Guide

Speed is a feature. Fast sites rank better, convert more visitors, and create better user experiences. Here are practical ways to make your site faster.

Optimize Your Images

Images are usually the biggest files on a web page. Optimizing them has the largest impact.

🚀

Quick Image Wins

  1. Use WebP format (30% smaller than JPEG)
  2. Compress images before uploading
  3. Serve appropriately sized images

In Next.js, the Image component handles much of this automatically:

import Image from 'next/image'

// Next.js optimizes automatically
<Image
  src="/hero.jpg"
  alt="Hero image"
  width={1200}
  height={600}
  priority // Load immediately for above-fold images
/>
📘

Image Sizing Rule

Never serve a 2000px image to display at 400px. Size images to their display size (or 2x for retina).

For background images in CSS:

/* Serve different sizes based on screen */
.hero {
  background-image: url('/hero-mobile.webp');
}

@media (min-width: 768px) {
  .hero {
    background-image: url('/hero-desktop.webp');
  }
}

Lazy Load Below the Fold

Do not load everything at once. Load what users see first, defer the rest.

💎

Above vs Below the Fold

Content visible without scrolling (above the fold) should load immediately. Everything else can wait until users scroll to it.

// Above fold - load immediately
<Image src="/hero.jpg" priority />

// Below fold - lazy load (default in Next.js)
<Image src="/feature.jpg" />

For non-Next.js projects:

<!-- Native lazy loading -->
<img src="image.jpg" loading="lazy" alt="Description" />

<!-- Lazy load iframes too -->
<iframe src="video.html" loading="lazy"></iframe>
⚠️

Do Not Lazy Load Everything

Above-the-fold content should NOT be lazy loaded. It causes layout shift and hurts perceived performance.

Minimize JavaScript

Every kilobyte of JavaScript has a cost. The browser must download, parse, and execute it all.

📘

JavaScript Cost

100KB of JavaScript is not the same as 100KB of images. JavaScript blocks rendering and requires CPU time to execute.

Ways to reduce JavaScript:

// Dynamic imports - only load when needed
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <Spinner />
})

// Only render on client if needed
const ClientOnlyChart = dynamic(() => import('./Chart'), {
  ssr: false
})
🚀

Bundle Analysis

Run npm run build and check your bundle sizes. Look for unexpectedly large packages.

Questions to ask:

  • Do you need that entire UI library or just a few components?
  • Is that date library necessary or can native Date work?
  • Are you importing the whole lodash or just the functions you need?
// Bad - imports everything
import _ from 'lodash'

// Good - imports only what you need
import debounce from 'lodash/debounce'

Enable Caching

Caching lets returning visitors load your site faster by reusing files they already downloaded.

💎

Cache-Control Headers

Set appropriate cache headers for different file types.

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/images/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=31536000, immutable',
          },
        ],
      },
    ]
  },
}

Cache duration guidelines:

File TypeCache DurationWhy
Images1 yearRarely change
CSS/JS (hashed)1 yearHash changes when content changes
HTMLNo cache or shortNeeds to be fresh
API responsesVariesDepends on data freshness needs

Core Web Vitals

Google measures these three metrics. They affect both user experience and search rankings.

📘

The Three Vitals

  • LCP (Largest Contentful Paint) - How fast main content loads
  • INP (Interaction to Next Paint) - How responsive to clicks
  • CLS (Cumulative Layout Shift) - How stable the layout is

Quick fixes for each:

LCP - Target under 2.5 seconds:

  • Optimize your largest image
  • Use priority on hero images
  • Reduce server response time

INP - Target under 200ms:

  • Break up long JavaScript tasks
  • Reduce third-party scripts
  • Use web workers for heavy computation

CLS - Target under 0.1:

/* Always set dimensions to prevent layout shift */
img, video {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}
⚠️

Font Loading CLS

Fonts loading late cause text to reflow. Use font-display: swap and preload critical fonts.

<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin />

Performance Testing

Measure before and after every optimization.

🚀

Free Tools

  • Chrome DevTools Lighthouse
  • PageSpeed Insights (web)
  • WebPageTest (detailed analysis)

Run tests on:

  • Your slowest pages
  • Pages with the most traffic
  • Key conversion pages

Test on throttled connections and mid-range devices, not just your fast development machine.

Key Takeaways

Performance optimization priorities:

  1. Optimize images (biggest impact for most sites)
  2. Lazy load below-the-fold content
  3. Audit and reduce JavaScript bundles
  4. Set appropriate cache headers
  5. Monitor Core Web Vitals

Small improvements compound. A 100ms improvement might not seem like much, but users notice when every interaction feels snappier.

Share this article