The Ultimate Performance Checklist: Launching Fast Websites Every Time
Over the past six months, we’ve covered every major aspect of web performance, from Core Web Vitals and image optimization to critical CSS, JavaScript performance, responsive images, and performance budgets. Each post went deep on a specific topic. This post brings it all together.
Consider this your comprehensive performance checklist. Every item here is something we check before launching any website. It’s the culmination of everything we’ve discussed in this series, organized into a practical, actionable format you can use for your own projects. This post covers one piece of a bigger system, and we mapped out the rest in our complete guide to website performance and Core Web Vitals.
Whether you’re building a new site or auditing an existing one, work through this checklist section by section. Not every item will apply to every project, but the majority will.
Pre-Launch Performance Audit
Before diving into specifics, run these baseline measurements and document them. They give you a starting point and help you measure the impact of your optimizations.
- [ ] Run PageSpeed Insights for both mobile and desktop. Document scores
- [ ] Run WebPageTest on a 4G mobile connection. Document filmstrip and metrics
- [ ] Check Google Search Console Core Web Vitals report (if the site is already live)
- [ ] Document total page weight for the five most important pages
- [ ] Document LCP, INP, CLS, FCP, and TTFB for each
- [ ] Identify the single biggest performance bottleneck on each page
Server and Hosting
The fastest-built website in the world will be slow if the server is slow. Start here.
- [ ] TTFB under 800ms. Time to First Byte should be well under one second. If it’s not, the server or hosting environment is the bottleneck.
- [ ] HTTP/2 or HTTP/3 enabled. Modern protocols allow multiplexing, header compression, and other performance benefits. Any decent modern host should support this.
- [ ] SSL/TLS certificate installed. HTTPS is required for HTTP/2 and is a ranking factor. Free certificates from Let’s Encrypt make this a non-negotiable.
- [ ] Gzip or Brotli compression enabled. Text-based assets (HTML, CSS, JavaScript, SVG, JSON) should be compressed before transmission. Brotli offers 15-25% better compression than Gzip.
- [ ] CDN configured. A content delivery network serves assets from the server closest to the visitor, reducing latency. Cloudflare’s free tier is a solid starting point.
- [ ] Server-side caching configured. For dynamic sites (WordPress, etc.), server-side caching stores rendered pages so the server doesn’t rebuild them on every request.
- [ ] Browser caching headers set. Static assets should have long cache expiration times (1 year for versioned assets). HTML should have shorter cache times or no-cache with ETags.
- [ ] DNS resolution is fast. Use a fast DNS provider (Cloudflare, Route53). Slow DNS adds hundreds of milliseconds before the connection even starts.
HTML and Document Structure
The HTML document is the foundation of everything. Get it right.
- [ ] Clean, semantic HTML. Use proper heading hierarchy (one H1, logical H2/H3 nesting), semantic elements (nav, main, article, section, footer), and avoid deeply nested or unnecessary div structures.
- [ ] Critical resources preloaded. Use
<link rel="preload">for fonts, critical images, and any other resources needed for above-the-fold rendering. - [ ] DNS prefetching for third-party domains. If you load resources from external domains (CDNs, analytics, fonts), use
<link rel="dns-prefetch">to start the DNS lookup early. - [ ] No render-blocking resources in the head. CSS should be inlined (critical) or loaded asynchronously. JavaScript should use
deferorasyncattributes unless it’s truly critical for initial render. - [ ] Document size is reasonable. The HTML document itself should be under 100KB. Bloated HTML (from page builders, excessive inline styles, or massive SVGs) adds parsing time.
- [ ] Proper viewport meta tag.
<meta name="viewport" content="width=device-width, initial-scale=1">ensures proper mobile rendering.
CSS Performance
CSS directly affects how quickly the browser can render content.
- [ ] Critical CSS inlined. Extract the CSS needed for above-the-fold content and inline it in the
<head>. Defer the full stylesheet. - [ ] Total CSS under 50KB (compressed). If your CSS exceeds this, audit for unused styles. Tools like PurgeCSS can remove CSS that no page actually uses.
- [ ] No unused CSS. Use Chrome’s Coverage tool to identify CSS that’s downloaded but never applied. Remove it.
- [ ] CSS minified. Remove whitespace, comments, and unnecessary characters from production CSS.
- [ ] No @import statements. CSS
@importcreates additional round trips. Use<link>tags or bundle CSS during the build process. - [ ] Efficient selectors. Avoid deeply nested selectors, universal selectors in performance-critical paths, and excessively specific selectors that increase file size.
- [ ] font-display: swap on all custom fonts. This ensures text is visible immediately with a fallback font while custom fonts load.
- [ ] No layout thrashing from CSS. Avoid styles that cause the browser to recalculate layout on scroll or interaction (e.g., changing width/height on hover without containment).
JavaScript Performance
JavaScript is the most expensive asset type per byte. Be ruthless.
- [ ] Total JavaScript under 100KB (compressed) for brochure sites. Under 200KB for web applications (initial load).
- [ ] No unused JavaScript. Use Chrome’s Coverage tool to identify dead code. Use tree shaking to eliminate it.
- [ ] Code splitting implemented. Each page should only load the JavaScript it needs. Route-based splitting is the minimum.
- [ ] Third-party scripts audited. List every third-party script. For each one, document its size, its purpose, and whether it’s worth the performance cost.
- [ ] Third-party scripts loaded asynchronously. Analytics, chat widgets, and marketing tags should use
asyncordefer. None of them should block rendering. - [ ] No jQuery (unless genuinely needed). In 2026, native browser APIs cover virtually everything jQuery provided. If jQuery is present, question whether it’s necessary.
- [ ] JavaScript minified and compressed. Production bundles should be minified (Terser, esbuild) and served with Brotli or Gzip compression.
- [ ] Long tasks broken up. Any JavaScript task that takes over 50ms blocks the main thread. Break long tasks into smaller chunks using
requestIdleCallback,setTimeout, or thescheduler.yield()API. - [ ] Event listeners are efficient. Use event delegation where possible. Remove listeners when they’re no longer needed. Debounce scroll and resize handlers.
- [ ] No synchronous layout reads in loops. Reading layout properties (offsetHeight, getBoundingClientRect) forces the browser to recalculate layout. Batch reads before writes.
Image Optimization
Images are typically the heaviest assets. Optimizing them delivers the biggest payload reductions.
- [ ] All images use responsive srcset. Every content image should provide multiple sizes via the
srcsetattribute. At least four sizes covering mobile through desktop. - [ ] sizes attribute matches CSS layout. The
sizesattribute tells the browser how wide the image will be at each viewport width. It must match your actual layout. - [ ] Modern formats served. Use the
<picture>element to serve AVIF with WebP fallback and JPEG/PNG as the final fallback. - [ ] Images properly compressed. Quality settings of 75-85 for JPEG/WebP are usually visually indistinguishable from 100 but significantly smaller.
- [ ] No images larger than their display size. An image displayed at 400px wide should not be served as a 2000px file (unless accounting for 2x retina, in which case 800px is appropriate).
- [ ] Above-the-fold images have fetchpriority=”high”. Tell the browser to prioritize your hero image and LCP element.
- [ ] Below-the-fold images have loading=”lazy”. Defer loading images that aren’t visible until the user scrolls.
- [ ] Image dimensions specified. Include
widthandheightattributes on every<img>tag to prevent layout shift during loading. - [ ] SVG used for icons and logos. Vector graphics are resolution-independent and typically much smaller than raster equivalents for simple graphics.
- [ ] No massive hero images. Hero images should be under 200KB after compression and format optimization. If they’re larger, reconsider the design or increase compression.
- [ ] Image CDN considered. For sites with many images, an image CDN (Cloudinary, imgix) automates resizing, format conversion, and delivery optimization.
Font Performance
Custom fonts add personality but can hurt performance if not managed carefully.
- [ ] Total font payload under 100KB. Each font file (wght variation) is typically 20-40KB. Limit yourself to two weights and two styles maximum.
- [ ] font-display: swap used. Prevents invisible text while fonts load. The text appears immediately in a fallback font, then swaps when the custom font is ready.
- [ ] Fonts preloaded.
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>for fonts used above the fold. - [ ] WOFF2 format used. WOFF2 offers the best compression for web fonts. Serve WOFF as a fallback for very old browsers (if you need to support them).
- [ ] Font subsetting applied. If you only use Latin characters, subset your font to exclude Cyrillic, Greek, and other character sets. This can reduce font file sizes by 50% or more.
- [ ] System font stack considered. For body text, a system font stack (
system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif) loads instantly with zero payload. Reserve custom fonts for headings where brand identity matters most. - [ ] Variable fonts used when appropriate. If you need multiple weights, a single variable font file is often smaller than multiple static font files.
Core Web Vitals Targets
These are the metrics Google uses as ranking signals. Meet the “Good” thresholds.
- [ ] LCP under 2.5 seconds (target: under 2.0 seconds). Identify your LCP element on each page and optimize everything that affects its load time.
- [ ] INP under 200 milliseconds (target: under 100 milliseconds). Ensure click, tap, and keyboard interactions respond quickly by minimizing main thread blocking.
- [ ] CLS under 0.1 (target: under 0.05). Prevent layout shifts by specifying dimensions on images/embeds, avoiding dynamically injected content above existing content, and using CSS containment.
- [ ] FCP under 1.8 seconds. Ensure something meaningful appears quickly: critical CSS, server-side rendering, and fast TTFB all contribute.
- [ ] TBT under 200 milliseconds. Total Blocking Time correlates with INP. Reduce it by minimizing and deferring JavaScript.
Third-Party Impact
Third-party scripts are often the biggest performance problem and the hardest to control.
- [ ] Every third-party script justified. List every external script. If you can’t articulate why it’s there and what business value it provides, remove it.
- [ ] Third-party scripts loaded efficiently. Use
asyncordefer. Consider loading non-critical third-party scripts after the page is interactive (e.g., on user interaction or after a delay). - [ ] Google Tag Manager audited. If you use GTM, audit every tag. Remove unused tags. Set appropriate triggers (not “all pages” if a tag is only needed on specific pages).
- [ ] Chat widget deferred. Chat widgets are heavy (often 200KB+). Load them after the page is interactive or on user intent (scroll, mouse movement over a trigger area).
- [ ] Social embeds replaced with static alternatives. Instead of embedding a live Instagram feed (which loads the Instagram SDK), show static images that link to your social profiles.
- [ ] Impact of each third party measured. Use Chrome DevTools or WebPageTest to measure the specific performance impact of each third-party script. Document it so you can make informed decisions.
WordPress-Specific Optimizations
If you’re running WordPress, these additional checks apply.
- [ ] Caching plugin configured. WP Rocket, W3 Total Cache, or LiteSpeed Cache. Page caching is the single most impactful WordPress optimization.
- [ ] Unused plugins deactivated and deleted. Every active plugin can add CSS, JavaScript, and database queries. Audit quarterly.
- [ ] Plugin CSS/JS limited to relevant pages. Contact form plugin scripts should only load on pages with contact forms. Use Asset CleanUp or Perfmatters to control this.
- [ ] Database optimized. Clean up post revisions, spam comments, transients, and orphaned metadata. Use WP-Optimize or WP Sweep.
- [ ] PHP version current. PHP 8.2+ is significantly faster than older versions. Check with your host.
- [ ] Image optimization plugin active. ShortPixel, Imagify, or EWWW to handle automatic compression and WebP/AVIF conversion on upload.
- [ ] Lazy loading configured correctly. WordPress adds
loading="lazy"by default, but verify it’s not applied to above-the-fold images. - [ ] Page builder impact assessed. Page builders (Elementor, Divi, WPBakery) add significant CSS and JavaScript overhead. If performance is critical, consider building with cleaner tools (GeneratePress, custom theme, or a headless approach).
Build Process and CI/CD
Performance enforcement during development prevents regression.
- [ ] Performance budget defined. Specific limits for page weight, JavaScript, CSS, and Core Web Vitals metrics.
- [ ] Lighthouse CI integrated. Automated performance testing on every pull request. Build fails if budgets are exceeded.
- [ ] Bundle size monitoring. Track JavaScript and CSS bundle sizes over time. Alert when they grow unexpectedly.
- [ ] Assets minified in production. HTML, CSS, and JavaScript should all be minified in production builds.
- [ ] Source maps generated but not served publicly. Source maps help with debugging but add to download size if served to visitors. Generate them for error tracking services but don’t expose them publicly.
- [ ] Build produces optimized images. Image processing (resizing, format conversion, compression) should happen as part of the build process, not manually.
Post-Launch Monitoring
Performance optimization isn’t a one-time task. Monitor continuously.
- [ ] Google Search Console Core Web Vitals monitored. Check weekly for the first month after launch, then monthly. Address any pages flagged as “Needs Improvement” or “Poor.”
- [ ] Real User Monitoring (RUM) configured. The Web Vitals JavaScript library or a service like SpeedCurve collects performance data from actual visitors.
- [ ] Synthetic monitoring scheduled. Regular Lighthouse or WebPageTest runs to catch regressions between real-user data reports.
- [ ] Performance review included in content workflow. When new content is published (blog posts, pages), verify it meets performance standards. Large unoptimized images in blog posts are a common post-launch regression.
- [ ] Quarterly performance audit scheduled. Full re-audit of performance every three months. Technologies change, content grows, and third-party scripts update. Ongoing attention is required.
The Quick-Win Prioritization
If you can’t do everything at once, here are the optimizations ranked by impact-to-effort ratio:
High Impact, Low Effort
- Enable Brotli/Gzip compression
- Add lazy loading to below-the-fold images
- Optimize and compress images (even just running them through Squoosh or ShortPixel)
- Remove unused plugins and their scripts
- Add
fetchpriority="high"to LCP images - Set browser caching headers
- Switch to WOFF2 fonts with font-display: swap
High Impact, Moderate Effort
- Implement responsive images with srcset/sizes
- Serve modern image formats (WebP, AVIF)
- Implement critical CSS
- Configure a CDN
- Audit and defer third-party scripts
- Implement code splitting for JavaScript
- Set up server-side caching (for WordPress/dynamic sites)
High Impact, Higher Effort
- Rebuild with lighter technology (replace heavy page builder or framework)
- Implement image CDN
- Set up CI/CD with performance budget enforcement
- Implement real user monitoring
- Complete JavaScript audit and rewrite
The Standard We Hold Ourselves To
Every website we launch at Hunter Creative Media goes through this checklist. Not every item applies to every project, but the principles behind them do: serve only what’s needed, serve it as fast as possible, and measure to make sure it stays that way.
Performance isn’t a feature you add at the end. It’s a discipline you maintain from the first line of code to every content update after launch. The sites that are fast today and still fast a year from now are the ones built by teams that treat performance as a core value, not an afterthought.