Initial assessment without passwords Quote before intervention One accountable specialist from start to finish

Measurement And Symptom Isolation

A WordPress Page Is Slow on the First Visit but Fast After Refresh

A WordPress page is slow the first time and fast on refresh. Separate browser cache, page cache, CDN and origin generation before changing settings.

The first visit takes several seconds. Refresh the page and it appears almost instantly.

That pattern is not proof that “the cache works”. It shows that something expensive is paid once and reused later. The reusable part might be the generated HTML, a large image, a font, JavaScript, a network connection or data stored by the browser.

The right repair depends on which cost disappears after refresh.

Reproduce the first visit without confusing the caches

Several caches can participate in one WordPress request:

  • browser cache;
  • full-page cache in WordPress or the web server;
  • object cache;
  • PHP opcode cache;
  • CDN edge cache;
  • DNS and connection reuse.

Opening a private window usually removes the normal browser cache and cookies. It does not necessarily empty the WordPress page cache or the CDN.

Use a test page that you are authorised to inspect. Record:

  1. first load in a clean private window;
  2. immediate refresh;
  3. first load after waiting for the normal cache expiry, if known;
  4. first load from another test location.

Do not purge every cache before every request. You need to observe which layer changes the result, not create an artificial worst case that visitors rarely see.

Compare response headers on the first and second request

Start with the HTML response:

curl -I https://example.com/page/
curl -I https://example.com/page/

Look for headers such as:

  • age;
  • cache-control;
  • cf-cache-status;
  • x-cache;
  • x-litespeed-cache;
  • x-fastcgi-cache;
  • a host-specific cache indicator.

Header names and values differ. The useful comparison is whether the first response is a cache miss and the second is a hit.

If both are hits but the browser still improves dramatically after refresh, the expensive part is more likely to be an asset or browser work. If the first response is a miss with a long first-byte time, origin generation deserves attention.

Measure the first-byte gap

Use repeated requests and print the first-byte time:

for i in 1 2 3; do
  curl -s -o /dev/null 
    -w "request $i: %{time_starttransfer}sn" 
    https://example.com/page/
done

Run this only against a site you control and keep the request count low. It is a diagnostic comparison, not a load test.

A pattern such as 2.4 seconds followed by 0.2 seconds suggests expensive origin work is cached. Three similar first-byte times suggest the visual improvement after refresh comes from another layer.

A warm page cache can hide an unhealthy origin

Full-page cache stores generated HTML so WordPress does not rebuild it for every visitor. That is useful and expected.

The uncached path still matters because it is used when:

  • a page expires;
  • content changes;
  • the cache is purged;
  • the visitor has a cookie that bypasses cache;
  • a URL variation creates a new cache key;
  • the request is personalised;
  • the page is cart, checkout or account content.

If an uncached page takes several seconds, inspect why WordPress needs that time. Possible causes include:

  • slow MySQL queries;
  • remote API calls;
  • excessive autoloaded options;
  • plugins doing work on every request;
  • PHP worker pressure;
  • filesystem delays;
  • repeated errors or warnings;
  • an oversized dynamic page.

Extending the cache lifetime reduces how often the cost is paid. It does not repair the cost.

Check whether cache keys create many “first visitors”

A cache can look effective in your tests while real traffic continually misses it.

Review whether the site creates separate cache entries for:

  • query parameters;
  • language;
  • currency;
  • device type;
  • cookies;
  • campaign tracking;
  • logged-in state;
  • URL variants with and without a trailing slash.

Do not merge cache entries that contain genuinely different or private content. The aim is to remove meaningless fragmentation, not personalise one visitor’s response for everyone.

Marketing parameters deserve careful testing. Some systems correctly ignore common tracking parameters; others treat every campaign URL as a new uncached page.

The browser may simply be reusing large assets

If the HTML first byte is fast on both requests, compare the Network waterfall.

On the first visit, note:

  • transferred size;
  • main image download;
  • font files;
  • CSS and JavaScript;
  • third-party domains;
  • video or embedded content.

On refresh, check whether the browser reports assets from memory cache or disk cache. A 3 MB hero image can disappear from the second waterfall and make the page look “fixed” even though every new visitor still downloads it.

Optimise the actual first-visit assets:

  • choose appropriate image dimensions and formats;
  • correct srcset and sizes;
  • compress decorative video;
  • remove unused font weights;
  • avoid loading scripts on pages that do not use them;
  • set valid cache headers for versioned static files.

Do not use a very long cache lifetime for unversioned assets that change under the same URL. Visitors may retain broken or outdated files.

Connection reuse also makes refresh faster

The first visit may perform DNS lookup, establish TCP and negotiate TLS for the main domain and several third parties. Refresh can reuse some of those connections.

This becomes noticeable when a page connects to many origins:

  • analytics;
  • tag managers;
  • consent services;
  • chat;
  • maps;
  • video;
  • fonts;
  • advertising.

Reducing unnecessary origins can improve the first visit even if the total downloaded bytes change only slightly.

Do not add preconnect to every domain. Each hint starts work and can compete with essential resources. Reserve it for origins required early in the page.

Fonts often explain “blank first visit, fine after refresh”

If text appears late on the first visit, inspect font loading.

Questions to answer:

  • Is visible text waiting for a remote font?
  • Are several weights downloaded before any are used?
  • Is the font served with a useful cache policy?
  • Is font-display defined?
  • Is a plugin loading a second copy?

A basic self-hosted rule can use:

@font-face {
  font-family: "Brand Sans";
  src: url("/fonts/brand-sans-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

Test layout stability when the font changes. A fast fallback that causes headings to jump later is not a complete solution.

Service workers and aggressive browser storage need separate checks

Some WordPress sites or installed applications use a service worker. It can return assets or pages from storage after the first visit.

In browser developer tools, inspect the Application panel:

  • Is a service worker registered?
  • Which URLs does it control?
  • Does unregistering it in a diagnostic session change the behaviour?
  • Can it serve outdated HTML or scripts after deployment?

Do not unregister service workers for real visitors as an experiment. Establish the intended update strategy first.

Logged-in visitors may never receive the fast path

Many full-page caches bypass users with a WordPress login cookie. WooCommerce session cookies can also change caching behaviour.

Compare:

  • a new logged-out visitor;
  • a returning logged-out visitor;
  • a logged-in customer;
  • a WordPress administrator.

If only logged-in journeys are slow, optimising public page cache is unlikely to help. Inspect the uncached application request, database work and assets loaded for that state.

Cache preloading is useful only after origin health is understood

Some systems can rebuild or “warm” important pages after a purge. This can protect visitors from paying the first-generation cost.

Use it carefully:

  • prioritise valuable pages;
  • limit concurrency;
  • exclude cart, checkout and personalised URLs;
  • avoid generating every filter and query variation;
  • monitor server resources while warming.

Preloading a catalogue with thousands of URLs can exhaust PHP workers and make the site slower. It should complement an efficient origin, not attack it with automated requests.

Do not cache the wrong WordPress pages

Never make cart, checkout, account or other private content publicly cacheable simply because those pages are slow on first visit.

Verify exclusions using response headers and two independent test sessions. A correct test confirms both:

  • dynamic pages are not shared between visitors;
  • their uncached response is acceptably fast.

For WooCommerce, also test cart fragments, currency, shipping and customer state after changing cache settings.

A disciplined repair sequence

Use this order:

  1. reproduce the first/refresh difference;
  2. compare HTML first-byte time;
  3. inspect page/CDN cache status;
  4. compare first-visit and cached asset waterfalls;
  5. identify the single largest disappearing cost;
  6. change the responsible layer;
  7. test clean first visit, refresh and dynamic journeys;
  8. preserve the rollback route and record the result.

This prevents an image problem from becoming a hosting migration, or a slow MySQL query from being hidden behind increasingly complex caches.

Evidence to send with an assessment

Provide:

  • the exact affected URL;
  • first-load and refresh timings;
  • response headers if available;
  • whether the visitor is logged in;
  • device, browser and location;
  • recent cache, CDN, plugin or hosting changes;
  • whether cart, checkout or forms are affected.

Do not include passwords. The first assessment should determine the slow layer and the access actually required.

If a WordPress page is consistently slow on first visit and fast after refresh, we can compare origin generation, cache behaviour and first-visit assets. The proposed work will identify the cost that disappears, explain the safe repair and define verification before any intervention begins.

BEFORE YOU SEND THE REQUEST

Frequently asked questions.

Do you ask for passwords in the form?+

No. The public form never requests access. Secure credentials are requested only after the scope and quote are approved.

Who reviews the incident?+

The request goes to Jordi Ensenyat, founder of Code Barcelona and a WordPress specialist with more than 15 years of experience.

Is anything changed before the quote?+

No. Visible symptoms and scope are reviewed first. Intervention begins after approval and with a rollback path prepared.

Do you work internationally?+

Yes. WP Repair handles WordPress and WooCommerce incidents in English and Spanish through a remote service.

Assess my incident