Your server returns HTML quickly, but the largest image appears late. Or the page paints immediately, yet clicking a filter still feels stuck. Neither symptom can be fixed reliably by following a universal list of speed tricks.

The useful question is not “Which optimization is considered best practice?” It is “Which part of this page's load or interaction is actually taking time?” These five myths are common because each contains a piece of truth. The mistake is treating that piece as the diagnosis.

For this article, LCP (Largest Contentful Paint) means when the largest eligible image, text block, or video in the viewport renders. INP (Interaction to Next Paint) describes responsiveness across user interactions. They measure different experiences, so a page can do well on one and poorly on the other. Google documents their behavior in its LCP and INP optimization guides.

Before changing anything, capture the evidence

Use a real page with a repeatable slow state, not an invented benchmark:

  1. In Chrome DevTools, open Network. Reload the page. Note the document request, the large resources, the Protocol column, Priority, Initiator, and the request waterfall. Check cache status instead of assuming every request crossed the network.
  2. Open Performance. Record a page reload and identify the LCP element and surrounding network/main-thread work. Record a separate interaction, such as opening a menu or changing a filter, if responsiveness is the complaint.
  3. For a controlled browser-cache-disabled reload, enable Disable cache in Network while DevTools is open. For a repeat-visit comparison, uncheck it, load once to populate the cache, then reload again. Keep device, viewport, network and CPU settings the same and repeat each case. This toggle does not clear a CDN cache or simulate every aspect of a first-time visit. A single local recording is a clue, not a population-level performance result.
  4. When real-user data is available, check it too, with mobile and desktop separated. Field data represents a distribution across actual visits, while a DevTools trace explains one reproducible case. Do not present a local trace as your site's field p75.

The Chrome Network panel reference documents request timing and priority; the Performance panel guide covers load and runtime recordings. Google's lab versus field data explanation explains why those results may disagree.

Keep this decision table nearby as you inspect the page:

What you observeWhere to look nextWhat not to assume
Many requests, but no meaningful delay in their start or completionProtocol, cache behavior, dependency chain, transfer sizesFewer requests must help
Slow click with visible main-thread activityInteraction timing, scripting, style, layout, paintThe framework alone is to blame
Low document TTFB but late LCPLCP resource discovery and render delayA CDN solved loading
LCP image loads early but appears lateCSS, scripts, visibility and main-thread work after response endSmaller image bytes are the only fix
Image finishes but the page cannot paintBlocking stylesheets and other critical-path dependenciesSmall CSS cannot matter

These are diagnostic interpretations, not measured outcomes for this portfolio.

Worked diagnosis: the LCP image starts late

Consider this hypothetical trace, not a measurement from this portfolio. The page's LCP element is a hero image; all times are measured from navigation start.

EventExample timestampCalculation
HTML first byte arrives200 msTTFB: 200 ms
Hero image request starts920 msResource load delay: 920 - 200 = 720 ms
Hero image download finishes1,100 msResource load duration: 1,100 - 920 = 180 ms
Hero image renders as LCP1,330 msElement render delay: 1,330 - 1,100 = 230 ms

The four spans total 1,330 ms. That number is only an arithmetic example, not a target or an observed result. The largest avoidable-looking gap is the 720 ms before the image request, not the 180 ms download. Changing the image format first would therefore be a poorly supported hypothesis.

To investigate that gap in a real recording:

  1. In Performance, record a reload and identify the actual LCP element. Confirm it is the hero image, not a text heading or another image.
  2. In Network, locate the image request. Use its Initiator and waterfall timing to determine when the browser discovered it. Does a stylesheet, JavaScript module or late-added DOM node trigger the request? An early HTML <img src> generally lets the browser discover the resource sooner.
  3. Change one cause suggested by the evidence, for example expose the resource in initial markup or preload an otherwise late-discovered hero image when appropriate. Do not add a speculative preload to every image.
  4. Repeat with the same conditions. Check whether resource load delay shrinks and whether LCP actually improves. A shorter request delay can be offset by a longer render delay or competition for other resources.

Use the LCP subpart breakdown to interpret the recording. The timestamps above are constructed solely to teach the calculation; they are not a benchmark, Chrome export or claim about a deployed site.

Myth 1: Fewer HTTP requests always mean a faster page

Combining every script and stylesheet into one file can reduce request count. It can also force visitors to download code for features they do not use, invalidate a large cached bundle after a small change, or delay a critical resource behind unrelated work.

The protocol matters. HTTP/2 supports multiplexed streams over a TCP connection; HTTP/3 uses QUIC rather than TCP. Multiplexing reduces some costs of serial delivery, but requests still consume bandwidth, processing and scheduling resources. It does not make each request free. See MDN on HTTP/2 and the HTTP/3 specification.

Check: In Network, compare a cold reload with a cached reload. Are there repeated large transfers? Is an important file waiting on a dependency? Does a chunk download only after the user navigates or interacts? Record the actual protocol; don't assume the page is using HTTP/2 or HTTP/3.

Choose: Split code at meaningful feature or route boundaries when it removes work from the initial path. Keep strongly coupled, always-needed modules together when splitting would add unnecessary dependencies. The goal is to improve delivery and execution of needed code, not maximize chunk count. The code-splitting article explores those boundaries separately.

When the old advice still helps: High request overhead, poor caching, or unusually deep dependencies can make consolidation useful. Measure before and after rather than treating file count as a score.

Myth 2: A slow React or Vue page proves the framework is slow

Framework runtimes have costs, and an application's choice of framework can affect loading and interaction work. But blaming the framework's name does not locate an expensive event handler, a large initial bundle, an overgrown DOM, or a costly render.

Two slow states can have entirely different causes:

  • Slow initial paint on a client-rendered route: If the initial HTML is an empty app shell, meaningful content can wait for JavaScript to download and run. By contrast, server-rendered or statically generated HTML can be visible before hydration, although JavaScript may still be needed for interactive behavior and can compete for main-thread time. Check the Network waterfall and scripting work rather than assuming every framework page has the same rendering path. React documents the distinction in its client-rendered root and hydration references.
  • Slow interaction: An input waits for the main thread, its callbacks take too long, or the resulting style/layout/paint takes too long. INP breaks a qualifying interaction into input delay, processing duration and presentation delay. Inspect these separately instead of treating every slow click as an excessive framework re-render.

Check: Record the action in Performance, find the long work associated with it, then inspect the call stack and rendering activity. Does the delay occur before the callback, inside the callback, or before the next paint? A JavaScript-heavy startup trace and a layout-heavy filter interaction call for different fixes. Google's INP guidance explicitly distinguishes those phases.

Choose: Remove or defer unrelated initialization, reduce the actual expensive computation, or limit DOM/style work where the recording shows it. Memoization, event delegation and component rewrites are not interchangeable performance fixes.

When the old advice still helps: Comparing framework architectures can be a legitimate design decision when equivalent implementations are actually measured under matching conditions. This article does not claim a framework benchmark.

Myth 3: Putting the site behind a CDN fixes loading performance

A CDN can shorten the path to cacheable content and reduce time to first byte (TTFB) for many visitors. But a CDN hit does not guarantee that the document reveals the LCP resource early, that a stylesheet finishes before rendering, or that JavaScript leaves enough main-thread time for interactions.

For a navigation with an image LCP, separate these four spans:

  1. TTFB: navigation start to first response byte of the HTML document.
  2. Resource load delay: HTML first byte to the start of the LCP resource request.
  3. Resource load duration: the LCP resource's download.
  4. Element render delay: completion of that resource to the element's render.

That breakdown comes from Google's Optimize LCP guide. For a text LCP with no separate resource, its resource-load spans can be zero.

Check: Compare a slow page's document request with the time its LCP element actually renders. Inspect cache-specific response headers if the CDN exposes them; names and meanings vary by provider. A cache hit and a cache miss are not equivalent cases. Do not try to cache personalized HTML indiscriminately, or use a made-up cache-bypass parameter without knowing your CDN configuration.

Choose: Improve origin/edge caching when TTFB is the problem. If the image request starts late, improve discovery. If the image is loaded but rendering waits, inspect blocking CSS, JavaScript and visibility. For more on where the network portion starts, see what happens when a browser opens a website.

When the old advice still helps: A CDN can be a significant TTFB improvement for an appropriately cacheable site with geographically distributed users. It is not a cure for work that happens after the response arrives.

Myth 4: The largest image file must be the first performance fix

Reducing image bytes is valuable when transfer time is actually excessive. But the LCP image may spend more time waiting to be requested than downloading, or it may download quickly and wait to render. Optimizing its format alone does not fix those delays.

For example, the markup below represents a potential above-the-fold hero image (illustrative, not a benchmark):

<!-- A likely LCP image should not be lazily loaded. -->
<img
  src="/assets/hero.webp"
  width="1200"
  height="675"
  alt="A landscape"
  fetchpriority="high"
/>

The browser can discover a normal <img src> while parsing HTML. If the image is instead inserted by JavaScript, hidden behind a library-specific data-src, or referenced only in a late-discovered CSS file, its request can start later. A high fetch priority can help a genuinely important resource, but marking many images high priority undermines prioritization. The LCP optimization guide advises against lazy-loading an LCP image.

Check: Identify the actual LCP element in the recording. If it is an image, inspect when its request starts relative to HTML TTFB and the other early resources. Look at transfer duration and the gap after it finishes. If the LCP element is text, an image-compression fix may be irrelevant to that visit.

Choose: Fix late discovery first when resource load delay dominates; reduce bytes or improve caching when resource load duration dominates; investigate blocking rendering when element render delay dominates. The biggest file and the biggest delay are not necessarily the same thing.

When the old advice still helps: Oversized images on a constrained connection can absolutely dominate transfer time. Confirm that with a waterfall before spending effort on an entirely different layer.

Myth 5: Small CSS cannot be the reason a page appears late

CSS may be a small percentage of transferred bytes and still sit on the critical rendering path. Stylesheets that apply to the current page can block rendering while the browser downloads and processes them. That does not mean every stylesheet blocks every render.

Consider these two resources (illustrative):

<!-- Applies to this screen and can block rendering. -->
<link rel="stylesheet" href="/styles/site.css">

<!-- Applies when printing, so does not block screen rendering. -->
<link rel="stylesheet" href="/styles/print.css" media="print">

A stylesheet with a non-matching media condition can be downloaded without blocking rendering of the current media. An @import can create another dependency discovered only after a stylesheet is loaded. MDN documents CSS loading and media conditions.

Check: If the LCP image has already finished loading but its element paints late, inspect the Performance recording for stylesheets, scripts, and main-thread work before the render. Confirm that the styles in question actually apply. Avoid treating every CSS request as equally critical.

Choose: Keep genuinely required initial styles discoverable early and reasonably small. Remove unused CSS carefully, account for layout and fonts, and defer only styles that do not affect the first render. Inlining all CSS can increase HTML size and lose shared-file caching; the Optimize LCP guide recommends inlining only when the stylesheet is appropriately small.

When the old advice still helps: A tiny CSS file loaded quickly from cache may be negligible. A small but late-discovered, necessary stylesheet may be decisive. Its position in the dependency chain matters more than a blanket size threshold.

Make the next optimization a testable hypothesis

Before touching the implementation, write down four observations: the symptom, the trace evidence, the change you predict will help, and the metric that should move. If your issue is a sluggish click, specify which interaction you are measuring. If it is slow LCP, identify which LCP span you expect to shorten. Then repeat the same test conditions and check field data over time where available.

If the predicted span does not improve, the right response is not to declare the optimization a success because bundle size fell or a score changed once. Revisit the diagnosis.

This is the useful lesson behind all five myths: smaller assets, fewer requests, a CDN, less JavaScript and leaner CSS can all help. None tells you what to fix next without evidence from the page you're actually serving.