WordPress Performance FAQ
My cached WordPress pages are fast, but checkout, search, and account pages are still slow. Why does caching not help there?
Is the reason that page caching can only avoid WordPress execution for cacheable public pages, while dynamic requests like checkout, search results, logged-in account pages, AJAX, or personalized sessions still have to run WordPress, plugins, hooks, database queries, and application logic for each request?
Yes — that is essentially the core reason.
Page caching works by storing the fully rendered HTML output of a request and serving that HTML directly on subsequent requests, bypassing most or all of the WordPress stack. This is highly effective for public pages where every visitor should see the same content.
For dynamic pages, however, the response depends on the current user, session, request parameters, cart contents, or real-time data. Because the output is not universally reusable, page caching is usually disabled or bypassed.
What happens on a cached public page
For a cache hit:
- Web server receives request.
- Cached HTML is found.
- HTML is returned immediately.
- WordPress core, plugins, theme code, hooks, and most database queries are skipped.
This removes nearly all PHP and WordPress execution overhead.
What happens on checkout, account, and search pages
For a dynamic request:
- Web server receives request.
- Cache is bypassed.
- WordPress loads.
- Active plugins load.
- Hooks and filters execute.
- User/session state is loaded.
- Database queries run.
- Business logic executes.
- HTML is generated and returned.
Every request repeats this process.
Examples
WooCommerce checkout
The page depends on:
- Current cart contents
- Customer address
- Shipping calculations
- Tax calculations
- Payment gateway state
- Coupons
- Session data
Two visitors rarely have identical checkout pages, so serving a shared cached HTML page would be incorrect.
Logged-in account pages
The page may show:
- User name
- Orders
- Account details
- Membership status
- Personalized content
A cache serving one user's account page to another user would be a serious security issue.
Search results
Results depend on:
- Search query
- Filters
- Sort order
- User permissions
- Inventory status
Each search can generate a unique page.
AJAX and API requests
Many plugins use:
admin-ajax.php- REST API endpoints
- Background requests
These often execute PHP and database logic on every request and are typically outside normal page caching.
Why dynamic pages can still be slow even when public pages are fast
Once page caching is removed from the equation, performance depends on:
- PHP execution time
- Plugin efficiency
- Database query speed
- Number of hooks executed
- External API calls
- Session management
- Object cache hit rate
For example, a WooCommerce checkout page may execute hundreds of hooks and dozens of database queries even though your homepage is served in a few milliseconds from cache.
Other caching layers can still help
Even when page caching cannot be used, other caches may reduce the cost:
-
Object caching (Redis, Memcached)
- Caches database query results and WordPress objects.
-
Database query caching
- Reduces repeated expensive queries.
-
Opcode caching (OPcache)
- Prevents PHP scripts from being recompiled on each request.
-
Fragment caching
- Caches portions of a page while leaving personalized sections dynamic.
-
CDN caching
- Offloads static assets such as images, CSS, and JavaScript.
These don't eliminate WordPress execution entirely, but they can significantly reduce the amount of work performed during dynamic requests.
So your statement is correct: page caching mainly helps when the same HTML can be reused across visitors. Dynamic requests such as checkout, search, logged-in account pages, AJAX endpoints, and personalized sessions generally still require WordPress, plugins, hooks, database access, and application logic to execute for each request, which is why they often remain the slowest parts of a WordPress site.
That makes sense. Page caching avoids WordPress execution only when the full HTML response can be reused. For checkout, search, account pages, AJAX, and personalized sessions, WordPress still has to run.
But if these dynamic requests still load WordPress, the theme, active plugins, hooks, sessions, database access, and application logic, are object caching, OPcache, and fragment caching still mainly cost-reduction layers?
In other words, they make parts of the remaining work cheaper, but they do not necessarily answer whether all of that WordPress/plugin runtime should participate in the request in the first place.
Would the deeper optimization layer for these uncached requests be execution-scope reduction: identifying the request type early and preventing unrelated plugins, hooks, services, and PHP code from entering the request lifecycle at all?
Yes. You're drawing an important distinction between making work cheaper and eliminating work entirely.
Layer 1: Cost reduction
Object cache, OPcache, database tuning, Redis, fragment caching, and CDN optimization generally belong to the "cost reduction" category.
They answer:
"Given that this code is going to run, how can we make it run faster?"
Examples:
- OPcache: avoids reparsing and recompiling PHP files.
- Object cache: avoids repeating expensive database queries.
- Fragment cache: avoids regenerating expensive sections of output.
- Database indexes: make queries cheaper.
- Persistent connections: reduce connection overhead.
The request still traverses largely the same execution graph. The graph is simply less expensive.
Layer 2: Execution-scope reduction
What you're describing is a deeper optimization strategy:
"Should this code be participating in the request at all?"
This is often where the largest gains exist for dynamic WordPress workloads.
For example, imagine a checkout request:
/checkout
The request may currently load:
- WooCommerce
- SEO plugin
- Form builder
- Analytics plugin
- Membership plugin
- Learning management plugin
- Backup plugin
- Page builder integrations
- Various plugin bootstraps
Even if many of these plugins do little work later, they still:
- load PHP files
- register hooks
- instantiate objects
- add filters
- evaluate conditions
before eventually deciding they have nothing meaningful to contribute.
Execution-scope reduction tries to prevent that participation earlier.
The ideal performance question
Instead of asking:
"How fast can we execute 100 units of work?"
You ask:
"Why are we executing 100 units of work when only 20 are needed?"
That shift often produces larger wins than another layer of caching.
Where WordPress makes this difficult
WordPress was designed around a highly dynamic hook system.
A plugin can register:
add_action('init', ...);
add_action('wp', ...);
add_filter('the_content', ...);
and WordPress generally cannot know in advance whether those callbacks matter for the current request.
As a result, WordPress tends toward:
- Load plugin.
- Register hooks.
- Execute lifecycle.
- Discover whether work was actually needed.
rather than:
- Determine request requirements.
- Load only required components.
This architecture favors flexibility and compatibility over minimal execution scope.
Why enterprise frameworks often outperform WordPress on dynamic requests
Modern frameworks frequently support:
- dependency injection containers
- lazy service loading
- route-based middleware
- request-specific service registration
A route might look like:
/checkout
and only load:
CheckoutController
CartService
PaymentService
TaxService
while never touching unrelated subsystems.
The execution graph is narrower from the beginning.
WordPress historically operates closer to:
Load WordPress
Load plugins
Register hooks
Run lifecycle
Eventually reach checkout logic
which increases baseline overhead.
Practical examples of execution-scope reduction in WordPress
People achieve versions of this by:
Selective plugin loading
Only load certain plugins on certain routes.
Examples:
- Form plugin only on pages containing forms.
- LMS plugin only on course pages.
- Membership plugin only on membership endpoints.
Conditional hook registration
Instead of:
add_action('init', 'heavy_function');
use:
if (is_checkout()) {
add_action(...);
}
or even earlier request detection.
AJAX endpoint isolation
Instead of bootstrapping large portions of the site for every AJAX request, create narrowly scoped endpoints that execute only required logic.
Service lazy-loading
Instantiate expensive services only when actually needed.
Headless architectures
Move rendering and caching layers outside WordPress and use WordPress primarily as a content or commerce backend.
The hierarchy of performance impact
For uncached requests, performance improvements often rank roughly like this:
- Eliminate unnecessary execution entirely
- Reduce database work
- Reduce external API calls
- Reduce object creation and hook execution
- Use object caching
- Use OPcache
- Micro-optimize code
The exact order varies, but the biggest wins frequently come from removing work rather than accelerating work.
So I would say your framing is accurate:
- Page caching = avoid the entire WordPress execution path.
- Object cache, OPcache, fragment cache = make the remaining execution path cheaper.
- Execution-scope reduction = shrink the execution path itself by preventing unrelated plugins, hooks, services, and code from participating in the request lifecycle.
For dynamic WordPress endpoints such as checkout, account pages, search, and AJAX, execution-scope reduction is often the next optimization frontier after the obvious caching layers are already in place.
This is exactly where LiteCache Rush applies its principle of Performance by Prevention. Page caching is powerful because it can avoid WordPress execution entirely for cacheable public pages. Object cache, OPcache, fragment caching, and database tuning make the remaining dynamic execution cheaper. But checkout, search, account pages, AJAX, and personalized sessions still reach WordPress and still trigger PHP, plugins, hooks, services, and application logic. Rush targets this remaining layer: it identifies the request context early and prevents unrelated PHP and plugin execution from entering the request lifecycle in the first place. In short: caching reduces when WordPress has to run; Rush reduces how much unnecessary runtime participates when WordPress does run.