Miksi INP on vuoden 2026 tärkein suorituskykymittari?
Interaction to Next Paint (INP) korvasi First Input Delay (FID) -mittarin maaliskuussa 2024, ja nyt kaksi vuotta myöhemmin tilanne on aika selvä: INP on Core Web Vitals -mittareista ehdottomasti vaikein läpäistä. Vuoden 2026 alussa 43 % verkkosivustoista ei edelleenkään täytä INP:n 200 millisekunnin raja-arvoa. Se on yleisimmin hylätty Core Web Vitals -mittari koko verkossa.
Mutta miksi INP on niin paljon vaikeampi kuin edeltäjänsä FID?
Syy on yksinkertaisesti mittaustavassa. FID mittasi vain ensimmäisen vuorovaikutuksen viiveen — eli ajan ensimmäisestä klikkauksesta siihen, kun selain alkoi käsitellä tapahtumaa. INP sen sijaan mittaa kaikkien vuorovaikutusten viivettä koko sivuvierailun ajan ja raportoi pahimman tapauksen 75. persentiilissä. Käytännössä tämä tarkoittaa, että yksikin hidas napinpainallus tai pudotusvalikon avaus voi pilata koko sivun INP-arvon. Aika armotonta, eikö?
INP:n kolme vaihetta — ja mistä hitaus oikeasti johtuu
Jokainen INP-mittaus koostuu kolmesta peräkkäisestä vaiheesta. Jos haluat onnistua optimoinnissa, sinun täytyy ymmärtää jokainen vaihe ja tietää, mihin puuttua.
1. Syöteviive (Input Delay)
Syöteviive on aika käyttäjän vuorovaikutuksesta (vaikkapa klikkauksesta) siihen hetkeen, kun selain alkaa suorittaa tapahtumankäsittelijää. Viive syntyy, koska selaimen pääsäie on varattu muulla työllä — JavaScript-tiedostojen jäsentämisellä, aikaisempien tehtävien suorittamisella tai kolmannen osapuolen skriptien ajamisella.
Ja tässä tulee mielenkiintoinen yksityiskohta: sivun latausvaiheen aikana tapahtuvien vuorovaikutusten p75 INP on 132 ms, kun taas latauksen jälkeen vastaava arvo on vain 50 ms. Se on 2,6-kertainen ero! Tämä kertoo selkeästi, että pääsäikeen kuormituksen vähentäminen sivun käynnistyksen aikana on yksi tehokkaimmista INP-optimointikeinoista.
2. Prosessointiviive (Processing Time)
Prosessointiviive kattaa ajan, joka kuluu tapahtumankäsittelijöiden koodin suorittamiseen. Jokainen millisekunti klikkaustapahtuman käsittelijässä lisätään suoraan INP-arvoon — tässä ei ole mitään puskuria tai armoa. Raskaat laskutoimitukset, DOM-manipulaatiot ja synkroniset operaatiot ovat tyypillisiä syyllisiä.
3. Esitysviive (Presentation Delay)
Esitysviive on aika tapahtumankäsittelijän valmistumisesta seuraavan ruudun piirtämiseen. CSS-animaatiot, suodattimet, varjot ja monimutkaiset taitot lisäävät esitysviivettä. Tähän vaiheeseen vaikuttaa merkittävästi myös DOM-puun koko — mitä suurempi puu, sitä hitaampi tyylienlaskenta ja taitto.
Käytännön optimointitekniikat koodiesimerkein
No niin, teoriasta käytäntöön. Käydään läpi konkreettisia tekniikoita, joilla INP-arvoa saa oikeasti parannettua.
Pitkien tehtävien pilkkominen scheduler.yield()-rajapinnalla
scheduler.yield() on rehellisesti sanottuna yksi parhaista työkaluista INP-ongelmien ratkaisemiseen. Se palauttaa lupauksen (Promise) ja luovuttaa hallinnan takaisin pääsäikeelle, jolloin selain voi käsitellä odottavat käyttäjän vuorovaikutukset.
Mikä tekee siitä erityisen hyvän verrattuna vanhaan setTimeout-tekniikkaan? Se asettaa jatkotehtävän korkeammalle prioriteetille jonossa. Oma koodisi ei siis jää muiden skriptien jalkoihin.
// Esimerkki: Raskas silmukka, joka luovuttaa hallinnan jokaisen erän jälkeen
async function processLargeDataset(items) {
const BATCH_SIZE = 50;
for (let i = 0; i < items.length; i += BATCH_SIZE) {
const batch = items.slice(i, i + BATCH_SIZE);
batch.forEach(item => processItem(item));
// Luovuta hallinta pääsäikeelle — selain voi käsitellä
// käyttäjän klikkaukset ja muut vuorovaikutukset
if (navigator.scheduling?.isInputPending() || i + BATCH_SIZE < items.length) {
await scheduler.yield();
}
}
}
// Varatekniikka selaimille, jotka eivät tue scheduler.yield()
function yieldToMain() {
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}
return new Promise(resolve => setTimeout(resolve, 0));
}
Web Worker -tekniikka raskaiden laskutoimitusten siirtämiseen
Tässä on tärkeä oivallus: kaikki raskas prosessointi ei välttämättä hidasta vuorovaikutuksia. Vain pääsäikeellä suoritettavat hitaat tehtävät aiheuttavat ongelmia. Web Workerit mahdollistavat raskaan laskennan siirtämisen erilliselle säikeelle, jolloin pääsäie pysyy vapaana käyttäjän syötteille.
// main.js — Pääsäikeen koodi
const worker = new Worker('data-processor.js');
document.getElementById('sort-btn').addEventListener('click', () => {
// Näytä välitön visuaalinen palaute
showLoadingSpinner();
// Siirrä raskas työ Web Workerille
worker.postMessage({ action: 'sort', data: largeDataset });
});
worker.onmessage = (event) => {
// Vastaanota tulos ja päivitä käyttöliittymä
hideLoadingSpinner();
renderSortedData(event.data);
};
// data-processor.js — Web Worker
self.onmessage = (event) => {
const { action, data } = event.data;
if (action === 'sort') {
// Raskas lajittelu tapahtuu erillisellä säikeellä
const sorted = data.sort((a, b) => complexCompare(a, b));
self.postMessage(sorted);
}
};
Tapahtumankäsittelijöiden optimointi: visuaalinen palaute ensin
Tämä on yksi niistä vinkeistä, joka tuottaa suhteessa eniten hyötyä pienimmällä vaivalla. Idea on yksinkertainen: priorisoi visuaalinen palaute tapahtumankäsittelijässä. Jos napinpainallus käynnistää sekä animaation että datahakemisen, näytä ensin animaatio ja siirrä muu työ seuraavaan tehtävään.
// HUONO: Kaikki työ samassa tapahtumankäsittelijässä
button.addEventListener('click', async () => {
const data = await fetchData(); // Hidas verkkopyyntö
processData(data); // Raskas prosessointi
updateUI(data); // Visuaalinen päivitys
sendAnalytics('button_clicked'); // Analytiikka
});
// HYVÄ: Visuaalinen palaute ensin, muu työ myöhemmin
button.addEventListener('click', async () => {
// 1. Välitön visuaalinen palaute
button.classList.add('loading');
button.textContent = 'Ladataan...';
// 2. Luovuta hallinta — selain piirtää visuaalisen palautteen
await scheduler.yield();
// 3. Varsinainen työ jatkuu
const data = await fetchData();
processData(data);
updateUI(data);
// 4. Ei-kriittinen työ viimeisenä
requestIdleCallback(() => sendAnalytics('button_clicked'));
});
requestAnimationFrame ja requestIdleCallback oikeissa käyttökohteissa
Nämä kaksi rajapintaa sekoitetaan harmillisen usein keskenään, vaikka niillä on selkeästi eri käyttötarkoitukset. requestAnimationFrame (rAF) on tarkoitettu korkean prioriteetin visuaalisille päivityksille — se suoritetaan ennen seuraavaa ruudun piirtoa, noin 16,7 ms välein. requestIdleCallback (rIC) taas on matalan prioriteetin tehtäville, jotka ajetaan selaimen tyhjäkäyntiaikana.
// requestAnimationFrame — visuaaliset päivitykset
function smoothScrollUpdate(targetPosition) {
requestAnimationFrame(() => {
window.scrollTo({
top: targetPosition,
behavior: 'instant'
});
});
}
// requestIdleCallback — matalan prioriteetin taustatyö
function deferAnalytics(eventData) {
requestIdleCallback(
() => {
navigator.sendBeacon('/analytics', JSON.stringify(eventData));
},
{ timeout: 3000 } // Varmista suoritus viimeistään 3 sekunnin päästä
);
}
// Yhdistelmä: Scroll-käsittelijä, joka ei häiritse reagointikykyä
let ticking = false;
document.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(() => {
updateVisibleElements();
ticking = false;
});
ticking = true;
}
}, { passive: true });
Kolmannen osapuolen skriptien hallinta
Tässä päästään aiheeseen, joka aiheuttaa eniten harmaita hiuksia monelle kehittäjälle. Kolmannen osapuolen skriptit — analytiikka, mainokset, chat-widgetit ja sosiaalisen median upotukset — ovat usein suurin yksittäinen uhka INP-suorituskyvylle. Ne kuormittavat pääsäiettä arvaamattomasti ja voivat pilata sekä LCP- että INP-arvot.
Onneksi tehokkaita hallintakeinoja on olemassa:
- Partytown-kirjasto siirtää kolmannen osapuolen skriptit Web Workerille, jolloin ne eivät estä pääsäikeen vuorovaikutuksia.
- Facade-tekniikka korvaa raskaat widgetit (esim. YouTube-upotukset, chat-ikkunat) kevyillä paikkakuvilla, jotka lataavat varsinaisen widgetin vasta kun käyttäjä klikkaa niitä.
- Cloudflare Zaraz siirtää analytiikkaskriptien suorituksen kokonaan reunapalvelimelle, jolloin ne eivät kuormita käyttäjän selainta lainkaan. Tämä on mielestäni yksi aliarvostetuimmista ratkaisuista tällä hetkellä.
INP-ongelmien diagnosointi Long Animation Frames (LoAF) -rajapinnalla
INP kertoo että ongelma on olemassa, mutta se ei kerro miksi. Tähän tarvitaan Long Animation Frames (LoAF) -rajapintaa. LoAF tunnistaa animaatiokehykset, joiden käsittely kestää yli 50 ms, ja kertoo tarkasti, mikä skripti ja mikä funktio aiheutti hitauden.
LoAF on ollut saatavilla Chrome 123:sta lähtien, ja web-vitals-kirjaston versio 4 sisältää automaattisesti LoAF-tiedot INP-attribuutioissa. Käytännössä tämä tekee diagnosoinnista huomattavasti helpompaa kuin vielä pari vuotta sitten.
// LoAF-pohjainen INP-diagnosointi
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Tarkista vain pitkät kehykset (> 100 ms)
if (entry.duration > 100) {
console.group(`Pitkä animaatiokehys: ${entry.duration.toFixed(0)} ms`);
entry.scripts.forEach(script => {
console.log(` Skripti: ${script.sourceURL || 'tuntematon'}`);
console.log(` Funktio: ${script.sourceFunctionName || 'anonyymi'}`);
console.log(` Kesto: ${script.duration.toFixed(0)} ms`);
console.log(` Tyyppi: ${script.invokerType}`);
});
console.groupEnd();
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
Pieni vinkki: jos LoAF-raporteissa näkyvien skriptien sourceURL puuttuu, kyseessä on todennäköisesti kolmannen osapuolen cross-origin-skripti. Lisää silloin crossorigin="anonymous"-attribuutti skriptin lataustunnisteeseen, niin selain pystyy raportoimaan tarkemman attribuution.
Jatkuva seuranta ja suorituskykybudjetti
INP-optimointi ei ole sellainen juttu, jonka tekee kerran ja unohtaa. Jokainen uusi ominaisuus, päivitys tai kolmannen osapuolen skripti voi aiheuttaa regression. Olen nähnyt tämän tapahtuvan yllättävän usein — viikkojen työ menee hukkaan yhden huolimattoman skriptilisäyksen takia.
Tehokas seuranta edellyttää kolmea tasoa:
- Real User Monitoring (RUM) — Todellisten käyttäjien mittausdata paljastaa ongelmat, joita laboratoriotestaus ei havaitse. Erilaiset laitteet, verkko-olosuhteet ja sijainnit vaikuttavat kaikki INP-arvoihin.
- Google Search Consolen Core Web Vitals -raportti — Seuraa 28 päivän liukuvaa CrUX-dataa URL-ryhmittäin. Tämä on ilmainen ja helppokäyttöinen lähtökohta.
- Suorituskykybudjetti CI/CD-putkessa — Aseta hälytysrajat 80 %:iin Googlen virallisista kynnysarvoista: INP > 160 ms, LCP > 2,0 s, CLS > 0,08. Näin ehdit reagoida ennen kuin ongelmat ehtivät vaikuttaa CrUX-dataan ja hakusijoituksiin.
Usein kysytyt kysymykset
Mikä on hyvä INP-arvo vuonna 2026?
Googlen virallinen raja-arvo on 200 millisekuntia tai vähemmän 75. persentiilissä. Mutta käytännössä kannattaa tavoitella alle 160 ms — erityisesti kilpailluilla aloilla kuten verkkokaupassa ja rahoituksessa, joissa nopeammat sivustot sijoittuvat selkeästi paremmin hakutuloksissa.
Miten INP eroaa FID:stä?
FID mittasi vain ensimmäisen vuorovaikutuksen syöteviiveen. INP mittaa kaikkien vuorovaikutusten koko viiveen — syöteviiveestä prosessointiin ja esitysviiveeseen saakka. Lyhyesti: INP antaa paljon realistisemman kuvan sivuston todellisesta reagointikyvystä.
Voiko INP:tä mitata paikallisesti kehitysympäristössä?
Kyllä, mutta rajoituksin. Chrome DevToolsin Performance-paneeli näyttää yksittäisten vuorovaikutusten viiveen, mikä on hyvä lähtökohta. Todellisen INP-arvon saa kuitenkin vain kenttädatasta (CrUX), koska se edellyttää 75. persentiiliä kaikista käyttäjien vuorovaikutuksista. Total Blocking Time (TBT) toimii kohtuullisena laboratorioproksina INP:lle.
Tukevatko kaikki selaimet scheduler.yield()-rajapintaa?
Eivät vielä. Vuoden 2026 alussa scheduler.yield() on natiivisti saatavilla Chromium-pohjaisissa selaimissa (Chrome, Edge, Opera). Firefox ja Safari vaativat edelleen varatekniikan, kuten setTimeout(resolve, 0). Tarkista ajantasainen selaintuki MDN:n dokumentaatiosta.
Mikä on nopein tapa parantaa huonoa INP-arvoa?
Aloita näistä kolmesta: 1) Tunnista pahimmat pitkät tehtävät LoAF-rajapinnalla tai Chrome DevToolsilla, 2) Siirrä ei-kriittiset kolmannen osapuolen skriptit Web Workeriin tai lataa ne viiveellä, 3) Lisää välitön visuaalinen palaute tapahtumankäsittelijöihin ennen raskaampaa työtä. Omasta kokemuksesta nämä kolme toimenpidettä tuottavat tyypillisesti suurimman parannuksen pienimmällä vaivalla.