Top Organic Leads

The Tech Stack Behind 100/100 PageSpeed Scores

Every tool, config, and technique we use to achieve perfect Google PageSpeed scores on every client site — with analytics and call tracking fully active.

Live Document— This guide is continuously updated as we optimize real client sites.

Last updated: May 30, 2026 at 7:46 PM UTC

AI-agent ready. Share this article with your coding agent and say: "Read this guide, run the detect commands on my project, and create an implementation plan for the fixes that apply."

Every website we build or optimize uses the same battle-tested stack. It's not experimental — it's the result of optimizing many real-world sites to perfect 100/100 PageSpeed scores on mobile, all with Google Analytics and call tracking fully active.

This article breaks down every tool in our stack and explains why each piece matters for performance.

Next.js 16 (App Router)

Next.js is the foundation. We use the App Router with React Server Components, which fundamentally changes how JavaScript reaches the browser.

Why it matters for speed:

  • Server Components render to pure HTML on the server. The browser receives ready-to-display markup with zero JavaScript hydration cost for static sections like headers, footers, and content areas.
  • Automatic code-splitting ensures only the JavaScript needed for the current page is loaded. Visit the homepage? You don't download the contact page's form validation library.
  • Static Site Generation (SSG) compiles pages into static HTML files at build time. When a user visits, they get an instant response from the CDN edge — no server computation, no database queries.
  • Turbopack (the Rust-based bundler) handles compilation, producing optimized bundles with tree-shaking that eliminates dead code paths.

The Server Component advantage:

On a traditional React site, every component ships its JavaScript to the browser for "hydration." On a page with 15 components, that's 15 bundles the browser must download, parse, and execute before the page becomes interactive.

With Server Components, only interactive components (forms, carousels, toggle menus) ship JavaScript. Everything else — headings, paragraphs, images, static layouts — renders as pure HTML. On our sites, this typically means 3-4 client components per page instead of 15+.

Vercel Edge Network

We deploy exclusively on Vercel's edge network. Every page is served from the CDN node closest to the visitor.

Why it matters for speed:

  • Time to First Byte (TTFB): Static pages served from edge nodes typically achieve TTFB under 50ms — compared to 200-800ms for traditional server-rendered WordPress sites hitting a MySQL database.
  • Global distribution: Vercel has edge nodes on every continent. A visitor in Tokyo gets the same sub-50ms TTFB as a visitor in New York.
  • Image optimization at the edge: The /_next/image endpoint processes and caches images at the edge, so subsequent requests for the same image dimensions are instant cache hits.

Vercel Blob Storage (Asset CDN)

All heavy assets — images, videos, PDFs, fonts — are hosted on Vercel Blob Storage, a globally distributed CDN. We never commit binary files to the Git repository.

Why it matters for speed:

  • Separation of concerns: Code deploys are fast (seconds) because they don't include hundreds of megabytes of images.
  • CDN caching: Assets are cached at edge nodes worldwide with long TTLs (1 year). After the first request, every subsequent visitor gets the asset from cache — zero origin server contact.
  • Pre-optimized pipeline: For maximum performance, we maintain a separate S3_OPT bucket with pre-optimized WebP images at target dimensions. These are served with the unoptimized prop in next/image, bypassing the Lambda processing entirely and eliminating cold-start latency.
// lib/s3.ts
export const S3 = 'https://STORE.public.blob.vercel-storage.com/project/';
export const S3_OPT = 'https://STORE.public.blob.vercel-storage.com/project-opt/';

// Usage — zero Lambda cost:
// <Image src={`${S3_OPT}assets/hero.webp`} width={1200} height={675} sizes="100vw" unoptimized />

SVGs stay on the original S3 path — they don't benefit from WebP conversion and unoptimized is unnecessary for them.

next/image (Responsive Image Delivery)

Every image on our sites goes through Next.js's <Image> component. This is non-negotiable.

What it does automatically:

  • Format conversion: Serves AVIF (30-50% smaller than JPEG) to browsers that support it, falling back to WebP.
  • Responsive srcsets: Generates multiple image sizes (640px, 750px, 828px, 1080px, 1200px, 1920px) so the browser downloads only the size it needs. An iPhone SE downloads a 750px image, not a 1920px desktop version.
  • Lazy loading: Images below the fold load only when the user scrolls near them, preserving bandwidth for the critical above-fold content.
  • Cache headers: Processed images get minimumCacheTTL: 31536000 (1 year) at the CDN edge.

The sizes prop — the most common mistake:

Without a sizes prop, next/image defaults to sizes="100vw" and the browser downloads the largest srcset entry (up to 3840px) even when the image displays at 665px. We always specify exact sizes matching the component's container width:

sizes="(max-width: 768px) 100vw, 640px"

This single prop can save 100-300KB per image.

AVIF + WebP Image Formats

We configure every project to serve AVIF first, with WebP as fallback:

// next.config.ts
images: {
  formats: ['image/avif', 'image/webp'],
  minimumCacheTTL: 31536000,
  qualities: [22, 55, 75],
}

The qualities array is required in Next.js 15+ — any quality value used on an <Image> component must be explicitly allowlisted here. Without it, the image optimizer returns a 400 Bad Request and the image silently fails to load.

Real-world size comparison (hero background image, 750px wide):

FormatSize
JPEG (default)~24 KB
WebP~12 KB
AVIF~6.6 KB

AVIF delivers a 72% reduction compared to JPEG at perceptually identical quality. On a 1.6 Mbps throttled mobile connection (which is what PageSpeed simulates), this is the difference between a 120ms image load and a 33ms image load.

Tailwind CSS v4

We use Tailwind CSS for all styling with a utility-first approach.

Why it matters for speed:

  • Tree-shaking: Tailwind v4 scans source files and generates CSS only for the classes actually used. A complex site with 720 unique classes produces ~84KB of CSS — but gzipped, that's only ~20KB.
  • Inline CSS (inlineCss: true): We inline the entire CSS bundle into the HTML stream. This sounds counterintuitive (bigger HTML!), but it eliminates a render-blocking round-trip. Without inline CSS, the browser must download an external .css file before it can paint anything. On mobile, that extra round-trip costs 200-400ms of blocked rendering.
  • Design tokens: We define a consistent typography scale and color palette in @theme blocks, reducing the number of unique CSS rules generated.

Critical rule: inlineCss: true must never be disabled without benchmarking. On one project, disabling it to "reduce HTML size" caused LCP to regress from 1.1s → 2.6s. The 83.8KB of inline CSS is a false economy concern — the external CSS file creates a render-blocking round-trip that always hurts LCP more than the larger HTML payload.

inlineCss: trueinlineCss: false
CSS deliveryInline in HTML <head> (immediate)External file (blocking round-trip)
LCP (measured)1.1s2.6s ❌
HTML size+83.8 KBUnchanged

Server-Side Google Analytics (GA4 Measurement Protocol)

This is our biggest single optimization. Traditional gtag.js is 171KB of client-side JavaScript. Even with lazyOnload, it loads during PageSpeed's measurement window and is flagged as "unused JavaScript."

Our replacement: ~1KB total client code.

Instead of loading Google's tracking library in the browser, we send analytics data server-side:

  1. A lightweight client module (~1KB) captures page views and sends them via navigator.sendBeacon to our own /api/analytics endpoint.
  2. The server-side API route forwards events to GA4 via the Measurement Protocol v2 — authenticated with an API secret.
  3. The browser never contacts google-analytics.com or googletagmanager.com.

What we preserve: All page views, session tracking, and SPA navigation tracking via usePathname().

What we trade: Automatic scroll depth, outbound click tracking, enhanced measurement, and Google Ads remarketing. For most lead generation sites, page views and form submissions are the only metrics that matter.

Font Optimization Pipeline

Fonts are a hidden LCP killer. Every font file preloaded competes with the hero image for bandwidth on PageSpeed's throttled 1.6 Mbps connection.

Our font rules:

  • Max 2 font families per project (e.g., one sans-serif body + one display/heading font). On one project, 8 font preloads across 5 families totaled 388KB — consuming 2+ seconds of bandwidth on PSI and causing 4.1s LCP.
  • ≤3 font files total, ≤50KB combined. Every KB of font preload is a KB the hero image can't use.
  • Variable fonts over static. A variable font serves all weights from a single file. Switching from a static font (4 weight files, 77KB) to a variable alternative (1 file, 33KB) saved 44KB.
  • woff2 format only. We convert all TTF files to woff2 using fonttools + brotli — 69% smaller:
pip3 install fonttools brotli --break-system-packages
for f in public/fonts/**/*.ttf; do
  python3 -c "
from fontTools.ttLib import TTFont
font = TTFont('$f'); font.flavor = 'woff2'; font.save('${f%.ttf}.woff2')
"
done
  • Fonts hosted on Blob CDN, never committed to Git. Referenced via @font-face in globals.css with font-display: optional.
Font budgetThreshold
Max font families2
Max font files preloaded3
Max combined font size50 KB
Formatwoff2 only

DeferredClientShell Pattern

Components like cookie banners, navigation loaders, and chat widgets have zero effect on the initial visual render — but if imported eagerly in layout.tsx, they add to the critical-path JS bundle and increase FCP.

Our pattern: A single "use client" wrapper component holds all ssr: false dynamic imports:

// components/deferred-client-shell.tsx
"use client";
import dynamic from "next/dynamic";

const NextTopLoader = dynamic(() => import("nextjs-toploader"), { ssr: false });
const CookieConsent = dynamic(
  () => import("@/components/cookie-consent").then((m) => m.CookieConsent),
  { ssr: false }
);

export function DeferredClientShell() {
  return (
    <>
      <NextTopLoader color="#dc5a31" height={3} showSpinner={false} />
      <CookieConsent />
    </>
  );
}

Imported once in layout.tsx, this removes those components from the initial JS bundle entirely. Less main-thread work at FCP → faster Speed Index.

content-visibility: auto (TBT Reduction)

Below-fold sections force the browser to run Style & Layout computation for content thousands of pixels off-screen. On complex pages, this can add 2-3 seconds of main-thread work.

We apply content-visibility: auto to every below-fold section wrapper:

/* globals.css */
.content-lazy {
    content-visibility: auto;
    contain-intrinsic-size: auto 600px;
}
// page.tsx
<Hero />                                              {/* LCP — NO content-lazy */}
<div className="content-lazy"><Services /></div>      {/* below fold ✅ */}
<div className="content-lazy"><Testimonials /></div>  {/* below fold ✅ */}
<div className="content-lazy"><Footer /></div>        {/* below fold ✅ */}

The browser skips layout computation for .content-lazy sections until they approach the viewport, dramatically reducing Total Blocking Time (TBT) for real users.

PageSpeed caution: content-visibility: auto is a real-user optimization only. PageSpeed's Speed Index is calculated from screenshots during a simulated scroll — deferred sections appear as blank rectangles, causing Speed Index to spike. A real-world 100/100 site collapsed to 72 after adding content-visibility: auto to 5 below-fold sections. Use it for real-user performance, but be aware it is fundamentally incompatible with PageSpeed's screenshot-based measurement.

AI-Powered Optimization Workflow

This is what makes our process fundamentally different from other agencies. We pair autonomous AI agents with hands-on human expertise — the agents execute at scale, but the human drives the loop with real-world diagnostics that no automated tool can replicate.

Our tooling:

  • Antigravity — Google DeepMind's agentic coding system. It reads our optimization playbook, implements fixes across the entire codebase, runs verification builds, and iterates. What takes a human team days, an agent completes in hours with zero missed regressions.
  • Claude Opus 4.6 — Anthropic's reasoning model powering Antigravity's decision-making. It handles the nuanced judgment calls: which preload strategy fits this specific page, whether a "use client" directive is actually needed, when to use decoding="auto" vs decoding="async". These aren't template fixes — they require understanding how 15+ browser behaviors interact.
  • Chrome DevTools MCP — Our agents connect directly to a real Chrome instance via the Model Context Protocol for automated traces and bottleneck identification.

Why human interaction is essential:

AI agents are powerful executors, but they can't open your production site and see what the browser actually does. The critical diagnostic step is human-driven: we paste specific scripts into Chrome DevTools Console on the live site and feed the raw output back to the agent. This is where the real optimization happens.

For example, our LCP diagnostic script (paste in Console, get instant results):

new Promise(r => {
  new PerformanceObserver(l => {
    const e = l.getEntries().at(-1);
    r({ element: e?.element?.tagName + ' ' + e?.element?.className?.substring(0, 60),
        url: e?.url, startTime: Math.round(e?.startTime),
        renderTime: Math.round(e?.renderTime), size: e?.size });
  }).observe({ type: 'largest-contentful-paint', buffered: true });
  setTimeout(() => r('timeout'), 6000);
}).then(console.log)

That output tells the agent exactly which element is slow and why — is it a /_next/image cold Lambda? A font swap updating LCP? A carousel slide the browser shouldn't have picked? The agent then implements the precise fix, but it's the human-provided console data that makes the diagnosis accurate.

The loop:

  1. Human runs diagnostic scripts on the live site → pastes output to the agent
  2. Agent reads our optimization playbook (2,800+ lines of battle-tested rules) and interprets the diagnostics
  3. Agent implements the fix across all affected files, builds, and verifies
  4. Human re-runs PageSpeed and console scripts → confirms the fix worked or provides new data
  5. Repeat until target score is achieved

Every rule in our playbook started as a real discovery from this human-agent feedback loop. The agent finds patterns across codebases at scale; the human validates them against real browser behavior. Neither works as well alone — together, they're how we optimize entire portfolios of sites simultaneously.

pnpm (Package Manager)

We use pnpm instead of npm or yarn for strict dependency resolution.

Why it matters:

  • Strict mode: pnpm prevents "phantom dependencies" — packages that work by accident because a transitive dependency happens to install them. This catches unused or misconfigured packages early.
  • Smaller node_modules: pnpm uses hard links and a content-addressable store, reducing disk usage by 50-70% compared to npm.
  • Faster installs: CI/CD builds are 2-3x faster, which matters when we're iterating on performance optimizations and rebuilding frequently.

LCP <Image> Props Reference (Next.js 16)

The LCP image is the single most impactful element on your PageSpeed score. In Next.js 16 with React 19, the correct prop combination is critical — wrong props cause duplicate preloads, delayed decoding, or missing fetchpriority signals.

The exact prop set that achieves 100/100:

<Image
    src={lcpImageUrl}
    alt="Descriptive alt text"
    fill={true}           // for full-bleed hero; use width/height for fixed-size images
    priority={true}       // generates <link rel="preload" fetchpriority="high"> in <head>
    fetchPriority="high"  // also adds fetchpriority="high" to <img> element itself
    decoding="auto"       // browser chooses sync-decode for small images → LCP ≈ FCP
    quality={55}          // explicit; must be in next.config.ts qualities[]
    sizes="100vw"         // required; prevents downloading 1920px image for 375px screen
    className="object-cover"
/>

Why each prop matters:

  • priority={true} — generates a <link rel="preload"> in the HTML <head> so the browser discovers the image before parsing the body.
  • fetchPriority="high" — in Next.js 16, fill={true} + priority={true} generates the preload but skips adding fetchpriority to the <img> element. This prop adds it explicitly.
  • decoding="auto" — overrides Next.js's default decoding="async", which queues the image decode as a background task. For small hero images (<30KB), auto lets the browser decode synchronously so the image appears in the same frame as FCP.
  • quality={N} — in Next.js 16 with React 19, omitting this causes two separate preloads at different quality values (one from SSR, one from React 19's ReactDOM.preload()), splitting bandwidth and doubling the LCP download cost.

LCP image checklist:

CheckRule
priority={true}Preload link with fetchpriority in <head>
fetchPriority="high"fetchpriority attribute on the <img> element
decoding="auto"Sync decode for small hero images (<30KB)
quality={N}Explicit value present in next.config.ts qualities array
sizesAccurate to actual rendered dimensions
No loading="lazy"Never lazy-load the hero image
No will-change: transformCauses FCP→LCP gap by forcing compositor layer
No CSS animationChrome measures LCP at animation end, not first paint

The Full Stack at a Glance

LayerToolImpact
FrameworkNext.js 16 (App Router)Server Components = zero hydration for static content
HostingVercel EdgeSub-50ms TTFB globally
AssetsVercel Blob Storage + S3_OPTCDN-cached, pre-optimized images
Imagesnext/image + AVIF72% smaller than JPEG, responsive srcsets
LCP ImageOptimized <Image> props (Next.js 16)priority + fetchPriority + decoding + explicit quality
StylingTailwind CSS v4 (inlineCss: true)Inline CSS eliminates render-blocking round-trip
Fontswoff2 + variable fonts + ≤50KB budget69% smaller than TTF, max 2 families
AnalyticsServer-side GA4~1KB client JS (replaces 171KB gtag.js)
Client ShellDeferredClientShellCookie banners, loaders deferred from critical path
TBT Reductioncontent-visibility: autoSkips layout for off-screen sections (real-user only)
AI AgentsAntigravity + Claude Opus 4.6Autonomous optimization: diagnose → implement → verify
ProfilingChrome DevTools MCPAI-powered 30-second performance diagnosis
Version ControlGitHub + Vercel CI/CDAuto-deploy on push, instant rollback
Package ManagerpnpmStrict deps, fast installs

Every piece is chosen for one reason: it makes the Largest Contentful Paint faster. LCP is the metric that determines your PageSpeed score, your Core Web Vitals pass/fail, and ultimately your search ranking.

Want to See the Results?

Visit our main speed optimization page to see 10 live showcases of sites we've optimized to 100/100 — with full PageSpeed screenshots and Chrome Performance traces.

Or dive into our optimization guides:

Want a Perfect 100/100?
Let Us Handle It.

Our team has achieved 100/100 PageSpeed scores on many real-world sites with Google Analytics and CallRail fully active. We'll do the same for yours.

Get a Perfect 100/100 PageSpeed Score

Services I'm interested in:

Top Organic Leads

Risk-free lead generation. We only get paid when your business gets new customers.

Address

333 City Blvd West Suite #1722

Orange, CA 92868

Hours

Mon – Fri

8:00 AM – 5:00 PM

©2026 Top Organic Leads. All rights reserved.