---
title: "How to Fix INP: Find and Fix Slow Interactions — Dardo"
description: "Fix Interaction to Next Paint step by step: field data, LoAF attribution, code for yielding and hydration, and INP pass rates by platform and country."
url: "https://dardo.studio/en/blog/fix-inp/"
language: "en"
translations: {"es":"https://dardo.studio/es/blog/mejorar-inp/","pt":"https://dardo.studio/pt/blog/melhorar-inp/"}
updated: "2026-10-17T23:33:18.424Z"
---

[Blog](https://dardo.studio/en/blog/)

# How to fix INP (Interaction to Next Paint): find the slow interaction, name the script, fix the cause

INP is good at 200 ms or less for 75% of visits. Find the slow tap and the script behind it with field data, then fix input delay, handlers or rendering.

By [Nicolás Cerón](https://dardo.studio/en/nicolas-ceron/) ·October 17, 2026

![A dark greenhouse at night where a single crimson cord, just pulled, swings a small bell under warm lamplight.](https://dardo.studio/_astro/01M563C6K280JMFH9G8YY84R6R_TIwp5.webp)

## Key takeaways

- INP is good when 75% of visits respond to clicks, taps and key presses within 200 milliseconds, and poor above 500 milliseconds; it replaced First Input Delay as a Core Web Vital on 12 March 2024.
- Every interaction splits into input delay, processing and presentation delay, and the long part tells you whether to fix load-time scripts, event handlers or rendering.
- The attribution build of web-vitals and the Long Animation Frames API name the element, the slow part and the script URL, which separates your code from a vendor's.
- In September 2026, 97.6% of sites had good INP on desktop but 79.4% on mobile, and only 59.7% of Next.js sites and 62.9% of sites measured in Colombia did on mobile.
- Breaking long tasks up with scheduler.yield() and a setTimeout fallback, delaying non-essential tags and hydrating less JavaScript fix most poor INP on marketing sites.

## The short answer

Interaction to Next Paint (INP) is good when 75% of visits respond to clicks, taps and key presses within 200 milliseconds, and poor above 500 milliseconds. To fix it, first find the slow interaction and the script behind it with field data (the attribution build of web-vitals and the Long Animation Frames API), then fix the part of the interaction that's long: input delay (other work blocking the main thread, usually during load), processing (your event handlers) or presentation (the rendering work that follows).

Most poor INP on marketing sites comes from three places: third-party tags running when someone taps, framework hydration during load, and handlers that do everything before the browser can paint. Breaking long tasks up and yielding to the main thread fixes most of it.

INP is mostly a phone problem. In September 2026, 97.6% of sites had good INP on desktop, but 79.4% on mobile, and 62.9% in Colombia, 55.3% in Brazil and 59.7% of Next.js sites worldwide (data below).

This guide goes deep on INP only. For all three Core Web Vitals and how to verify a fix in Google's 28-day data, see our [Core Web Vitals playbook](https://dardo.studio/en/blog/pass-core-web-vitals/).

## What INP measures, and what it doesn't

INP observes every click, tap and key press during a visit and reports the slowest one, ignoring one outlier for every 50 interactions ([web.dev](https://web.dev/articles/inp)). Hovering, scrolling and zooming don't count. A page that nobody interacted with has no INP at all, so pages with little to click often show no INP data.

The thresholds, measured at the 75th percentile of visits, separately for mobile and desktop:

| INP at the 75th percentile | Rating            |
| -------------------------- | ----------------- |
| 200 ms or less             | Good              |
| Over 200 ms, up to 500 ms  | Needs improvement |
| Over 500 ms                | Poor              |

INP replaced First Input Delay as a Core Web Vital on 12 March 2024 ([web.dev](https://web.dev/blog/inp-cwv-launch)). The difference matters for diagnosis: FID only timed the wait before the first interaction's handlers started. INP times every interaction, from the tap to the next painted frame, in three parts:

| Part                | What it is                               | Usually caused by                                                          | First fix                                               |
| ------------------- | ---------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------- |
| Input delay         | Tap until your handlers start            | Long tasks already running: script evaluation, hydration, tags, timers     | Break up and defer work during load                     |
| Processing duration | Your handlers running                    | Handlers that do everything at once; forced layout                         | Paint the visible change first, yield, then do the rest |
| Presentation delay  | Handlers done until the frame is painted | Large DOM, big style and layout recalculations, client-side HTML rendering | Smaller updates, content-visibility, less DOM           |

Two details catch teams out. Interactions inside iframes count toward the page's INP in Chrome's data, but JavaScript on the page can't see them, so your own measurement and CrUX can differ ([web-vitals](https://github.com/GoogleChrome/web-vitals)). And a long task is any task over 50 milliseconds; the browser can't respond to input until the current task finishes ([web.dev](https://web.dev/articles/optimize-long-tasks)).

## How sites score on INP, by platform and country

We read the HTTP Archive's [technology report API](https://cdn.httparchive.org/v1/cwv?technology=ALL&geo=ALL&rank=ALL&start=latest) on 17 October 2026. Its latest release, September 2026, is built from the Chrome UX Report: the share of sites (origins) on each platform whose real Chrome visitors on phones got a good INP. Our [website platform speed report](https://dardo.studio/en/tools/website-platform-speed-report/) shows the same data for every platform and metric, updated monthly.

| Platform (mobile, good INP) | All countries | United States | Mexico | Colombia | Brazil |
| --------------------------- | ------------- | ------------- | ------ | -------- | ------ |
| Squarespace                 | 97.3%         | 98.6%         | 81.4%  | 81.0%    | 82.8%  |
| Wix                         | 92.6%         | 96.6%         | 82.8%  | 82.9%    | 83.9%  |
| WordPress                   | 90.3%         | 92.6%         | 78.2%  | 77.1%    | 78.8%  |
| Webflow                     | 88.0%         | 92.4%         | 68.0%  | 57.9%    | 61.9%  |
| Shopify                     | 86.7%         | 95.1%         | 71.5%  | 56.0%    | 64.8%  |
| HubSpot CMS                 | 86.2%         | 92.4%         | 63.1%  | 57.7%    | 55.5%  |
| Astro                       | 85.0%         | 92.6%         | 68.7%  | 65.3%    | 67.7%  |
| Framer                      | 80.3%         | 88.2%         | 56.8%  | 37.9%    | 57.6%  |
| All sites                   | 79.4%         | 87.3%         | 66.4%  | 62.9%    | 55.3%  |
| Gatsby                      | 76.0%         | 78.1%         | 57.6%  | 51.6%    | 55.2%  |
| Nuxt                        | 64.1%         | 83.9%         | 45.8%  | 38.7%    | 32.4%  |
| Next.js                     | 59.7%         | 75.9%         | 43.5%  | 37.4%    | 40.2%  |
| VTEX                        | 39.3%         | 57.3%         | 32.5%  | 23.7%    | 40.5%  |

Source: HTTP Archive technology report, September 2026 release (Chrome UX Report field data), mobile. Colombia's Framer row covers 116 sites; every other cell covers more than 120.

What the table says:

- **INP is a phone problem.** On desktop, 97.6% of all sites had good INP; on mobile, 79.4%. Next.js sites drop from 94.2% on desktop to 59.7% on mobile. Same code, slower processors.
- **JavaScript frameworks fail INP; WordPress fails elsewhere.** 90.3% of WordPress sites had good INP, but only 48.3% passed all three Core Web Vitals on mobile, so WordPress's problem is mostly loading. For Next.js (35.7% passing overall) and Nuxt (28.8%), INP is the metric that fails.
- **The country moves the number more than the platform.** A Webflow or Shopify site that's good for 92–95% of US sites is good for 56–58% of sites measured in Colombia. Our [Latin America Core Web Vitals study](https://dardo.studio/en/blog/core-web-vitals-latin-america/) explains why: the same pages, run on mid-range Android phones.
- **It's improving, unevenly.** Across all sites, good mobile INP rose from 71.6% in March 2024 to a peak of 82.3% in April 2026, then eased to 79.4% by September 2026. Chrome 147 changed how interactions are recorded so that fewer are dropped from CrUX; Chrome says this doesn't change individual durations but raises coverage ([Chromium changelog](https://chromium.googlesource.com/chromium/src/+/main/docs/speed/metrics%5Fchangelog/2026%5F02%5Finp.md)). This data can't tell how much of the dip that explains. Brazil's figure fell furthest, from 65.1% in April to 55.3% in September, partly because about 30,000 more Vue.js sites, only 15.8% of them with good INP, entered the Brazilian data in July. Next.js improved most over the whole period: from 37.3% in March 2024 to 59.7%.

The platform is a correlation, not a verdict. A Next.js site is more often an app with filters and logged-in state; a Squarespace site is more often a brochure. Your own template's data is what decides.

### Sites that carry common third-party tags

The same report can be filtered by technologies detected on a site, including tags. These are the shares of sites with good mobile INP among sites that carry each tag, worldwide, against 79.4% for all sites:

| Tag on the site    | Category          | Sites measured | Good INP (mobile) |
| ------------------ | ----------------- | -------------- | ----------------- |
| CookieYes          | Consent banner    | 178,408        | 92.4%             |
| Cookiebot          | Consent banner    | 122,868        | 88.8%             |
| Google Tag Manager | Tag manager       | 2,082,037      | 77.7%             |
| OneTrust           | Consent banner    | 97,352         | 75.6%             |
| Zendesk            | Chat and support  | 152,504        | 75.8%             |
| Facebook Pixel     | Ads               | 1,291,616      | 73.7%             |
| Hotjar             | Session recording | 153,395        | 73.1%             |
| Microsoft Clarity  | Session recording | 485,305        | 68.8%             |
| VWO                | A/B testing       | 19,735         | 65.3%             |
| Intercom           | Chat and support  | 18,950         | 60.2%             |
| Optimizely         | A/B testing       | 21,048         | 57.6%             |
| TikTok Pixel       | Ads               | 169,710        | 51.4%             |

Source: HTTP Archive technology report, September 2026, all countries.

Read this with care: it describes sites that carry a tag, not the tag's own cost. Sites with Optimizely or Intercom tend to be larger sites with more of everything, and consent tools used on small WordPress sites inherit those sites' good numbers. What holds regardless: Google's tag guidance reports "a correlation between the size of tag managers and poorer INP scores" ([web.dev](https://web.dev/articles/tag-best-practices)), and A/B testing, chat and session recording all run code in the page while people use it.

## Step 1: confirm INP is the problem, and on which template

Start with Google's field data, mobile first:

- **Search Console's** [**Core Web Vitals report**](https://support.google.com/webmasters/answer/9205520) groups similar URLs and shows each group's INP at the 75th percentile over 28 days. Groups are sorted by impressions, so the first example URL tells you which template to fix first. A group can appear without INP data, because Search Console only requires enough LCP and CLS data to list it.
- **PageSpeed Insights** shows the same Chrome data for one URL, or for the whole origin when the URL has too few visits. Check which one you're reading.
- **No field data at all** usually means the site has too few Chrome visitors to be included. Then your own measurement is the only field data you'll have.

The Web Almanac adds a useful prior: in 2025, 80% of mobile home pages had good INP, but only 69% of other pages ([HTTP Archive](https://almanac.httparchive.org/en/2025/performance)). Listing pages, product pages and anything with filters are where to look.

## Step 2: find the interaction and the script, in the field

CrUX tells you that INP is poor, not why. For why, collect attribution from real visits. The [web-vitals](https://github.com/GoogleChrome/web-vitals) library (version 6.2.3, released 5 October 2026) has an attribution build that reports, for the slowest interaction of each visit: the element, the three parts, whether the page was still loading, and the longest script that overlapped it.

```js
import {onINP} from 'web-vitals/attribution';

onINP(({value, rating, attribution: a}) => {
  const script = a.longestScript?.entry;
  navigator.sendBeacon('/rum', JSON.stringify({
    page: location.pathname,
    inp: Math.round(value),
    rating,
    target: a.interactionTarget,       // which element was tapped
    loadState: a.loadState,            // was the page still loading?
    inputDelay: Math.round(a.inputDelay),
    processing: Math.round(a.processingDuration),
    presentation: Math.round(a.presentationDelay),
    scriptURL: script?.sourceURL,      // your bundle or a vendor's
    scriptInvoker: script?.invoker,    // e.g. BUTTON.onclick
    scriptPart: a.longestScript?.subpart,
  }));
});
```

The script fields come from the [Long Animation Frames API](https://developer.chrome.com/docs/web-platform/long-animation-frames) (LoAF), shipped in Chrome 123. It reports frames delayed beyond 50 milliseconds and names each script that ran more than 5 milliseconds in them, with its URL, function name and how it was called. That's how you tell your own code from a vendor's. Its limits: no attribution for scripts inside cross-origin iframes, and it exists only in Chromium browsers.

You can also watch LoAF directly while you test:

```js
new PerformanceObserver((list) => {
  for (const frame of list.getEntries()) {
    if (frame.blockingDuration < 100) continue;
    for (const s of frame.scripts) {
      console.log(Math.round(s.duration), s.invokerType, s.invoker, s.sourceURL);
    }
  }
}).observe({type: 'long-animation-frame', buffered: true});
```

Measurement now reaches beyond Chrome: the [web-vitals](https://github.com/GoogleChrome/web-vitals) README lists `onINP()` as supported in Chromium, Firefox and Safari, now that both of the latter expose the interaction data it relies on. Google's INP numbers still come from Chrome users only, but you can now see whether iPhone visitors have the same slow interaction.

Then group the data by target element, load state and the longest part. The pattern points at the fix:

| What the data shows                                                   | Likely cause                                     | Go to                             |
| --------------------------------------------------------------------- | ------------------------------------------------ | --------------------------------- |
| Long input delay, loadState "dom-interactive" or "dom-content-loaded" | Script evaluation, hydration or tags during load | Long tasks during load; hydration |
| Long input delay after load, scriptURL a vendor's                     | A tag's timers or listeners                      | Third-party tags                  |
| Long processing, scriptURL your bundle                                | The handler itself                               | Expensive event handlers          |
| Long processing with forced style and layout                          | Reading layout after changing styles             | Layout thrashing                  |
| Long presentation delay                                               | Too much to re-render                            | Large DOM and big updates         |

## Step 3: reproduce it in Chrome DevTools

Open the [Performance panel](https://developer.chrome.com/docs/devtools/performance/overview). Without recording, it shows your local INP as you click and lists each interaction with its element and its three parts. Connect it to field data and it compares your local numbers with your real visitors' and suggests settings to match them.

Slow the CPU to match the phones your visitors use: DevTools can calibrate CPU throttling presets to approximate low- and mid-tier mobile devices. Then record while you tap the element your field data named, ideally while the page is still loading, since that's when the main thread is busiest. In the recording, find the interaction in the Interactions track and read the main-thread tasks beneath it; long tasks carry a red triangle ([web.dev](https://web.dev/articles/optimize-long-tasks)).

A Lighthouse page-load test doesn't tap anything, so it can't measure INP. Google suggests its Total Blocking Time as a proxy for load-time input delay, not a substitute ([web.dev](https://web.dev/articles/inp)).

## Fixes, by cause

### Long tasks: break them up and yield

The browser can't respond while a task runs, so split long work and give the main thread back between pieces. `scheduler.yield()` does that and resumes your code ahead of other queued work. It's in Chrome and Edge 129 and Firefox 142, not in Safari as of October 2026, so use it with a fallback ([web.dev](https://web.dev/articles/optimize-long-tasks)):

```js
function yieldToMain() {
  if (globalThis.scheduler?.yield) return scheduler.yield();
  return new Promise((resolve) => setTimeout(resolve, 0));
}

filterButton.addEventListener('click', async () => {
  showSpinner();            // the visible response
  await yieldToMain();      // let the browser paint it
  renderResults(filterProducts(state));
  await yieldToMain();
  sendAnalytics('filter_applied');
});
```

For loops over many items, yield only when about 50 milliseconds have passed since the last yield, so the yielding overhead doesn't add up. Two traps: `forEach` doesn't wait for an awaited yield, so use `for…of`; and Google no longer recommends `isInputPending()`.

### Third-party tags

Tags hurt INP two ways: their scripts make input wait during load, and their listeners run when people click.

- **The consent banner's Accept button.** Accepting often starts every tag at once. A consent tool can yield right after the click so the banner closes in the next frame; PubTech reported that doing so reduced INP on its consent tool's customer sites by up to 64% ([web.dev case study](https://web.dev/case-studies/pubconsent-inp)). If your vendor doesn't, ask.
- **Fire non-essential tags after Window Loaded** in Google Tag Manager, and prefer image tags and templates to Custom HTML tags, which Google ranks as the costliest type ([web.dev](https://web.dev/articles/tag-best-practices)).
- **Remove what nobody reads.** Session recording, heatmaps and A/B testing scripts that ran for a past project are common. QuintoAndar, the largest housing platform in Brazil, removed third-party pixels as part of the work that cut its INP by 80% ([web.dev case study](https://web.dev/case-studies/quintoandar-inp)).

Use LoAF's `sourceURL` to name the vendor before you remove anything, so the decision rests on data rather than suspicion.

### Hydration of big frameworks

Server-rendered pages look ready before they are: the page "can't actually respond to input until the client-side scripts for components are executed and event handlers have been attached," and that cost shows up in INP ([web.dev](https://web.dev/articles/rendering-on-the-web)). That matches the table above, where the JavaScript-framework rows sit lowest.

- **Ship less component JavaScript.** In Next.js, every import of a file marked `'use client'` ends up in the client bundle ([Next.js docs](https://nextjs.org/docs/app/getting-started/server-and-client-components)), so keep that boundary low in the tree, around the interactive part only.
- **Hydrate later, or only what's interactive.** Astro renders static HTML and hydrates only the components you mark, when you choose ([Astro docs](https://docs.astro.build/en/concepts/islands/)):

```html
<ProductFilters client:visible />
<NewsletterSignup client:idle />
```

- **Mark non-urgent React updates as transitions** with `useTransition`, so typing stays responsive while results re-render. QuintoAndar used transitions this way ([web.dev case study](https://web.dev/case-studies/quintoandar-inp)):

```jsx
const [isPending, startTransition] = useTransition();

function onSearchChange(e) {
  setQuery(e.target.value);                          // urgent: the input
  startTransition(() => setResultsFilter(e.target.value)); // can wait
}
```

If a framework is the wrong tool for a mostly static marketing site, our comparison of [Astro and Next.js](https://dardo.studio/en/blog/astro-vs-nextjs/) covers when each fits.

### Expensive event handlers

Do only what the next frame needs inside the handler, and move the rest after the paint. Debounce handlers that fire repeatedly, such as scroll, input and resize. And watch how much work one interaction triggers: bus-ticket site redBus reported that fetching 10 results per lazy load instead of 30 brought those interactions from 870–900 to 350–370 milliseconds ([web.dev case study](https://web.dev/case-studies/redbus-inp)).

### Layout thrashing

Reading a layout property (`offsetWidth`, `getBoundingClientRect()`, `scrollHeight`) after changing styles forces the browser to lay out the page on the spot. In a loop, it does that every time ([web.dev](https://web.dev/articles/avoid-large-complex-layouts-and-layout-thrashing)):

```js
// Forces a layout on every iteration after the first
for (const bar of bars) {
  bar.style.width = container.offsetWidth * bar.dataset.share + 'px';
}

// Read once, then write
const width = container.offsetWidth;
for (const bar of bars) {
  bar.style.width = width * bar.dataset.share + 'px';
}
```

LoAF reports it as `forcedStyleAndLayoutDuration` on each script, and DevTools marks the Layout or Recalculate Style task with a red triangle.

### Large DOM and big rendering updates

Rendering work grows with DOM size, so render menus, tabs and long lists when they're needed rather than all up front. The Economic Times removed about 1,200 nodes by rendering its menu only when opened, part of the work that took its INP from over 1,000 to 257 milliseconds ([web.dev case study](https://web.dev/case-studies/economic-times-inp)).

For long pages, `content-visibility: auto` skips rendering for sections far from the viewport; in Google's demo, rendering went from 232 to 30 milliseconds on load ([web.dev](https://web.dev/articles/content-visibility)). Give each section a placeholder size so the scrollbar doesn't jump:

```css
.long-page section {
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}
```

The same web.dev page lists support in Chrome 85, Firefox 125 and Safari 18. Off-screen content stays in the accessibility tree and stays searchable with find-in-page.

## Verify the fix

Your own measurement shows a fix within days. Google's data won't: Search Console and PageSpeed Insights read a rolling 28-day window, so a fix shipped today is fully reflected about four weeks later. Ship one INP fix per release when you can, and note the date, so you know which change moved the number. Our [Core Web Vitals playbook](https://dardo.studio/en/blog/pass-core-web-vitals/) covers validation in Search Console step by step.

## INP checklist

| Step                      | Done when                                                                                  |
| ------------------------- | ------------------------------------------------------------------------------------------ |
| Find the failing template | Search Console names the URL group with poor INP on mobile                                 |
| Collect attribution       | Field data shows the element, the longest part and the script for the slowest interactions |
| Reproduce                 | The same interaction is slow in DevTools with calibrated CPU throttling                    |
| Fix load-time input delay | No long tasks from tags or hydration where people tap first                                |
| Fix handlers              | The visible change paints before the rest of the work runs                                 |
| Fix rendering             | No forced layouts in handlers; long pages use content-visibility                           |
| Verify                    | Your own data improves within days; Google's 28-day data about four weeks after release    |

## What to do next

Check how sites on your platform do in your visitors' country in our [website platform speed report](https://dardo.studio/en/tools/website-platform-speed-report/), then add the web-vitals attribution snippet above to your site and let it collect a week of data. If you'd rather hand the diagnosis and fixes over, that's our [website speed optimization](https://dardo.studio/en/services/website-speed-optimization/) service, and deeper rebuilds of slow interfaces are [web development](https://dardo.studio/en/services/web-development/) work.

## Common questions

**What is a good INP score?**

200 milliseconds or less at the 75th percentile of visits, measured separately for mobile and desktop. Between 200 and 500 milliseconds needs improvement, and above 500 milliseconds is poor. Google's tools report the value over a rolling 28 days.

**What is the difference between INP and FID?**

First Input Delay only measured the wait before the first interaction's handlers started. INP measures every click, tap and key press in a visit, from the input to the next painted frame, and reports the slowest one, ignoring one outlier per 50 interactions. INP replaced FID as a Core Web Vital on 12 March 2024.

**Why is my INP poor on mobile but good on desktop?**

Phones run the same JavaScript on slower processors, so a task that's short on a laptop can become a long task on a mid-range Android phone. In September 2026, 97.6% of sites had good INP on desktop and 79.4% on mobile. Test with CPU throttling calibrated to a mid-tier phone.

**Why does PageSpeed Insights show no INP for my page?**

INP only exists when visitors click, tap or type, and Chrome's data only covers pages and sites with enough eligible visits. A page few people interact with, or a small site, may have no INP data at all. Measure it on your own visits with the web-vitals library instead.

**Does scheduler.yield() work in every browser?**

No. As of October 2026 it works in Chrome and Edge 129 and later and Firefox 142 and later, but not in Safari. Use a small helper that calls scheduler.yield() when it exists and falls back to a setTimeout promise, so every browser still yields.

**Can a plugin fix INP?**

Rarely on its own. Caching and image plugins speed up loading, but INP depends on which scripts run when someone taps, how much work each handler does and how much the page re-renders. Those live in your templates, components and tag settings, which is where INP gets fixed.

## Sources & further reading

Sources behind this page, with further detail from the original publishers.

- [web.dev: Interaction to Next Paint (INP)](https://web.dev/articles/inp) · web.dev
- [web.dev: Interaction to Next Paint is officially a Core Web Vital](https://web.dev/blog/inp-cwv-launch) · web.dev
- [web.dev: Optimize long tasks](https://web.dev/articles/optimize-long-tasks) · web.dev
- [HTTP Archive: Technology report API, Core Web Vitals endpoint (September 2026 release)](https://cdn.httparchive.org/v1/cwv?technology=ALL&geo=ALL&rank=ALL&start=latest) · cdn.httparchive.org
- [Chromium: Interaction to Next Paint changes in Chrome 147](https://chromium.googlesource.com/chromium/src/+/main/docs/speed/metrics%5Fchangelog/2026%5F02%5Finp.md) · chromium.googlesource.com
- [web.dev: Best practices for tags and tag managers](https://web.dev/articles/tag-best-practices) · web.dev
- [Search Console Help: Core Web Vitals report](https://support.google.com/webmasters/answer/9205520) · support.google.com
- [HTTP Archive: Web Almanac 2025, Performance](https://almanac.httparchive.org/en/2025/performance) · almanac.httparchive.org
- [GoogleChrome on GitHub: web-vitals library](https://github.com/GoogleChrome/web-vitals) · github.com
- [Chrome for Developers: Long Animation Frames API](https://developer.chrome.com/docs/web-platform/long-animation-frames) · developer.chrome.com
- [Chrome for Developers: Performance panel](https://developer.chrome.com/docs/devtools/performance/overview) · developer.chrome.com
- [web.dev: How PubTech's consent management platform reduced INP](https://web.dev/case-studies/pubconsent-inp) · web.dev
- [web.dev: How QuintoAndar reduced INP by 80%](https://web.dev/case-studies/quintoandar-inp) · web.dev
- [web.dev: Rendering on the web](https://web.dev/articles/rendering-on-the-web) · web.dev
- [Next.js docs: Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components) · nextjs.org
- [Astro docs: Islands architecture](https://docs.astro.build/en/concepts/islands/) · docs.astro.build
- [web.dev: How redBus improved INP](https://web.dev/case-studies/redbus-inp) · web.dev
- [web.dev: Avoid large, complex layouts and layout thrashing](https://web.dev/articles/avoid-large-complex-layouts-and-layout-thrashing) · web.dev
- [web.dev: Economic Times quest for fixing INP](https://web.dev/case-studies/economic-times-inp) · web.dev
- [web.dev: content-visibility](https://web.dev/articles/content-visibility) · web.dev

[Nicolás Cerón](https://dardo.studio/en/nicolas-ceron/)

Nicolás Cerón is the founder of Dardo, a brand, web design and development studio in Bogotá, Colombia.

## Related articles

- [**How to improve Core Web Vitals: a field-data-first playbook for marketing sites**Find the failing metric and template in Search Console, fix LCP, INP and CLS by their cause, then confirm the result in field data about 28 days later.](https://dardo.studio/en/blog/pass-core-web-vitals/)
- [**Core Web Vitals in Latin America: how many sites pass in each country, and why mobile fails (2026 data)**In September 2026, a third of sites passed Core Web Vitals for mobile visitors in Colombia and Brazil, against 63% in the US. Data by country and what to do.](https://dardo.studio/en/blog/core-web-vitals-latin-america/)
- [**Website redesign checklist: what to do before, during and after launch, with the SEO checks**A website redesign checklist by phase: what to export first, what to build, how to keep SEO, what to test at launch and what to watch for 90 days.](https://dardo.studio/en/blog/website-redesign-checklist/)
- [**Astro vs Next.js: which to choose for a marketing site or a product in 2026**Astro for sites that look the same to every visitor, Next.js for signed-in products: rendering, JavaScript, hosting and support compared.](https://dardo.studio/en/blog/astro-vs-nextjs/)

## Keep exploring.

- [Service · **Website speed and Core Web Vitals optimization**](https://dardo.studio/en/services/website-speed-optimization/)

- [Your project · **Start a conversation**](https://dardo.studio/en/contact/)
