When a website feels slow, the common solution is to add CPU, move hosting, or install a new caching plugin. Sometimes these steps help. However, the problem often lies in oversized hero images, database queries that take too long, or third-party JavaScript that only runs after the page is visible.
A website does not become faster just because one component is replaced. The browser must request HTML, receive the server's response, fetch CSS and JavaScript, load images, calculate layout, and then render the page on the screen. This sequence is known as the critical rendering path—the path the browser takes to convert code into a viewable display for users. MDN explains that this process involves the DOM, CSSOM, render tree, layout, and painting.
Start with the simplest question: where is the slowness occurring?
Think of the process of opening a page like ordering food. There is time for the restaurant to receive the order, prepare the food, deliver it, and then the customer opens the packaging. If the food is delayed in preparation, the issue is different from traffic jams or difficult-to-open packaging.
On a website, the breakdown is roughly as follows:
- Before the server responds: DNS time, connection, TLS, and URL redirection.
- While the server is working: application processing, PHP, API calls, and database queries.
- While the browser loads the page: CSS, JavaScript, fonts, images, and third-party resources.
- While the page is in use: JavaScript events, animations, forms, and layout changes.
Since the sources of the problem vary, measurements must be taken before optimization. Use PageSpeed Insights or Chrome DevTools to view the waterfall—the sequence of time for each request—not just the summary score. The score is useful as a signal, but the waterfall often provides more concrete clues.
1. Check TTFB before blaming images
TTFB or Time to First Byte is the time from when the browser requests the page until the first byte of the response is received. This figure includes several parts such as connection, redirection, and the time the server takes to prepare the response. Chrome explains that TTFB is not just the application execution time on the server; DNS and redirects can also contribute to delays.
If the TTFB of the homepage is already high, reducing image sizes may not resolve the first issue perceived by users. Look for causes on the server side, such as:
- dynamic pages performing too many database queries;
- PHP processes waiting for external APIs;
- object cache not working or frequently empty;
- PHP-FPM running out of workers, causing requests to queue;
- pages that should be cacheable are always being regenerated.
In practice, compare three conditions: the page that is not logged in, the cached page, and the dynamic page after logging in. If the public page is fast when the cache is warm but slow when the cache is empty, the main issue may lie in the page generation process, not network capacity.
2. Differentiate between the page being displayed and the page being ready for use
A page displaying a title is not necessarily ready for use. The browser may still be downloading large JavaScript files, waiting for fonts, or running scripts that block interaction.
One important metric is Largest Contentful Paint (LCP), which is the time until the largest visible content element in the viewport is fully rendered. For a good experience, a common target is an LCP of no more than 2.5 seconds at the 75th percentile of visits. The LCP element can be a main image, video, or large text block—not always an image.
If LCP is poor, check the elements flagged by testing tools. Some commonly relevant steps include:
- Use image sizes appropriate for the display, rather than sending a 4000-pixel image for an 800-pixel wide area.
- Choose modern formats if compatible with the website's workflow, then compress images without sacrificing readability.
- Do not apply lazy loading to main images that are immediately visible on the screen.
- Reduce CSS and JavaScript that must be downloaded before the main content appears.
- Ensure important fonts do not delay the main text for too long.
Keep in mind, preload is not a “speed up everything” button. Loading too many resources simultaneously can cause bandwidth contention. Web.dev's guide also emphasizes that preload should be used for truly critical resources.
3. Look for JavaScript that keeps the browser busy
After HTML and CSS are received, the browser still needs to parse and execute JavaScript. Large or numerous scripts can hinder parsing, layout, and response to clicks.
Note whether delays only occur after the user presses a button. If so, the server may not be the issue. The cause could be a click handler that performs too much work, tables rendering thousands of rows at once, or analytics libraries binding many events.
Separate JavaScript based on necessity. Features needed when the page first opens can be loaded earlier. Features only used on specific pages should be loaded when needed. For long lists, use pagination or virtualization to prevent the browser from rendering all items at once.
4. Do not ignore layout shifts
A website can feel “slow” even when content is displayed, especially if users keep losing their reading position due to moving elements. This is measured through Cumulative Layout Shift (CLS), a metric that describes layout instability.
Common causes of CLS include images without dimensions, ads or iframes without allocated space, and fonts that change text size after loading. The solution is simple but must be consistent: set width and height attributes on images, provide space for embeds, and test font strategies on real devices.
Web.dev recommends a CLS of 0.1 or lower for a good experience on at least 75 percent of visits.
5. Diagnostic steps you can take now
- Test the same page three times. Note whether the results vary significantly between cold cache and warm cache.
- Look at the waterfall. Look for the longest requests, redirect chains, and files waiting for other requests.
- Compare TTFB with render time. High TTFB points to server or network issues; low TTFB but high LCP points to assets and browser processes.
- Check application and database logs. Look for repeated queries, slow external endpoints, and requests that take too long.
- Test without third-party scripts. Temporarily disable chat widgets, ads, analytics tags, or A/B testing tools to see the impact.
- Change one thing at a time. If cache, image compression, and JavaScript configuration are changed simultaneously, it will be difficult to know which change actually worked.
What does this mean for us?
Website optimization is not a race to chase a single score. The goal is to reduce the wait times most felt by users: the page starts responding, the main content is visible, buttons respond quickly, and the layout is stable.
If TTFB is high, start with the application, database, cache, and server queues. If TTFB is healthy but LCP is poor, check images, CSS, fonts, and critical resources. If the page is visible but clicks feel delayed, audit JavaScript. By breaking down issues by stage, tuning decisions become cheaper, measurable, and less reliant on guesswork.
Sources & further reading
- Critical rendering path — MDN Web Docs
- Reduce server response times — Chrome for Developers
- Largest Contentful Paint (LCP) — web.dev
- Optimize Largest Contentful Paint — web.dev
- Preload critical assets to improve loading speed — web.dev
- Optimize Cumulative Layout Shift — web.dev
– Rio Yotto @rioyotto
