The gap between the first byte (TTFB) and the first visual paint (FCP) is where most performance budgets are broken. Optimizing only the frontend is no longer enough — modern applications demand a full‑stack strategy. In this guide, we explore how to reduce latency from the moment a user clicks a link until the browser renders meaningful content. From database queries and serverless cold starts to HTTP/3, early hints, and speculative loading — every layer matters. Let's shrink the critical path together.
Before optimizing, we must understand the timeline: Time To First Byte (TTFB) measures server responsiveness (DNS, TCP/TLS, request queuing, backend processing). First Contentful Paint (FCP) marks when any text or image appears. The delta between TTFB and FCP is dominated by resource fetching, parsing, and rendering. Full‑stack optimization targets both ends: minimize server processing and network latency, then accelerate the browser's critical rendering path.
TTFB includes routing, authentication, database queries, template rendering, and network transit. Advanced techniques include database indexing & query optimization, caching (Redis, CDN edge), asynchronous non‑blocking I/O, and server‑side streaming (early flush).
-- Before: full table scan (slow)
SELECT * FROM orders WHERE user_id = 1234 AND status = 'pending';
-- After: composite index reduces TTFB by 80%
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- Use EXPLAIN ANALYZE to verify.
const redis = require('ioredis');
const client = new redis(process.env.REDIS_URL);
async function getUserProfile(userId) {
const cached = await client.get(`user:${userId}`);
if (cached) return JSON.parse(cached);
const user = await db.users.findUnique({ where: { id: userId } });
await client.setex(`user:${userId}`, 300, JSON.stringify(user));
return user;
}
Modern CDNs do more than cache static assets. Edge networks now execute logic (Edge Workers), terminate TLS closer to users, and support Anycast routing. Additional techniques include HTTP/3 (QUIC) for faster connection establishment, TLS 1.3 session resumption, and preconnect for third‑party origins.
// Edge worker: cache API responses with custom logic
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const url = new URL(request.url);
const cacheKey = new Request(url, request);
let response = await caches.default.match(cacheKey);
if (!response) {
response = await fetch(request);
response = new Response(response.body, response);
response.headers.set('Cache-Control', 'public, max-age=60');
event.waitUntil(caches.default.put(cacheKey, response.clone()));
}
return response;
}
The 103 Early Hints status code allows the server to send resource hints before the final response.
This dramatically reduces FCP because the browser can start fetching critical CSS, fonts, or images while the backend
is still generating the HTML.
app.get('/product/:id', async (req, res) => {
// Send early hints immediately
res.writeHead(103, {
Link: '; rel=preload; as=style',
Link: '; rel=preload; as=script',
Link: '; rel=preload; as=image'
});
// Simulate slow backend data fetching
const data = await fetchProductData(req.params.id);
res.render('product', { data });
});
Traditional SSR waits for the entire HTML to be generated before sending the first byte. Streaming SSR (React 19+ / Vue 3.5+) sends the document shell immediately and streams content as it becomes ready. This reduces TTFB and FCP dramatically, especially for slow backend data dependencies.
import { renderToPipeableStream } from 'react-dom/server';
function handleRequest(req, res) {
const stream = renderToPipeableStream(<App />, {
onShellReady() {
res.setHeader('Content-Type', 'text/html');
stream.pipe(res);
},
onError(err) { console.error(err); }
});
}
Once the HTML arrives, the browser must discover resources. Help it by using: preload (high‑priority, needed now), preconnect (early handshake for third‑party origins), prefetch (low‑priority for next navigation), and modulepreload (for ES modules).
<!-- Preload hero background image -->
<link rel="preload" as="image" href="hero.avif">
<!-- Preconnect to analytics & CDN -->
<link rel="preconnect" href="https://api.example.com" crossorigin>
<!-- Prefetch next page likely to be visited -->
<link rel="prefetch" href="/checkout" as="document">
CSS is render‑blocking by default. Extract critical CSS (above‑the‑fold styles) and inline it in the <head>.
Defer non‑critical CSS using media="print" or JavaScript `onload` tricks.
Modern tools like Critters (Webpack) or PurgeCSS automate this.
<link rel="preload" href="/styles/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles/main.css"></noscript>
<style>/* Inlined critical CSS for header, hero */</style>
Script tags can delay FCP. Use async for independent scripts (e.g., analytics), defer for scripts
that need DOM readiness but shouldn't block parsing. For ES modules, modulepreload fetches modules in parallel.
<script defer src="/app.js"></script>
<script async src="https://analytics.com/tracker.js"></script>
<link rel="modulepreload" href="/vendor/react.js">
Serverless and edge functions (Cloudflare Workers, Vercel Edge, AWS Lambda@Edge) bring compute closer to users, reducing TTFB from hundreds of milliseconds to single digits. Use them for personalization, A/B testing, or API aggregation without a full origin roundtrip.
export const config = { runtime: 'edge' };
export default async function handler(req) {
const url = new URL(req.url);
const response = await fetch(`https://origin.com${url.pathname}`);
const html = await response.text();
const optimized = html.replace('', '<link rel="preload" href="/critical.css" as="style">');
return new Response(optimized, {
headers: { 'Content-Type': 'text/html' }
});
}
Images are the largest contributors to FCP delays. A full‑stack approach includes:
on‑the‑fly resizing (image CDN), automatic WebP/AVIF conversion,
responsive images (srcset), and lazy loading below the fold.
Use the <picture> element with modern formats.
<picture>
<source type="image/avif" srcset="hero.avif">
<source type="image/webp" srcset="hero.webp">
<img src="hero.jpg" alt="full stack optimization" loading="eager" decoding="sync">
</picture>
The modern Speculation Rules API allows the browser to prerender entire pages before the user clicks. Combine with machine learning to predict next actions, making subsequent navigations feel instant.
<script type="speculationrules">
{
"prerender": [
{
"source": "list",
"urls": ["/dashboard", "/product/featured"],
"eagerness": "moderate"
}
],
"prefetch": [
{
"source": "document",
"where": { "href_matches": "/category/*" },
"eagerness": "eager"
}
]
}
</script>
Optimizing blindly is dangerous. Collect real‑world TTFB and FCP using the Navigation Timing API and PerformanceObserver. Send data to RUM providers (Datadog, New Relic, SpeedCurve) to identify regional bottlenecks and deploy targeted fixes.
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name === 'first-contentful-paint') {
console.log('FCP:', entry.startTime);
// send to analytics
}
}
}).observe({ type: 'paint', buffered: true });
// TTFB from Navigation Timing
window.addEventListener('load', () => {
const nav = performance.getEntriesByType('navigation')[0];
const ttfb = nav.responseStart - nav.requestStart;
console.log('TTFB:', ttfb);
});
Full‑stack optimization is not a single silver bullet — it's a layered approach. Start by measuring real user metrics, then reduce TTFB via database tuning, caching, and edge compute. Improve network efficiency with HTTP/3, CDN, and early hints. Finally, accelerate the browser's rendering with critical CSS, resource hints, speculative loading, and modern image formats. When every layer works in harmony, TTFB drops below 100ms, FCP becomes nearly instantaneous, and users enjoy a frictionless experience.
Remember: performance is a system property. The best backend in the world won't save a bloated frontend, and vice versa. Embrace a culture of performance budgets, automated testing, and continuous monitoring. Your users — and your business metrics — will thank you.