How to Improve Website Performance
Diagnose slow pages with real-user and lab data, then target loading, responsiveness, and layout stability with a repeatable optimization workflow.
To improve website performance, first identify what real visitors experience, then use a controlled browser recording to locate the cause, make a targeted change, and check both lab results and field data afterward. Start with the three Core Web Vitals: Largest Contentful Paint (LCP) for loading, Interaction to Next Paint (INP) for responsiveness, and Cumulative Layout Shift (CLS) for visual stability. Good targets at the 75th percentile are LCP at or below 2.5 seconds, INP at or below 200 milliseconds, and CLS at or below 0.1. Google’s Web Vitals guidance defines these measures and recommends evaluating mobile and desktop separately.
A single Lighthouse score is not a complete performance diagnosis. Field data tells you what users encountered; lab tools help explain what happened in a repeatable session. Use both, fix the bottleneck the evidence points to, and keep monitoring after release.
1. Measure the experience visitors actually get
Begin with PageSpeed Insights. When sufficient Chrome User Experience Report (CrUX) observations exist, review its field data before its simulated Lighthouse report. Check the specific URL and the origin summary separately, and compare mobile with desktop. An origin aggregate can conceal a slow page, and a URL report may be unavailable when there is not enough data.
Core Web Vitals are judged at the 75th percentile: the goal is for at least three quarters of measured visits to meet the good threshold. Review LCP, INP, and CLS rather than optimizing for one lab score. Search Console’s Core Web Vitals report groups similar URLs and summarizes their field performance. If public field data is missing or too broad to diagnose a page, add real-user monitoring (RUM) so you can inspect your own visitors’ measurements.
| Metric | What it tells you | Good target at the 75th percentile |
|---|---|---|
| LCP | When the largest visible image or text block renders | 2.5 seconds or less |
| INP | Responsiveness across a visit’s interactions | 200 milliseconds or less |
| CLS | Unexpected movement of visible page content | 0.1 or less |
These are user-experience outcomes, not diagnoses. The same poor LCP could arise from slow initial HTML, late discovery of the hero image, slow image transfer, or delayed rendering. Measure first so you work on the cause rather than guess.
2. Reproduce the bottleneck in a browser
- Open the affected page in Chrome and use an Incognito window or a clean profile when extensions and existing storage might affect the result.
- Open DevTools, select the Network panel, enable the option to disable cache while DevTools is open, and reload. Inspect the request waterfall, response times, transferred sizes, redirects, and failed requests.
- Open the Performance panel and record a page load. If the issue occurs after load, record the interaction that exposes it as well. Inspect main-thread work, network activity, and relevant LCP or INP insights.
- Run a Lighthouse audit as a repeatable lab diagnostic. Keep the device and throttling settings consistent when comparing runs.
- Repeat a few times. A single run can be affected by cache state, server variation, competing work on the machine, and network conditions.
Lighthouse can help diagnose loading and layout behavior, but a simulated run without user input cannot measure INP. Total Blocking Time (TBT) is a lab signal that can point to potential interaction problems; it is not a substitute for field INP. Use actual interactions and field data to establish whether visitors experience slow responses. See the Chrome DevTools Performance panel guide for recording and trace inspection.
3. Improve loading performance (LCP)
LCP measures the time from navigation until the largest image or text block in the viewport renders. The useful target is 2.5 seconds or less for at least 75% of visits. Find the actual LCP element in PageSpeed Insights, Lighthouse, or a DevTools trace, then examine its timing and the initial document’s response. Follow the loading path in order.
Make the main resource discoverable early
If the LCP element is a hero image, make its URL visible in the initial HTML when possible. A resource hidden behind JavaScript, a CSS background, or a lazy-loading mechanism may not start downloading until browser work has already completed. Do not lazy-load an above-the-fold LCP image. If the image is referenced only from CSS and the trace confirms late discovery, consider preloading it:
<link rel="preload" fetchpriority="high" as="image" href="/images/hero.webp" type="image/webp">
Use preload selectively for the actual LCP resource. Preloading the wrong image or too many resources competes with other important downloads. Where a normal image element can expose the URL directly, prefer that straightforward discovery path; verify the effect in the waterfall.
Let the element render as soon as its data is ready
Look for JavaScript work that delays rendering after the image or font has arrived. A large main-thread task, client-side rendering dependency, or render-blocking stylesheet can leave the browser unable to paint. Use the Performance trace to identify the work at the time of the LCP event, then reduce or defer work only when the page can still render correctly.
Reduce transfer time without degrading the content
Inspect the actual LCP resource size and transfer duration. Serve appropriately sized images, choose an efficient format supported by your delivery path, and avoid shipping desktop-sized assets to small viewports. Preserve sufficient visual quality. If diagnostics show a slow image host or repeated long-distance transfer, consider caching or image delivery changes as possible implementation options; select them because the evidence points to delivery latency.
Deliver the initial HTML promptly
Check Time to First Byte (TTFB), redirects, and cache behavior. Slow TTFB can make a good LCP difficult because the browser cannot discover page resources before the HTML arrives. Redirect chains, server distance, network conditions, and cache bypass can contribute. Use the trace and server-side measurements to identify which applies. A faster server response, fewer redirects, or a suitable cache policy may help when that is the demonstrated bottleneck.
Google’s LCP guide frames optimization as four parts: start loading the LCP resource early, allow it to render promptly, reduce its load time without sacrificing quality, and deliver the initial HTML quickly.
4. Investigate responsiveness and layout stability
When interactions feel slow
INP reflects responsiveness across a user’s visit, so identify the interactions and real-user conditions associated with poor field results. A no-input Lighthouse run cannot establish field INP. Record the slow interaction in DevTools and inspect main-thread activity around it. Use TBT as a lab clue for potential blocking, then verify with field measurements. Avoid assuming that one generic code change will fix every slow interaction; the trace should show which work is delaying the response.
When content jumps
CLS measures unexpected layout movement. Compare field CLS with a browser session and note which visible elements move and when. Reproduce the same route and interaction state where possible, then inspect the recording around the shift. The specific cause depends on the page, so use the observed movement to guide the fix and confirm the result in field data rather than relying on a universal remedy.
5. Measure your own visitors with JavaScript
When CrUX does not provide enough page-level detail, collect RUM measurements. Google recommends the web-vitals JavaScript library as a small wrapper around browser APIs. The following browser-module example reports each metric to a same-origin endpoint; replace /rum with an endpoint your application implements. The receiving endpoint should validate and store the payload, and the page should avoid including personal data in it.
<script type="module">
import { onCLS, onINP, onLCP } from 'https://unpkg.com/web-vitals@4?module';
function sendToRUM(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating,
id: metric.id,
navigationType: metric.navigationType
});
if (navigator.sendBeacon) {
navigator.sendBeacon('/rum', new Blob([body], { type: 'application/json' }));
} else {
fetch('/rum', {
method: 'POST',
body,
headers: { 'Content-Type': 'application/json' },
keepalive: true
}).catch(() => {});
}
}
onLCP(sendToRUM);
onINP(sendToRUM);
onCLS(sendToRUM);
</script>
This example demonstrates collection, not a complete analytics backend. Pin and manage the library version through your application’s normal dependency process, and ensure the endpoint accepts the request format. Aggregate by metric, page template, device class, and time period; use percentiles rather than averages alone. Do not expect an individual page view to provide a stable percentile.
6. Verify each change without fooling yourself
- Repeat the same lab route, viewport, cache state, and throttling conditions used for the baseline.
- Compare the relevant trace and metric, not only the overall audit score.
- Check field data as it accumulates, segmented by mobile and desktop and by URL where sample size allows.
- Watch for tradeoffs: a change that speeds one resource can increase bytes or delay another; a lab improvement may not shift field results if the original issue was not common among users.
- Keep monitoring after release. Device capability, user networks, and interaction patterns differ from a controlled lab session.
Lab measurements are useful for development because they are repeatable; field measurements show the experience visitors had. Neither alone answers both questions. Google summarizes this distinction in its Web Vitals guidance.
7. Troubleshooting common performance investigations
| Symptom or error | Likely cause | What to check or change |
|---|---|---|
| PageSpeed Insights has no URL field data | There may not be enough CrUX observations for that URL. | Check origin-level data for context, then instrument RUM for page-specific evidence. |
| Origin looks good but one route is slow | The origin aggregate can hide a route or template problem. | Compare URL-level results and inspect that route directly in DevTools. |
| Lighthouse looks good but users report slow interactions | A lab run without interaction does not measure field INP. | Capture real-user INP or reproduce the relevant interaction in DevTools; treat TBT as a clue only. |
| LCP image begins late in the waterfall | Its URL may be discovered through CSS or JavaScript, or it may be inappropriately lazy-loaded. | Expose it early in HTML or selectively preload the confirmed LCP image; recheck the waterfall. |
| Image downloads quickly but LCP is still late | Rendering may wait on main-thread JavaScript, styles, or other browser work. | Inspect the Performance trace around LCP and address the work that actually precedes paint. |
| TTFB is high or inconsistent | Redirects, distance, network conditions, or cache bypass can delay the document. | Inspect redirects, server response, and cache behavior; avoid changing infrastructure until measurements identify the source. |
| Before-and-after scores vary widely | Runs may differ in cache state, network, device activity, or server conditions. | Align settings, repeat runs, and compare field percentiles over time. |
| RUM events do not arrive | The endpoint may reject the content type, the request may fail, or the page may unload before delivery. | Check browser Network and server logs, support the beacon payload format, and use the keepalive fallback shown above. |
8. Performance, reliability, and cost considerations
Performance work has an opportunity cost: begin with the issue affecting the most visits or the largest user-visible delay, and measure again before broad architectural changes. Repeatable lab runs are relatively quick to use during development, while field percentiles require enough real visits and time to represent your audience. RUM adds a data-collection endpoint and operational work; keep the payload minimal and monitor whether reporting itself succeeds.
Reliability matters alongside speed. Preserve page behavior while deferring or trimming work, keep a baseline, and monitor after deployment for regressions. Avoid treating a passing aggregate as proof that every route or device is fast. When choosing paid hosting, caching, or image-delivery options, first confirm that server response, caching, or asset transfer is the measured bottleneck; the research does not establish a universal service or expected improvement.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It is useful for capturing visual snapshots while you inspect a page; a screenshot is not a substitute for Core Web Vitals field data, Lighthouse, or a performance trace. One GET request returns an image or PDF. Example using cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners are accepted like a visitor and removed along with 60+ known consent platforms, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which page verdict and billing status applied. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
FAQ
How do I improve website performance?
Measure field experience, reproduce the bottleneck in a browser, make a targeted change, and verify the result in both lab and field data.
How can I make my website load faster?
Find the LCP element and inspect the full path: initial HTML, when its resource starts, its transfer time, and the work required before it renders.
Why is my website slow?
There is no single universal cause. Field data and a browser trace help distinguish slow server response, late resource discovery, transfer delays, main-thread work, sluggish interactions, and layout movement.
How do I improve Core Web Vitals?
Use the 75th-percentile LCP, INP, and CLS results for mobile and desktop to choose the page and metric to investigate, then verify after each change.


