Βελτιστοποίηση INP: Ο Πλήρης Οδηγός για Ταχύτερες Ιστοσελίδες το 2026

Οδηγός βελτιστοποίησης INP — ο δείκτης Core Web Vitals που αποτυγχάνει το 43% των ιστοσελίδων. Μάθετε πώς να σπάσετε long tasks, να χρησιμοποιήσετε scheduler.yield() και να πετύχετε INP κάτω από 200ms με πρακτικά παραδείγματα κώδικα.

Γιατί το INP Είναι ο Πιο Κρίσιμος Δείκτης Web Performance το 2026

Ας ξεκινήσουμε με ένα νούμερο που μιλάει μόνο του: το 43% των ιστοσελίδων αποτυγχάνει στο όριο INP των 200ms. Αυτό κάνει το Interaction to Next Paint τον πιο συχνά αποτυχημένο δείκτη Core Web Vitals το 2026. Αν η σελίδα σας φαίνεται γρήγορη στο φόρτωμα αλλά νιώθει αργή στη χρήση, το πρόβλημα σχεδόν σίγουρα κρύβεται στο INP.

Το INP αντικατέστησε επίσημα το First Input Delay (FID) τον Μάρτιο 2024 ως Core Web Vital — και αποτελεί πλέον σήμα κατάταξης της Google. Η διαφορά μεταξύ τους; Τεράστια. Ενώ το FID μετρούσε μόνο την καθυστέρηση της πρώτης αλληλεπίδρασης, το INP αξιολογεί κάθε αλληλεπίδραση κατά τη διάρκεια της επίσκεψης — κλικ, αγγίγματα, πληκτρολόγηση — και αναφέρει τη χειρότερη. Δεν μπορείτε πια να κρύψετε αργές αλληλεπιδράσεις πίσω από ένα γρήγορο πρώτο κλικ.

Στον προηγούμενο οδηγό μας καλύψαμε τη βελτιστοποίηση εικόνων για LCP και CLS, και σε ξεχωριστό άρθρο τη μείωση TTFB. Σήμερα κλείνουμε τον κύκλο με τον τρίτο — και ειλικρινά πιο απαιτητικό — πυλώνα των Core Web Vitals.

Τι Ακριβώς Μετρά το INP: Οι Τρεις Φάσεις

Για να βελτιστοποιήσετε αποτελεσματικά το INP, πρέπει πρώτα να καταλάβετε τι ακριβώς μετρά. Κάθε αλληλεπίδραση αποτελείται από τρεις φάσεις, και η καθυστέρηση μπορεί να κρύβεται σε οποιαδήποτε από αυτές.

1. Input Delay — Ο Χρόνος Αναμονής

Αυτή είναι η περίοδος μεταξύ της στιγμής που ο χρήστης κάνει κλικ και της στιγμής που ο browser αρχίζει να εκτελεί τον event handler. Αν το main thread είναι απασχολημένο με κάποιο long task, ο χρήστης απλά... περιμένει.

Τα δεδομένα εδώ είναι αποκαλυπτικά: αλληλεπιδράσεις κατά τη φάση φόρτωσης έχουν p75 INP 132ms, ενώ μετά την ολοκλήρωση φόρτωσης πέφτει στα 50ms. Διαφορά 2.6x — δηλαδή η σελίδα σας είναι πολύ πιο αργή ακριβώς τη στιγμή που ο χρήστης αρχίζει να αλληλεπιδρά.

2. Processing Time — Η Εκτέλεση του Κώδικα

Ο χρόνος εκτέλεσης των event handlers σε JavaScript. Κάθε millisecond μέσα στον click handler σας προστίθεται κατευθείαν στο INP. Εδώ κρύβονται συνήθως τα μεγαλύτερα bottlenecks: βαριά DOM manipulation, σύνθετοι υπολογισμοί, και κώδικας που δεν χρειαζόταν καν να τρέξει εκείνη τη στιγμή (analytics, third-party callbacks).

3. Presentation Delay — Η Απόδοση στην Οθόνη

Αφού ολοκληρωθεί ο event handler, ο browser πρέπει να κάνει recalculate styles, layout και paint. Μεγάλο DOM, σύνθετα CSS selectors και layout thrashing μπορούν να κάνουν αυτή τη φάση πραγματικά βαριά.

Κατώφλια Αξιολόγησης: Τι Σημαίνει «Καλό» INP

Η Google ορίζει τρία επίπεδα, μετρημένα στην 75η εκατοστιαία μοίρα (p75) πραγματικών χρηστών:

  • Καλό (Good): κάτω από 200ms — η σελίδα ανταποκρίνεται άμεσα
  • Χρειάζεται βελτίωση: 200ms έως 500ms — αισθητή καθυστέρηση
  • Κακό (Poor): πάνω από 500ms — η σελίδα νιώθει «κολλημένη»

Ένα στοιχείο που πολλοί παραβλέπουν: η κινητή συσκευή έχει p75 INP 131ms, ενώ το desktop μόλις 48ms. Αυτή η διαφορά 2.8x σημαίνει ότι αν βελτιστοποιείτε μόνο σε desktop, πιθανότατα χάνετε εντελώς το πρόβλημα.

Πώς να Μετρήσετε το INP Σωστά

Field Data: Η Μόνη Αξιόπιστη Μέτρηση

Εδώ πρέπει να γίνω σαφής: το INP δεν μετρείται στο εργαστήριο. Το Lighthouse δεν μπορεί να το μετρήσει γιατί χρειάζεται πραγματικές αλληλεπιδράσεις χρηστών. Αυτό που μπορείτε να χρησιμοποιήσετε ως proxy είναι το Total Blocking Time (TBT), που συσχετίζεται αρκετά καλά — αλλά δεν αντικαθιστά πραγματικά field data.

Για πραγματικά δεδομένα INP, αυτά είναι τα εργαλεία σας:

  • PageSpeed Insights — εμφανίζει τα CrUX (Chrome User Experience Report) field data
  • Google Search Console — αναφορά Core Web Vitals σε επίπεδο URL
  • CrUX Dashboard — λεπτομερή ιστορικά δεδομένα μέσω Looker Studio

Η Βιβλιοθήκη web-vitals για Custom Tracking

Αν θέλετε ακριβή παρακολούθηση στο δικό σας analytics σύστημα, η βιβλιοθήκη web-vitals είναι ο πιο αξιόπιστος τρόπος:

import { onINP } from 'web-vitals';

onINP((metric) => {
  console.log('INP value:', metric.value);
  console.log('INP rating:', metric.rating); // "good", "needs-improvement", "poor"

  // Στείλτε στο analytics σύστημά σας
  sendToAnalytics({
    name: metric.name,
    value: metric.value,
    id: metric.id,
    attribution: metric.attribution
  });
});

Long Animation Frames (LoAF) API

Αυτό είναι ένα σχετικά νέο browser API που μπορεί να σας γλιτώσει ώρες debugging. Το LoAF σας δείχνει ακριβώς ποια scripts και ποιες functions συνεισφέρουν σε κακό INP:

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > 50) {
      console.log('Long Animation Frame:', {
        duration: entry.duration,
        blockingDuration: entry.blockingDuration,
        scripts: entry.scripts.map(s => ({
          sourceURL: s.sourceURL,
          sourceFunctionName: s.sourceFunctionName,
          duration: s.duration
        }))
      });
    }
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });

Ομολογώ ότι αυτό το API μου έχει λύσει τα χέρια σε αρκετές περιπτώσεις — αντί να μαντεύετε ποιο script φταίει, βλέπετε κατευθείαν τον ένοχο.

Σπάστε τα Long Tasks: Η Πιο Αποτελεσματική Τεχνική

Tasks JavaScript μεγαλύτερα από 50ms θεωρούνται «long tasks» και μπλοκάρουν το main thread. Αυτή είναι, στις περισσότερες περιπτώσεις, η κύρια αιτία κακού INP.

scheduler.yield(): Το Νέο Εργαλείο του Browser

Λοιπόν, ας μιλήσουμε για το scheduler.yield() — ίσως η πιο σημαντική προσθήκη για βελτιστοποίηση INP τα τελευταία χρόνια. Επιτρέπει στη JavaScript να «παραχωρήσει» ρητά τον έλεγχο στο main thread, δίνοντας στον browser ευκαιρία να ανταποκριθεί σε εκκρεμείς αλληλεπιδράσεις:

async function processLargeDataset(items) {
  for (const item of items) {
    processItem(item);
    // Παραχωρούμε τον έλεγχο στον browser κάθε iteration
    await scheduler.yield();
  }
}

// Παράδειγμα: μεγάλη λίστα αποτελεσμάτων
async function renderSearchResults(results) {
  const container = document.getElementById('results');

  for (const result of results) {
    const element = createResultElement(result);
    container.appendChild(element);
    await scheduler.yield(); // Ο browser μπορεί να ανταποκριθεί σε input
  }
}

Και εδώ είναι το κομβικό σημείο: σε αντίθεση με το setTimeout(0), η συνέχεια του κώδικα έχει προτεραιότητα. Δηλαδή αν παραχωρήσετε τον έλεγχο στη μέση ενός task, ο κώδικάς σας θα τρέξει πριν από tasks τρίτων. Αυτό αποτρέπει παρεμβολές από third-party scripts — κάτι που το setTimeout δεν εγγυάται.

Batching με shouldYield() για Βέλτιστη Απόδοση

Μικρή λεπτομέρεια που κάνει μεγάλη διαφορά: αν τα items σας επεξεργάζονται σε microseconds, το yielding σε κάθε iteration δημιουργεί περιττό overhead. Η λύση είναι απλή — παραχωρείτε τον έλεγχο μόνο όταν έχει περάσει αρκετός χρόνος:

const BATCH_DURATION = 50; // ms - ταιριάζει με το όριο long task
let lastYieldTime = performance.now();

function shouldYield() {
  const now = performance.now();
  if (now - lastYieldTime > BATCH_DURATION) {
    lastYieldTime = now;
    return true;
  }
  return false;
}

async function processItems(items) {
  for (const item of items) {
    processItem(item);

    if (shouldYield()) {
      await scheduler.yield();
    }
  }
}

Τα 50ms είναι ένα καλό σημείο εκκίνησης. Αρκετά μικρό ώστε οι αλληλεπιδράσεις να μην καθυστερούν αισθητά, αρκετά μεγάλο ώστε το overhead να είναι αμελητέο.

Fallback για Browsers Χωρίς scheduler.yield()

Δεδομένου ότι δεν το υποστηρίζουν ακόμα όλοι οι browsers, χρειάζεστε ένα fallback. Η παρακάτω helper function καλύπτει και τις δύο περιπτώσεις:

// Polyfill για scheduler.yield
function yieldToMain() {
  if (globalThis.scheduler?.yield) {
    return scheduler.yield();
  }
  // Fallback: setTimeout wraps σε Promise
  return new Promise((resolve) => setTimeout(resolve, 0));
}

// Χρήση
async function heavyOperation() {
  doPartOne();
  await yieldToMain();
  doPartTwo();
  await yieldToMain();
  doPartThree();
}

Εναλλακτικά, υπάρχει και το πακέτο scheduler-polyfill αν θέλετε πλήρη υποστήριξη χωρίς custom κώδικα.

Βελτιστοποίηση Event Handlers

Διαχωρισμός Κρίσιμου και Μη Κρίσιμου Κώδικα

Αυτό το μοτίβο το βλέπω συνεχώς: ο event handler κάνει τα πάντα μαζί — ενημερώνει το UI, στέλνει analytics, τρέχει validations, ενημερώνει state. Ο χρήστης περιμένει να δει αλλαγή στην οθόνη, αλλά ο browser έχει κολλήσει στέλνοντας analytics. Η λύση είναι να διαχωρίσετε τον κρίσιμο κώδικα από τον μη κρίσιμο:

// ❌ Κακό: όλα μαζί στον event handler
button.addEventListener('click', () => {
  updateUI();           // Κρίσιμο — ο χρήστης περιμένει να δει αλλαγή
  sendAnalytics();      // Μη κρίσιμο
  syncWithServer();     // Μη κρίσιμο
  updateRecommendations(); // Μη κρίσιμο
});

// ✅ Καλό: κρίσιμος κώδικας πρώτα, τα υπόλοιπα deferred
button.addEventListener('click', () => {
  updateUI(); // Μόνο η οπτική ενημέρωση

  // Τα υπόλοιπα τρέχουν μετά το next paint
  requestAnimationFrame(() => {
    setTimeout(() => {
      sendAnalytics();
      syncWithServer();
      updateRecommendations();
    }, 0);
  });
});

Αυτό το pattern — requestAnimationFrame + setTimeout — εξασφαλίζει ότι ο μη κρίσιμος κώδικας εκτελείται μετά το επόμενο paint. Η διαφορά στο perceived performance είναι εντυπωσιακή.

Debounce και Throttle για Επαναλαμβανόμενα Events

Events όπως scroll, resize, input και mousemove πυροδοτούνται δεκάδες φορές το δευτερόλεπτο. Χωρίς κάποιον περιορισμό, κάθε event φορτώνει το main thread ασταμάτητα:

// Throttle: εκτελεί μέγιστο μία φορά ανά interval
function throttle(fn, delay) {
  let lastCall = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastCall >= delay) {
      lastCall = now;
      fn(...args);
    }
  };
}

// Χρήση σε scroll event
window.addEventListener('scroll', throttle(() => {
  updateScrollIndicator();
}, 100));

// Debounce: εκτελεί μόνο μετά από παύση
function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// Χρήση σε search input
searchInput.addEventListener('input', debounce((e) => {
  performSearch(e.target.value);
}, 300));

Μείωση Presentation Delay: DOM και Rendering

CSS Containment: Περιορίστε τον Αντίκτυπο των Αλλαγών

Κάθε φορά που αλλάζετε ένα στοιχείο στη σελίδα, ο browser μπορεί να χρειαστεί να υπολογίσει εκ νέου styles και layout σε ολόκληρο το DOM tree. Η ιδιότητα CSS contain λέει στον browser «ό,τι αλλάζει εδώ μέσα, μένει εδώ μέσα»:

/* Ο browser γνωρίζει ότι αλλαγές μέσα σε αυτό
   το element δεν επηρεάζουν τίποτα έξω από αυτό */
.card-container {
  contain: layout style paint;
}

/* content-visibility: auto — ο browser δεν κάνει render
   τα off-screen elements μέχρι να χρειαστούν */
.long-list-item {
  content-visibility: auto;
  contain-intrinsic-size: 0 80px; /* Εκτιμώμενο ύψος */
}

Ειδικά το content-visibility: auto κάνει θαύματα σε μεγάλες λίστες: ο browser παραλείπει εντελώς το rendering των items που δεν φαίνονται στην οθόνη. Σε σελίδες με εκατοντάδες items, η μείωση στον χρόνο paint είναι δραματική.

Αποφυγή Layout Thrashing

Ο όρος «layout thrashing» περιγράφει κάτι που μοιάζει αθώο αλλά δεν είναι καθόλου: η JavaScript εναλλάσσεται μεταξύ ανάγνωσης layout properties και εγγραφής styles, αναγκάζοντας τον browser σε συνεχείς επανυπολογισμούς:

// ❌ Layout thrashing — προκαλεί forced reflows
function resizeElements(elements) {
  elements.forEach(el => {
    const height = el.offsetHeight; // ΑΝΑΓΝΩΣΗ → forces layout
    el.style.height = (height * 2) + 'px'; // ΕΓΓΡΑΦΗ → invalidates layout
  });
}

// ✅ Batch reads πρώτα, μετά batch writes
function resizeElements(elements) {
  // Φάση 1: Διαβάζουμε όλα τα μεγέθη
  const heights = elements.map(el => el.offsetHeight);

  // Φάση 2: Εφαρμόζουμε τις αλλαγές
  elements.forEach((el, i) => {
    el.style.height = (heights[i] * 2) + 'px';
  });
}

Μέγεθος DOM: Μικρότερο = Ταχύτερο

Κάθε DOM node κοστίζει — σε μνήμη, σε χρόνο recalculation, σε χρόνο painting. Σελίδες με χιλιάδες nodes (πάνω από 1.400 θεωρείται ήδη υπερβολικό) δυσκολεύονται σοβαρά να πετύχουν καλό INP.

Πρακτικές λύσεις που λειτουργούν:

  • Virtualized lists — αντί να κάνετε render 10.000 rows, κάντε render μόνο τα ορατά (react-window, tanstack-virtual κλπ.)
  • Lazy rendering components — φορτώστε τμήματα του DOM μόνο όταν χρειάζονται
  • Αποφύγετε υπερβολικά nested wrappers — κάθε page builder (Elementor, Divi, κ.α.) προσθέτει layers από wrapper divs που σπάνια χρειάζονται

Framework-Specific Τεχνικές Βελτιστοποίησης INP

React: Concurrent Features και Αποτροπή Περιττών Re-renders

Αν δουλεύετε με React 18+, έχετε ισχυρά εργαλεία στη διάθεσή σας. Το κλειδί είναι να ξεχωρίσετε τις urgent ενημερώσεις (π.χ. input value) από τις non-urgent (π.χ. φιλτράρισμα λίστας):

import { useState, useTransition, useDeferredValue, memo } from 'react';

function SearchPage() {
  const [query, setQuery] = useState('');
  const [isPending, startTransition] = useTransition();

  function handleChange(e) {
    const value = e.target.value;

    // Το input ενημερώνεται αμέσως (υψηλή προτεραιότητα)
    setQuery(value);

    // Τα αποτελέσματα ενημερώνονται σε χαμηλή προτεραιότητα
    startTransition(() => {
      setSearchResults(filterResults(value));
    });
  }

  return (
    <div>
      <input value={query} onChange={handleChange} />
      {isPending ? <Spinner /> : <ResultsList />}
    </div>
  );
}

// useDeferredValue: αναβάλλει ακριβούς υπολογισμούς
function ProductList({ products }) {
  const deferredProducts = useDeferredValue(products);

  return (
    <ul>
      {deferredProducts.map(p => (
        <ProductCard key={p.id} product={p} />
      ))}
    </ul>
  );
}

// memo: αποτρέπει re-renders χωρίς αλλαγή props
const ProductCard = memo(function ProductCard({ product }) {
  return <li>{product.name} - {product.price}€</li>;
});

Vue: v-memo και Async Components

Στο Vue, τα πράγματα είναι λίγο πιο straightforward — αλλά υπάρχουν κρυμμένες βελτιστοποιήσεις που πολλοί δεν χρησιμοποιούν:

<!-- v-memo: skip re-render αν δεν αλλάξει η dependency -->
<div v-for="item in list" :key="item.id" v-memo="[item.updated]">
  {{ item.name }}
</div>

<!-- Async component: φορτώνεται μόνο όταν χρειαστεί -->
<script setup>
import { defineAsyncComponent } from 'vue';

const HeavyChart = defineAsyncComponent(() =>
  import('./HeavyChart.vue')
);
</script>

Angular: OnPush, trackBy και @defer

Στο Angular, η default στρατηγική change detection ελέγχει τα πάντα σε κάθε κύκλο. Αν δεν χρησιμοποιείτε OnPush, πιθανότατα κάνετε πολύ περισσότερη δουλειά από όσο χρειάζεται:

// OnPush: το component ενημερώνεται μόνο με αλλαγή input reference
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <ul>
      <li *ngFor="let item of items; trackBy: trackById">
        {{ item.name }}
      </li>
    </ul>

    <!-- @defer: lazy load component -->
    @defer (on viewport) {
      <heavy-component />
    } @placeholder {
      <p>Φόρτωση...</p>
    }
  `
})
export class ItemListComponent {
  trackById(index: number, item: Item) {
    return item.id;
  }
}

Third-Party Scripts: Ο Κρυφός Εχθρός του INP

Δεν φταίει πάντα ο δικός σας κώδικας. Τα third-party scripts — analytics, chat widgets, ad networks, social embeds — τρέχουν στο main thread και μπλοκάρουν τις αλληλεπιδράσεις σας. Το Google Tag Manager μόνο του μπορεί να φορτώνει δεκάδες tags, το καθένα με τη δική του JavaScript. Αν αναρωτιέστε γιατί το INP σας είναι κακό ενώ ο κώδικάς σας φαίνεται καθαρός, κοιτάξτε εδώ πρώτα.

Facade Pattern: Αντικαταστήστε Βαριά Widgets με Ελαφριά Placeholders

Η ιδέα είναι απλή: αντί να φορτώνετε ένα βαρύ widget κατευθείαν, δείχνετε ένα ελαφρύ placeholder και φορτώνετε το πραγματικό μόνο όταν ο χρήστης αλληλεπιδράσει.

<!-- Αντί να φορτώνετε ολόκληρο το YouTube player -->
<lite-youtube videoid="dQw4w9WgXcQ"></lite-youtube>

<!-- Αντί να φορτώνετε ολόκληρο το chat widget -->
<button id="chat-trigger" aria-label="Ξεκινήστε συζήτηση">
  💬 Χρειάζεστε βοήθεια;
</button>

<script>
document.getElementById('chat-trigger').addEventListener('click', () => {
  // Φόρτωση του πραγματικού widget μόνο στο κλικ
  import('./loadChatWidget.js').then(m => m.init());
}, { once: true });
</script>

Web Workers για Βαρύ Processing

Αν έχετε υπολογισμούς που δεν χρειάζονται DOM access (data processing, sorting, filtering μεγάλων datasets), μεταφέρτε τους σε Web Worker. Το main thread ελευθερώνεται αμέσως:

// main.js
const worker = new Worker('data-processor.js');

button.addEventListener('click', () => {
  // Δείξτε αμέσως loading state
  showSpinner();

  // Ο βαρύς υπολογισμός γίνεται εκτός main thread
  worker.postMessage({ type: 'process', data: largeDataset });
});

worker.onmessage = (event) => {
  hideSpinner();
  displayResults(event.data);
};

// data-processor.js (Web Worker)
self.onmessage = (event) => {
  if (event.data.type === 'process') {
    const result = heavyComputation(event.data.data);
    self.postMessage(result);
  }
};

Πρακτικό Checklist Βελτιστοποίησης INP

Αν αποτυγχάνετε στο INP, ακολουθήστε αυτή τη σειρά — τα πρώτα βήματα συνήθως αρκούν για να δείτε σημαντική βελτίωση:

  1. Ελέγξτε τα third-party scripts — Υψηλότερος αντίκτυπος, χαμηλότερη προσπάθεια. Αφαιρέστε ή φορτώστε lazy ό,τι δεν χρειάζεται αμέσως
  2. Lazy load μη κρίσιμα features — Chat widgets, feedback tools, βαριά embeds
  3. Βελτιστοποιήστε event handlers — Κάντε profiling και βελτιώστε τις πιο αργές αλληλεπιδράσεις
  4. Μειώστε τo JavaScript payload — Code splitting, tree shaking, dynamic imports
  5. Βελτιώστε rendering performance — CSS containment, virtualized lists, μικρότερο DOM
  6. Χρησιμοποιήστε scheduler.yield() — Σπάστε τα long tasks στους πιο βαρείς κώδικες

Και ένα πραγματικό παράδειγμα για να πειστείτε: η RedBus βελτιστοποίησε το INP και είδε αύξηση 7% στις πωλήσεις. Ένα e-commerce site μείωσε το INP από 450ms σε 180ms, με αποτέλεσμα αύξηση 34% στο organic traffic μέσα σε 6 εβδομάδες. Τα νούμερα μιλάνε μόνα τους.

Συχνές Ερωτήσεις (FAQ)

Ποια η διαφορά μεταξύ INP και FID;

Το FID μετρούσε μόνο την καθυστέρηση πριν ξεκινήσει ο event handler της πρώτης αλληλεπίδρασης. Το INP μετρά ολόκληρη τη διάρκεια (input delay + processing + presentation) για κάθε αλληλεπίδραση και αναφέρει τη χειρότερη. Είναι πολύ πιο αυστηρός δείκτης — γι' αυτό και το 43% των sites αποτυγχάνει ενώ με το FID τα πήγαιναν μια χαρά.

Μπορώ να μετρήσω το INP στο Lighthouse;

Όχι άμεσα. Το INP χρειάζεται πραγματικές αλληλεπιδράσεις χρηστών, κάτι που το Lighthouse δεν μπορεί να προσομοιώσει. Ο δείκτης Total Blocking Time (TBT) αποτελεί αρκετά καλό proxy — τα long tasks που αυξάνουν το TBT αυξάνουν και το input delay του INP. Για πραγματικά δεδομένα, χρησιμοποιήστε PageSpeed Insights ή CrUX.

Πόσο χρόνο χρειάζεται για να φανούν βελτιώσεις INP στο Search Console;

Τα δεδομένα βασίζονται στις τελευταίες 28 ημέρες πραγματικών χρηστών. Μετά τη δημοσίευση βελτιώσεων, αναμένετε 2-4 εβδομάδες ώστε η αλλαγή να αντικατοπτριστεί πλήρως. Κάντε υπομονή — τα αποτελέσματα έρχονται, απλά όχι αμέσως.

Γιατί το INP είναι χειρότερο στο κινητό;

Πιο αργοί επεξεργαστές, λιγότερη μνήμη, υψηλότερο network latency. Τα δεδομένα δείχνουν p75 INP 131ms σε κινητό έναντι 48ms σε desktop — σχεδόν 3x χειρότερο. Πάντα βελτιστοποιείτε πρώτα για κινητές συσκευές, αλλιώς βελτιστοποιείτε για λάθος κοινό.

Τα third-party scripts μπορούν να χαλάσουν το INP ακόμα κι αν ο χρήστης δεν αλληλεπιδρά μαζί τους;

Ναι, απολύτως. Third-party scripts που τρέχουν στο main thread μπλοκάρουν όλες τις αλληλεπιδράσεις, ανεξαρτήτως πηγής. Αν ένα analytics script εκτελεί long task τη στιγμή που ο χρήστης κάνει κλικ σε ένα κουμπί, η αλληλεπίδραση καθυστερεί μέχρι να τελειώσει το script. Γι' αυτό η αφαίρεση ή η lazy φόρτωση third-party scripts είναι συχνά η πρώτη και πιο αποτελεσματική κίνηση.

Σχετικά με τον Συγγραφέα Editorial Team

Our team of expert writers and editors.