Web Performance Optimization in 8 Steps

- Measure real-user performance before deciding what to optimise.
- Track the current Core Web Vitals: LCP, INP, and CLS.
- Reduce server delay and shorten the path to the Largest Contentful Paint element.
- Serve correctly sized images and avoid lazy-loading above-the-fold content.
- Load only the fonts, CSS, and JavaScript required for the initial experience.
- Audit third-party scripts by their business value and performance cost.
- Cache versioned assets for a long time and define shorter policies for changing content.
- Use preload and prefetch only when the browser cannot prioritise resources correctly on its own.
- Set performance budgets and monitor releases with both lab tests and Real User Monitoring.
A slow website rarely has one isolated problem. The delay usually accumulates across several layers: the server takes too long to produce HTML, the browser discovers the main image late, large JavaScript bundles block interaction, third-party tags compete for resources, and layout shifts continue after content appears.
This is why web performance optimization cannot be reduced to compressing images or installing a caching plugin. It requires understanding the complete path from navigation to a usable page.
The objective is not to chase a perfect Lighthouse score. It is to improve what users experience across real devices, network conditions, locations, and page types. A fast first visit on a high-end laptop does not prove that a product page is responsive on a mid-range phone or that a returning user can complete checkout without interaction delays.
This guide presents an eight-step process for measuring performance, finding the actual bottleneck, improving the critical rendering path, and preventing regressions.
Why Web Performance Matters
Performance affects how quickly users can see content, whether the page responds when they interact, and whether the layout remains stable while they read or tap.
A technically loaded page can still feel slow. Text may appear while the main image remains blank. A button may be visible but unable to respond because JavaScript is blocking the main thread. A user may attempt to select a product just as a promotional banner moves the interface.
These experiences influence several business and product outcomes.
User experience
Fast pages help users orient themselves and begin tasks with less friction. This is particularly important for mobile users on slower networks and less powerful devices.
Speed also affects trust. A delayed payment step, unresponsive form, or shifting checkout button can make a user uncertain whether the application is working correctly.
Search visibility
Google uses Core Web Vitals as part of its page-experience signals. However, performance is one signal among many; passing Core Web Vitals does not guarantee high rankings, and failing them does not make useful, relevant content irrelevant.
Performance also affects SEO indirectly. Faster pages can make crawling more efficient, improve engagement, and reduce the friction users experience after selecting a search result.
Conversion and retention
The relationship between performance and conversion differs by business, audience, and page. Generic claims such as “every 100 milliseconds costs exactly 1% of revenue” should not be applied universally.
The reliable approach is to connect your own performance data with business events. Compare conversion, abandonment, engagement, and retention across LCP and INP ranges while controlling for device, location, connection, and page type.
Infrastructure and bandwidth
Smaller responses, effective caches, optimised database queries, and fewer unnecessary requests can reduce bandwidth and computing costs. These improvements also help an application handle traffic spikes with less infrastructure.
Understand the Current Core Web Vitals
The current Core Web Vitals are Largest Contentful Paint, Interaction to Next Paint, and Cumulative Layout Shift. First Input Delay was replaced by INP and should not appear as the current responsiveness metric.
Google recommends evaluating Core Web Vitals at the 75th percentile of visits, separately for mobile and desktop. A page or origin passes when all three metrics meet their recommended thresholds at that percentile.
| Metric | Good threshold | What it represents |
| LCP | 2.5 seconds or less | How quickly the primary visible content appears |
| INP | 200 milliseconds or less | How responsive the page remains across user interactions |
| CLS | 0.1 or less | How visually stable the page remains |
Other metrics remain useful for diagnosis:
| Supporting metric | What it helps diagnose |
| TTFB | Server, network, redirect, and CDN delay before HTML begins arriving |
| FCP | When the first DOM content becomes visible |
| TBT | Main-thread blocking in a controlled Lighthouse test |
| Resource size | Excessive image, font, CSS, JavaScript, or media transfer |
| Long tasks | JavaScript work that prevents prompt interaction |
| LCP subparts | Whether LCP is delayed by TTFB, discovery, download, or rendering |
TBT is a lab metric, not a Core Web Vitals metric. It is useful because long tasks found in a controlled test often point to responsiveness problems, but it should not be presented as a replacement for real-user INP.
There is also no universal 200-millisecond TTFB target for every website. TTFB varies by application type, caching status, geography, connection, and hosting architecture. It should be treated as one component of the LCP path.
Step 1: Measure Field and Lab Performance
Do not begin by minifying random files. First establish which pages, users, and metrics are slow.
Performance measurement has two complementary forms.
Field data shows what users experienced
Field data comes from real page visits. It includes the range of devices, browsers, connection speeds, locations, cache states, and user behaviours present in production.
Sources include:
- Chrome User Experience Report data in PageSpeed Insights
- Search Console’s Core Web Vitals report
- A Real User Monitoring platform
- The
web-vitalslibrary connected to your analytics system - Application Performance Monitoring tools
Core Web Vitals are designed to be evaluated in the field. Google recommends examining percentiles rather than averages because an average can hide a substantial group of users receiving a poor experience.
Segment results by:
- Mobile and desktop
- Page template
- New and returning visitors
- Country or region
- Connection type
- Browser
- Device capability
- Authenticated and unauthenticated journeys
- Application version
An origin-wide score can hide one slow template. Product pages, articles, search results, account dashboards, and checkout flows should be examined independently.
Lab tests help reproduce and diagnose problems
Lighthouse, Chrome DevTools, and WebPageTest run tests under controlled conditions. They help developers inspect network waterfalls, rendering, long tasks, layout shifts, code coverage, CPU work, and resource priorities.
Useful tools include:
- PageSpeed Insights for field and lab data
- Lighthouse for repeatable audits
- Chrome DevTools Performance panel
- Chrome DevTools Network panel
- WebPageTest for filmstrips, waterfalls, locations, and connection profiles
- Coverage tools for unused JavaScript and CSS
- Performance Insights for visual diagnostics
Lab data describes a simulated experience and may not match the field. Google recommends using field data to identify the problem and lab tools to reproduce and diagnose it.
Record a meaningful baseline
Before changing production code, record:
- The affected URLs or templates
- Mobile and desktop field metrics
- Lighthouse configuration
- Device and connection profile
- Server and CDN cache state
- Page weight and request count
- LCP element
- Longest main-thread tasks
- Third-party contribution
- Business metrics connected to the journey
Use the same test conditions after the change. Otherwise, an apparently faster result may simply reflect a warm cache or different network conditions.
Step 2: Reduce Server and Network Delay
The browser cannot render application content before it receives useful HTML and discovers the required resources. A slow backend delays everything that follows.
TTFB includes more than application processing. It may contain DNS resolution, connection establishment, TLS negotiation, redirects, CDN routing, edge processing, server rendering, API calls, and database work.
Remove unnecessary redirects
Every redirect can add another network round trip before the browser reaches the final document. Audit:
- HTTP-to-HTTPS redirects
wwwand non-wwwredirects- Old campaign URLs
- Device-specific redirects
- Authentication redirects
- Trailing-slash rules
- Locale detection
Where possible, link directly to the final URL and collapse redirect chains.
Improve backend work
Profile the server rather than guessing. Common causes of slow responses include:
- Unindexed database queries
- Sequential API calls
- N+1 queries
- Slow authentication or session lookups
- Rendering that waits for non-critical data
- Repeated calculations
- Missing application caching
- Large HTML responses
- Cold serverless functions
- Calls to unreliable third-party services
Cache frequently requested results where freshness requirements permit. Add database indexes based on measured query patterns, not assumptions. Run independent upstream requests concurrently when their results do not depend on one another.
Choose rendering according to the content
Static Site Generation works well for content that can be generated ahead of time. Server-Side Rendering is useful when the initial response requires current or personalised information. Client-side rendering may be appropriate for interactions after the initial page, but making users download and execute a large JavaScript application before seeing meaningful content can harm LCP.
Many systems benefit from a hybrid model:
- Pre-render stable content
- Cache shared server-rendered responses
- Stream parts of the response where supported
- Load personalised or non-critical sections later
- Revalidate content instead of rebuilding everything
The correct strategy depends on freshness, personalisation, cacheability, and operational complexity.
Use modern transport and compression
HTTP/2 and HTTP/3 can improve connection use and request delivery, but they do not make unnecessary resources free. Too many small files still create headers, prioritisation work, processing, and cache-management overhead.
Compress text-based responses such as HTML, CSS, JavaScript, JSON, and SVG using Brotli or Gzip according to server and client support. Do not recompress formats that already use effective compression, such as JPEG, AVIF, WebP, MP4, or WOFF2.
Step 3: Optimise Images, Video, and Embedded Media
Images are frequently the Largest Contentful Paint element and often account for a large portion of transferred bytes. The correct goal is not merely “convert everything to AVIF.” It is to send the smallest asset that preserves the required visual quality and compatibility.
Serve the correct dimensions
Do not send a 3000-pixel image to a 300-pixel card. Generate several sizes and let the browser select an appropriate source using responsive-image markup.
The selected size should account for:
- Rendered dimensions
- Device pixel ratio
- Viewport width
- Layout breakpoint
- Crop or art direction
- Network and browser support
A responsive image can reduce transfer size without visibly reducing quality.
Boost Your Website’s Speed and Performance
We help you speed up your website, improve Core Web Vitals, and deliver smoother user experiences that convert better.
Select formats according to the content
AVIF and WebP can provide strong compression, but the best result depends on the image.
- AVIF can perform well for photographs at low file sizes.
- WebP offers broad modern-browser support and handles both lossy and lossless use cases.
- SVG is appropriate for many logos, icons, and simple illustrations.
- PNG remains useful when lossless detail or alpha transparency is required.
- JPEG may remain practical for some photographic workflows and fallbacks.
Automated image pipelines can generate variants, but quality should still be reviewed. Aggressive compression can damage product images, text inside screenshots, and fine visual detail.
Do not lazy-load the LCP image
Lazy loading is useful for content below the initial viewport:
<img loading="lazy" src="..." alt="..." />This allows the browser to postpone selected images until they approach the viewport, reducing initial network competition and saving data for users who never scroll to them.
Do not apply lazy loading indiscriminately. A hero image or other likely LCP resource should normally be discovered and fetched early. Lazy-loading it can delay LCP.
Always provide meaningful alternative text for informative images, and reserve space through intrinsic dimensions or CSS aspect ratio to reduce layout shifts.
Treat video as a separate performance problem
Large video embeds and autoplaying backgrounds can consume substantial bandwidth, CPU, memory, and battery.
Consider:
- A lightweight poster image before playback
- User-initiated playback
- Adaptive streaming for longer video
- Several resolutions and bitrates
- Deferring the player until it approaches the viewport
- Avoiding unnecessary autoplay
- Pausing off-screen media
- Removing unused audio tracks
- Loading third-party embed code only after consent or interaction
H.265 is not a universal web-delivery recommendation because browser, device, and licensing support vary. H.264 remains widely compatible, while VP9 and AV1 can provide efficient alternatives where supported.
Embedding YouTube or Vimeo may reduce the burden on the origin server, but their standard players can add substantial JavaScript and third-party connections. A facade that displays a lightweight preview and loads the player after interaction can provide a better initial experience.
Step 4: Optimise Fonts and CSS Delivery
CSS and fonts affect when text appears, when the browser can paint the page, and whether the layout shifts after the first render.
Reduce font payload
Load only the families, weights, styles, character sets, and variable-font axes the product actually uses. A design system that requests several font families and every available weight can add hundreds of kilobytes before the user reads one paragraph.
WOFF2 is generally the preferred web-font format for modern browsers. Subsetting can reduce file size for sites that need a limited range of characters, but multilingual products must ensure required scripts and glyphs remain available.
Select an appropriate font-display strategy
The existing developer example uses font-display: swap:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}This allows fallback text to appear while the web font loads. It improves text visibility but can cause layout movement when the final font has different dimensions.
Google’s font performance guidance notes that font-display involves trade-offs. swap prioritises early text while still using the web font, whereas optional may avoid a late swap when the font does not arrive quickly.
Choose a fallback font with similar metrics, and consider font metric overrides where necessary to reduce CLS.
Remove unnecessary CSS
Use coverage tools to find styles not required by the current templates. Large global stylesheets often accumulate rules from retired components, experiments, and pages.
Minification removes unnecessary characters, but it does not remove unused design-system code by itself.
Frameworks such as Tailwind can produce small production CSS when content detection is configured correctly. They do not guarantee small output automatically, especially when dynamic class names, broad safelists, or third-party component styles are involved.
Be cautious with critical CSS
Inlining a small amount of above-the-fold CSS can remove an early render-blocking request, but over-inlining increases HTML size, reduces shared cache reuse, and can duplicate styles across navigations.
Measure whether critical CSS helps the actual template before adopting a complex extraction pipeline.
Tools such as PostCSS, Autoprefixer, and CSSNano perform different roles:
- PostCSS provides a transformation pipeline.
- Autoprefixer adds prefixes according to browser targets.
- CSSNano minifies and optimises CSS.
They can improve delivery but cannot fix inefficient selectors, duplicated component systems, or excessive design dependencies on their own.
Step 5: Reduce JavaScript and Third-Party Work
JavaScript affects both download cost and runtime responsiveness. The browser must download, decompress, parse, compile, and execute it. On lower-end devices, processing can cost more than transfer.
A page can display quickly and still have poor INP because long tasks delay event handling and the next visual update.
Ship only what the current page needs
Route-level and component-level code splitting can reduce the initial bundle. The developer’s React example uses lazy loading:
const Component = React.lazy(() => import('./Component'));This tells the bundler to create a separately loaded module for the component.
Code splitting has trade-offs. Excessive splitting can create request waterfalls, duplicate small modules, and cause users to wait after interaction. Split at meaningful boundaries and preload a chunk only when there is strong evidence it will be needed soon.
Analyse the bundle
A bundle visualiser can reveal:
- Large libraries
- Duplicate package versions
- Unused locales
- Development code in production
- Heavy polyfills
- Full-library imports where smaller modules exist
- Code shared by no relevant initial route
- Client-side dependencies that could remain on the server
Tree shaking depends on module structure, package metadata, and build configuration. Do not assume the bundler removed unused code without inspecting the output.
Break up long tasks
A task that monopolises the main thread prevents the browser from handling input and presenting the next frame.
Improve responsiveness by:
- Dividing large work into smaller tasks
- Yielding to the browser between units of work
- Avoiding unnecessary synchronous processing
- Reducing component re-rendering
- Virtualising large lists
- Moving appropriate computation to Web Workers
- Updating only the affected DOM
- Deferring non-essential hydration or initialization
- Avoiding expensive event handlers
INP measures more than the delay before a handler begins. It includes input delay, event-processing time, and presentation delay before the browser displays the result.
Audit every third-party script
Analytics, advertising, chat, consent, personalisation, A/B testing, social embeds, fraud detection, and tag managers can add network requests and long tasks outside the application team’s direct control.
For each third party, document:
- Business owner
- Pages where it is required
- Transfer size
- Main-thread cost
- Loading behaviour
- Data collected
- Failure behaviour
- Consent requirement
- Renewal or removal date
Use async or defer appropriately for non-critical scripts, but recognise that these attributes do not eliminate execution cost. A deferred script can still block the main thread later.
Load scripts only on relevant pages or after user interaction where appropriate. Review replacements according to features, privacy, reliability, and performance rather than assuming that a smaller analytics product is always a drop-in substitute.
Step 6: Apply Caching and CDN Strategy Deliberately
Caching prevents the browser, CDN, or application from repeating work when a valid result already exists.
A CDN can reduce latency by serving cacheable resources from locations closer to users. It can also absorb traffic and offload the origin. However, a CDN cannot compensate for uncacheable HTML, slow application logic, oversized assets, or JavaScript execution.
Use long caching for versioned static assets
The developer’s existing cache example is:
Cache-Control: public, max-age=31536000, immutableThis policy is appropriate for public assets whose URLs change whenever their contents change, such as hashed JavaScript, CSS, images, and fonts.
Do not apply a one-year immutable policy to a file that may be changed at the same URL. Users could remain stuck with the old version.
A reliable deployment process uses content hashes:
app.a81d3f.js
styles.291ac4.cssWhen content changes, the filename changes, allowing the old resource to remain cached safely.
Define separate policies for different content
Caching strategy should distinguish between:
- Immutable static assets
- HTML documents
- Public API responses
- Private user data
- Personalised pages
- Frequently changing inventory
- Error responses
- Redirects
Shared caches must not serve one user’s private information to another. Responses containing personal or account-specific content require deliberate cache headers and cache keys.
Validate the full cache chain
Check browser, service-worker, CDN, reverse-proxy, application, and database caches. Multiple layers can create stale content or make invalidation difficult.
Monitor:
- Cache-hit ratio
- Age of served content
- Origin offload
- Revalidation behaviour
- Purge duration
- Variation by cookies or headers
- Unexpected cache misses
- Incorrectly cached private responses
Use service workers only with a clear update model
Service workers can precache an application shell, support offline behaviour, and implement runtime caching. They can also serve stale code, make debugging difficult, and complicate deployments.
Tools such as Workbox reduce implementation work, but the team still needs to define:
- Which assets are precached
- Which requests use runtime caching
- When caches expire
- What happens offline
- How a new service worker activates
- How incompatible application versions are handled
- How users recover from a broken cache
Step 7: Prioritise Critical Resources Carefully
Browsers already have a sophisticated resource scheduler. Loading hints are most useful when the browser lacks information needed to prioritise correctly.
Preload resources needed for the current page
The developer’s example is:
<link rel="preload" href="main.css" as="style">
This tells the browser to fetch main.css early as a style resource. Preloading does not, by itself, apply the file as a stylesheet. The page still needs a correct mechanism that uses the CSS.
Use preload only for resources that are definitely required for the current navigation and would otherwise be discovered late. Candidates may include:
- A critical font
- A CSS file discovered through another resource
- The LCP image when it is not discoverable in initial HTML
- A critical script chunk
- A media asset required immediately
The as value must match the resource type. Cross-origin fonts may also require correct CORS configuration. Incorrect preload attributes can cause duplicate downloads.
Too many preloads compete with more important resources and defeat the purpose of prioritisation.
Prefetch likely future navigation
The developer’s example is:
<link rel="prefetch" href="/next-page">
Prefetch is a low-priority hint that a resource may be needed for a future navigation. It can reduce later latency when the browser has idle capacity.
Boost Your Website’s Speed and Performance
We help you speed up your website, improve Core Web Vitals, and deliver smoother user experiences that convert better.
Use it only when the next action is reasonably likely. Aggressive prefetching can waste bandwidth, data, battery, server capacity, and user privacy—particularly on mobile networks.
User intent can provide stronger signals. A product may prefetch after a user hovers, focuses, or begins interacting with a link rather than predicting every possible destination at page load.
Avoid conflicting priorities
A common performance failure occurs when the application:
- Lazy-loads an LCP image
- Preloads many non-critical fonts
- Starts several third-party connections
- Prefetches future pages
- Downloads a hero video
- Requests a large JavaScript bundle
All of these compete for finite bandwidth. Examine the network waterfall and decide which resources genuinely contribute to the first useful experience.
Step 8: Monitor Users and Prevent Regressions
Performance changes as the product evolves. A new analytics tag, hero image, font weight, component library, or experiment can reverse previous gains.
Performance needs ownership and release controls.
Collect Real User Monitoring data
RUM helps teams understand actual performance by device, browser, region, page template, and application version.
Collect Core Web Vitals together with diagnostic context such as:
- URL or route
- LCP element
- Navigation type
- Device category
- Connection information where available
- Release version
- Experiment variant
- Attribution data for INP and CLS
- Server timing
- Relevant business events
Protect user privacy and avoid collecting sensitive page content.
Create performance budgets
A performance budget turns “keep the site fast” into an enforceable engineering constraint.
Budgets can cover:
- JavaScript transferred and uncompressed size
- CSS size
- Image weight
- Font weight
- Third-party requests
- Total request count
- Lighthouse metrics
- LCP, INP, and CLS field targets
- Server response percentiles
Bundle-size budgets are easiest to enforce in CI. Lab-metric budgets should allow for natural variability and use repeated runs or controlled environments.
Field metrics change more slowly because they depend on sufficient real-user data. Use them to confirm whether lab improvements reached production users.
Add checks to CI/CD
Tools such as Lighthouse CI can compare selected pages against thresholds or previous builds. Bundle analysers can reject unexpectedly large JavaScript changes. Visual and integration tests can reveal layout shifts and delayed interactions.
Do not rely on a single Lighthouse score. A score may change when metric weighting, test conditions, or Lighthouse versions change. Track the underlying metrics and resource changes.
Review performance with product changes
Performance should appear in acceptance criteria for:
- New page templates
- Large media
- Third-party integrations
- Personalisation
- Consent tools
- Search and filtering
- Navigation changes
- Framework upgrades
- Marketing campaigns
- A/B tests
Assign an owner to each regression. Without ownership, performance findings become a report that everyone sees and no one fixes.
Diagnosing Each Core Web Vitals
When LCP is slow
LCP can be divided into four broad stages:
- TTFB
- Delay before the browser starts loading the LCP resource
- Resource download time
- Delay before the element is rendered
If TTFB is dominant, work on the server and delivery path. If resource discovery is late, expose or preload the LCP resource. If download is slow, reduce the file or improve delivery. If rendering is delayed, inspect CSS, fonts, JavaScript, and client-side rendering.
When INP is poor
Use field attribution and DevTools to locate the affected interaction.
Look for:
- Long event handlers
- Excessive rendering after input
- Layout and style recalculation
- Large DOM structures
- Synchronous storage
- Third-party callbacks
- Hydration work
- Repeated state updates
- Expensive validation
- Main-thread work unrelated to the interaction
Test more than the first click. INP observes interactions across the page’s lifespan.
When CLS is high
Common causes include:
- Images or embeds without reserved dimensions
- Ads inserted without allocated space
- Cookie banners pushing existing content
- Web-font metric differences
- Dynamically inserted content above the viewport
- Animations that change layout properties
- Components that render different initial and hydrated layouts
Some movement is user-initiated and expected. CLS is designed to identify unexpected shifts, so inspect the individual shift clusters before changing the interface.
Common Web Performance Mistakes
Optimising only the homepage
Search results, product pages, articles, dashboards, and checkout flows may use entirely different templates. Prioritise high-traffic and high-value journeys.
Treating a Lighthouse score as the user experience
Lighthouse is a diagnostic test under one configuration. It cannot represent the full range of production devices, networks, cache states, and interactions.
Lazy-loading everything
Lazy loading conserves initial resources only when applied to non-critical content. Applying it to the hero image or content already in the first viewport can make the page slower.
Installing optimisation plugins without understanding them
Plugins may compress, combine, cache, or defer resources, but they can also duplicate functionality, break caching, delay important scripts, or hide the actual bottleneck.
Assuming a CDN fixes backend performance
A CDN helps when it can cache the requested content or shorten connection distance. A personalised, uncacheable response may still wait for the origin and database.
Removing useful features to improve a score
Performance is one product quality. Accessibility, security, analytics, functionality, and revenue also matter. Measure trade-offs and optimise the implementation before removing something users need.
A Practical Performance Workflow
| Phase | Action | Output |
| Discover | Review field metrics and business impact | Prioritised slow templates and user segments |
| Reproduce | Test under controlled lab conditions | Repeatable slow scenario |
| Diagnose | Inspect server timing, waterfall, LCP, shifts, and long tasks | Evidence-backed bottleneck |
| Improve | Make one focused architectural or delivery change | Reviewable implementation |
| Verify | Repeat lab tests and release gradually | Confirmation that the change helped |
| Observe | Compare production RUM and business metrics | Real-user impact |
| Protect | Add budgets, tests, and ownership | Reduced regression risk |
Frequently Asked Questions
What is web performance optimization?
Web performance optimization improves how quickly a website displays meaningful content, responds to interaction, and maintains visual stability across real devices and network conditions.
What are the current Core Web Vitals?
The current Core Web Vitals are Largest Contentful Paint, Interaction to Next Paint, and Cumulative Layout Shift. FID is no longer the current responsiveness metric.
What is a good Largest Contentful Paint score?
Google defines a good LCP as 2.5 seconds or less at the 75th percentile of page visits, evaluated separately for mobile and desktop.
How does a CDN improve performance?
A CDN can serve cacheable resources from infrastructure closer to users, reducing latency and origin load. Its effectiveness depends on cacheability, routing, configuration, and the location of the audience.
Does website performance affect SEO?
Yes. Core Web Vitals are part of Google’s page-experience signals. Performance also affects user behaviour and crawl efficiency, but it is not a substitute for relevant, high-quality content.
Final Thoughts
Web performance optimization is the process of removing delays from the complete user journey, not collecting isolated technical tricks.
Begin with real-user evidence. Determine whether the primary problem is server response, late resource discovery, heavy media, render-blocking CSS, JavaScript execution, third-party code, poor caching, or a combination of these factors.
Then make targeted changes and confirm their effect. A compressed image does not help if the server waits several seconds to send HTML. A CDN does not solve a long JavaScript task. A high Lighthouse score does not prove that later interactions remain responsive.
The final step is preventing regression. Performance budgets, automated checks, field monitoring, and clear ownership turn one-time optimisation into a durable engineering practice.



