/ Agent Compat Fixes / Agent Rendering

How to Fix Slow Rendering for Agents

Agents fetch your page, parse it, extract facts, return to the LLM for the user's reply. Every second your page takes is a second the user waits for ChatGPT or Perplexity to answer. User-triggered browsing agents budget aggressively — typically 5-10 seconds total. If your page can't deliver useful HTML in that window, the agent gives up and tells the user "couldn't find it". This guide covers shrinking the render path.

1. The agent latency budget

Agent typeTTFB targetFCP targetTotal
Crawler (GPTBot, ClaudeBot)< 2 sn/a (raw HTML)< 10 s
User browsing (ChatGPT-User)< 800 ms< 2.5 s< 8 s
User browsing (Perplexity-User)< 600 ms< 1.8 s< 5 s
Mobile agent over 4G< 1 s< 3 s< 10 s

2. Measure current

Step 1
curl with timing
curl -w "@-" -o /dev/null -s https://example.com/ <<'EOF'
    time_namelookup:  %{time_namelookup}s
       time_connect:  %{time_connect}s
    time_appconnect:  %{time_appconnect}s
   time_pretransfer:  %{time_pretransfer}s
      time_redirect:  %{time_redirect}s
 time_starttransfer:  %{time_starttransfer}s    <-- this is TTFB
                     ----------
         time_total:  %{time_total}s
EOF
Step 2
WebPageTest from agent geographies
webpagetest.org with Test Location set to US-East or EU-West (where most AI infrastructure lives). Run with cache disabled, no JS execution checkbox for crawler emulation.

3. Eliminate slow path components

Slow DB query on render

// Bad: synchronous DB query before any HTML sends
const products = await db.query('SELECT ...');  // 800ms
return renderTemplate({ products });            // total TTFB: 800ms+

// Good: cached query + streaming
const products = await cache.getOrSet('products', 
  () => db.query('SELECT ...'), 
  { ttl: 60 }
);  // 5ms when cached
return renderTemplate({ products });

Slow API call on render

// Bad: blocking on third-party
const personalisedRecs = await fetch('https://thirdparty.com/api/recs');
// → adds 300-2000ms unpredictably

// Good: render without, hydrate after
return (
  <Layout>
    <ProductGrid /> {/* server-rendered */}
    <LazyHydrate>
      <PersonalisedRecs /> {/* loads client-side */}
    </LazyHydrate>
  </Layout>
);

Large JS bundle blocking parse

<!-- Bad: JS in head, no defer/async -->
<script src="/bundle.js"></script>

<!-- Good: defer ensures HTML parses first -->
<script src="/bundle.js" defer></script>

<!-- Better: only ship what's needed -->
<script src="/critical.js" defer></script>
<script src="/secondary.js" defer async></script>

4. Edge cache for public pages

# Cloudflare page rule / cache rule
Match: example.com/*
Cache Level: Cache Everything
Edge TTL: 1 hour (or longer for static content)
Browser TTL: 10 minutes

# Bypass for authenticated requests
Cookie: session_id → bypass cache

# Result: first byte from CDN edge (~50ms)
# Origin only hit on cache miss or for logged-in users

Public marketing/content pages on CDN edge cache typically deliver TTFB < 100ms regardless of origin speed. Single most impactful fix.

5. Server-side render critical content

See Fix JS-Only Content. SSR replaces "blank shell + JS fetch + render" with "HTML arrives with content". Saves a network round-trip + JS parse + JS execute = typically 1-3 seconds saved.

6. Optimised images don't block render

<!-- Lazy-load below-the-fold -->
<img src="hero.webp" alt="..." width="800" height="400" />
<img src="..." loading="lazy" alt="..." width="..." height="..." />

<!-- Modern formats -->
<picture>
  <source srcset="hero.avif" type="image/avif" />
  <source srcset="hero.webp" type="image/webp" />
  <img src="hero.jpg" alt="..." />
</picture>

7. Optional: lighter response for agents

For maximum speed, detect agent UAs and serve a stripped HTML version:

// Express middleware
app.use((req, res, next) => {
  const ua = req.get('User-Agent') || '';
  if (/GPTBot|ClaudeBot|PerplexityBot|CCBot/i.test(ua)) {
    req.agentMode = true;
  }
  next();
});

// In route
if (req.agentMode) {
  return res.render('product-lite', { product });
  // Just title, description, price, schema. No JS, no images, no CSS.
  // Renders in < 100ms even from origin.
} else {
  return res.render('product-full', { product });
}

Not cloaking — the content is the same; only the delivery format differs. Allowed by Google and aligned with what agents need.

8. Verify after fixes

Step 1
curl as each agent
for ua in "GPTBot/1.0" "ClaudeBot/1.0" "PerplexityBot/1.0"; do
  time curl -s -A "$ua" https://example.com/ -o /dev/null
done

# All should complete in < 2 seconds for TTFB
Step 2
Re-run audits
Run Agent Compat audit + Core Web Vitals + Page Speed. All three should improve from the same underlying fixes.
💡 If you can only do one thing: put a CDN in front of your site with "cache everything" for non-authenticated public pages. TTFB drops from 600ms to 50ms instantly. Most agent rendering complaints disappear at the edge.

🤖 Re-run Agent Compat audit

Verify rendering completes within agent timeout windows.

Run Agent Compat →
Related Guides: Agent Compat Fixes  ·  Fix JS-Only Content  ·  Core Web Vitals Guide
💬 Got a problem?