Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.

Keep page weight under 1500KB

Total page weight including all resources is under 1500KB (ideally under 500KB).

Utilities
Quick take
Typical fix time 20 min
  • Target under 500KB for optimal performance, max 1500KB
  • Images typically account for 50-70% of page weight
  • JavaScript bundles are often the second largest contributor
  • Monitor with performance budgets in CI/CD
Why it matters: Page weight directly correlates with load time—a 1.5MB page takes 3-5 seconds on 4G mobile. Every 100KB reduction improves user experience, especially on slower networks.

Rule Details

Page weight is the total size of all resources needed to render a page.

Code Examples

// next.config.js - automatic image optimization
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],
    minimumCacheTTL: 60 * 60 * 24 * 365, // 1 year
  }
}
// Component with optimized images
import Image from 'next/image'
 
function ProductCard({ image, name }: { image: string; name: string }) {
  return (
    <Image
      src={image}
      alt={name}
      width={300}
      height={200}
      loading="lazy"
      sizes="(max-width: 640px) 100vw, 300px"
    />
  )
}

Why It Matters

Page weight directly correlates with load time—a 1.5MB page takes 3-5 seconds on 4G mobile. Every 100KB reduction improves user experience, especially on slower networks.

Weight Benchmarks

CategoryTargetAcceptablePoor
Total page< 500KB< 1500KB> 1500KB
HTML< 50KB< 100KB> 100KB
CSS< 50KB< 100KB> 100KB
JavaScript< 200KB< 400KB> 400KB
Images< 200KB< 500KB> 500KB
Fonts< 100KB< 200KB> 200KB

Typical Page Weight Breakdown

Resource TypeAverage %Optimization Priority
Images50-70%High
JavaScript15-25%High
CSS5-10%Medium
Fonts5-10%Medium
HTML2-5%Low

JavaScript Bundle Optimization

// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // Split vendor code
          vendor: ['react', 'react-dom'],
          // Split by feature
          charts: ['recharts', 'd3'],
        }
      }
    },
    // Warn if chunk exceeds size
    chunkSizeWarningLimit: 200
  }
}
// Dynamic imports for code splitting
import { lazy, Suspense } from 'react'
 
const HeavyChart = lazy(() => import('./HeavyChart'))
const AdminPanel = lazy(() => import('./AdminPanel'))
 
function Dashboard() {
  return (
    <Suspense fallback={<Skeleton />}>
      {showChart && <HeavyChart />}
      {isAdmin && <AdminPanel />}
    </Suspense>
  )
}

CSS Optimization

/* Remove unused CSS with PurgeCSS */
/* After: Only critical styles remain */
 
/* Use CSS custom properties to reduce repetition */
:root {
  --color-primary: #3b82f6;
  --spacing-md: 1rem;
}
 
/* Avoid large frameworks entirely if possible */
/* Tailwind CSS with purging typically produces < 10KB */

Font Optimization

/* Subset fonts to only needed characters */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-latin.woff2') format('woff2');
  font-display: swap;
  unicode-range: U+0000-007F, U+0080-00FF; /* Latin only */
}
 
/* Or use system fonts */
body {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

Performance Budget in CI/CD

// lighthouse.config.js
module.exports = {
  extends: 'lighthouse:default',
  settings: {
    budgets: [
      {
        resourceSizes: [
          { resourceType: 'total', budget: 500 },
          { resourceType: 'script', budget: 200 },
          { resourceType: 'image', budget: 200 },
          { resourceType: 'stylesheet', budget: 50 },
          { resourceType: 'font', budget: 100 },
        ]
      }
    ]
  }
}
# GitHub Actions performance check
- name: Run Lighthouse
  uses: treosh/lighthouse-ci-action@v10
  with:
    budgetPath: ./lighthouse-budget.json
    uploadArtifacts: true

Measuring Page Weight

// Check total page weight
function measurePageWeight() {
  const resources = performance.getEntriesByType('resource')
  const navigation = performance.getEntriesByType('navigation')[0]
 
  const breakdown = {
    html: navigation?.transferSize || 0,
    css: 0,
    js: 0,
    images: 0,
    fonts: 0,
    other: 0
  }
 
  resources.forEach(r => {
    const size = r.transferSize || 0
    if (r.initiatorType === 'css' || r.name.includes('.css')) {
      breakdown.css += size
    } else if (r.initiatorType === 'script' || r.name.includes('.js')) {
      breakdown.js += size
    } else if (r.initiatorType === 'img' || /\.(jpg|png|webp|avif|gif|svg)/.test(r.name)) {
      breakdown.images += size
    } else if (/\.(woff2?|ttf|otf|eot)/.test(r.name)) {
      breakdown.fonts += size
    } else {
      breakdown.other += size
    }
  })
 
  const total = Object.values(breakdown).reduce((a, b) => a + b, 0)
 
  console.table({
    ...Object.fromEntries(
      Object.entries(breakdown).map(([k, v]) => [k, `${(v / 1024).toFixed(1)} KB`])
    ),
    total: `${(total / 1024).toFixed(1)} KB`
  })
 
  return { total, breakdown }
}

Verification

Automated Checks

  • Check Network tab—sort by Size column
  • Run Lighthouse performance audit
  • Use WebPageTest for detailed breakdown
  • Set up performance budgets in CI

Manual Checks

  • Monitor with Real User Monitoring (RUM)

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Analyze the total page weight including all resources. Check if it's under 1500KB (ideally under 500KB).

Fix

Auto-fix issues

Optimize this page to reduce its total weight through image optimization, code minification, and removing unnecessary resources.

Explain

Learn more

Explain how page weight impacts loading time, especially on mobile networks, and affects user experience.

Review

Code review

Review the routes, assets, and loading behavior that affect Keep page weight under 1500KB. Flag exact files, requests, or rendering steps that add unnecessary network, CPU, or layout cost, and describe the measurement method used to confirm the issue.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

PageSpeed Insights
pagespeed.web.devTool

Rules that often go hand-in-hand with this one.

Minimize HTTP requests

HTTP requests are minimized by combining files, using sprites, and HTTP/2.

Performance
Enable text-based compression

Compress text resources (HTML, CSS, JS) using Gzip or Brotli to reduce data transfer size.

Performance

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385