Come Trendyol ha ridotto l'INP del 50%, determinando un aumento dell'1% della percentuale di clic

Questo caso di studio descrive un flusso di lavoro passo passo per il debug e il miglioramento dell'INP in React utilizzato da Trendyol sfruttando gli strumenti Google come PageSpeed Insights (PSI), Chrome DevTools e l'API scheduler.yield.

Due componenti fondamentali di qualsiasi sito web di e-commerce sono la pagina di elenco dei prodotti (PLP) e la pagina dei dettagli del prodotto (PDP). Il traffico di e-commerce proviene spesso dalle pagine delle schede di prodotto, tramite campagne email, social media o annunci. Di conseguenza, è fondamentale assicurarsi che l'esperienza PLP sia progettata con attenzione per ridurre il tempo necessario per effettuare un acquisto. Dare la priorità alla qualità dell'esperienza utente è fondamentale per ottenere risultati. Pubblicazioni di ricerche come Milliseconds Make Millions hanno già rivelato l'impatto significativo delle prestazioni sul web sulla volontà dei consumatori di spendere denaro e interagire con i brand online.

Trendyol è una piattaforma di e-commerce con circa 30 milioni di clienti e 240.000 venditori, che ci ha permesso di diventare la prima azienda in Turchia con una valutazione di oltre 10 miliardi di dollari e una delle principali piattaforme di e-commerce al mondo.

Per raggiungere il suo obiettivo di offrire la migliore esperienza utente possibile su larga scala, mantenendo la flessibilità dei contenuti e lavorando con una versione precedente di React, Trendyol si è concentrata sull'Interaction to Next Paint (INP) come metrica chiave da migliorare. Questo case study descrive il percorso di Trendyol per migliorare l'INP sulla sua scheda di prodotto avanzata, con un risultato di una riduzione del 50% dell'INP e un aumento dell'1% della metrica aziendale dei risultati di ricerca.

Procedura di indagine di Trendyol relativa alle attività illegali online

L'INP misura l'adattabilità di un sito web all'input utente. Un buon INP indica che il browser è in grado di rispondere rapidamente e in modo affidabile a tutti gli input utente e di ridisegnare la pagina, un componente chiave di una buona esperienza utente.

Il percorso di Trendyol per migliorare l'INP nella sua PLP è iniziato con un'analisi approfondita dell'esperienza utente prima di apportare qualsiasi miglioramento. In base a un report PSI, l'esperienza utente reale del PLP ha avuto un INP di 963 millisecondi su dispositivo mobile, come mostrato nella figura seguente.

INP di Trendyol in base alla lettura di CrUX in PageSpeed Insights. L'INP di Trendyol al 5 settembre 2023 era di 963 millisecondi, rientrando nella fascia "scadente".
INP di Trendyol a partire dal 5 settembre 2023 da PSI.

Per garantire una buona reattività, i proprietari di siti dovrebbero puntare a un INP inferiore o pari a 200 millisecondi, il che significa che, in quel momento, l'INP di Trendyol rientrava nell'intervallo "scadente".

Fortunatamente, PSI fornisce sia i dati sul campo per le pagine incluse nel Report sull'esperienza utente di Chrome (CrUX) sia dati diagnostici dettagliati di laboratorio. Esaminando i dati del laboratorio, il controllo del tempo di esecuzione di JavaScript di Lighthouse ha suggerito che lo script search-result-v2 occupava il thread principale per più tempo rispetto agli altri script della pagina.

Un'analisi delle origini delle attività lunghe in Lighthouse per il sito web Trendyol. Una delle principali fonti di attività lunghe è uno script che gestisce i risultati di ricerca nella PLP di Trendyol.
Controllo del tempo di esecuzione di JavaScript di Trendyol da Lighthouse a partire dal 5 settembre 2023 da PSI.

Per identificare i colli di bottiglia reali, abbiamo utilizzato il pannello delle prestazioni in DevTools di Chrome per risolvere i problemi relativi all'esperienza PLP e identificare la causa del problema. L'emulazione delle prestazioni su dispositivo mobile con un rallentamento della CPU di 4 volte in Strumenti per sviluppatori di Chrome ha rivelato un'attività lunga 700-900 millisecondi nel thread principale. Se il thread principale è occupato da altre attività per più di 50 millisecondi, potrebbe non essere in grado di rispondere in modo tempestivo agli input dell'utente, con conseguente esperienza utente negativa.

Uno screenshot di una sessione di profilazione delle prestazioni in Chrome DevTools per il PLP di Trendyol. L'attività lunga indicata viene eseguita per 737, 6 millisecondi e fa parte di un callback di Intersection Observer.
Un profiler delle prestazioni delle attività lunghe nella PLP di Trendyol nel riquadro delle prestazioni di Chrome DevTools.

L'attività più lunga è stata causata da un callback dell'API Intersection Observer nello script dei risultati di ricerca all'interno di un componente React. A questo punto, abbiamo iniziato a esaminare la possibilità di suddividere l'attività lunga in piccoli blocchi per offrire al browser più opportunità di rispondere a attività di priorità più elevata, incluse le interazioni degli utenti.

L'utilizzo dell'operazione setState che attiva il rielaborare di React all'interno del callback dell'osservatore di intersezione ha un costo elevato, che potrebbe essere problematico per i dispositivi di fascia bassa perché occupa il thread principale per troppo tempo.

Uno dei metodi utilizzati dagli sviluppatori per suddividere le attività in altre più piccole coinvolge setTimeout. Abbiamo utilizzato questa tecnica per posticipare l'esecuzione della chiamatasetState in un'attività separata. Sebbene setTimeout consenta di posticipare l'esecuzione di JavaScript, non fornisce alcun controllo sulla priorità. Per questo motivo, abbiamo deciso di partecipare alla prova dell'origine scheduler.yield per garantire la continuità dell'esecuzione dello script dopo il passaggio al thread principale:

/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
  if('scheduler' in window && 'yield' in scheduler) {
    return await scheduler.yield();
  }

  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
  entries.forEach(handleIntersection);
  const maxNumberOfEntries = Math.max(...this.intersectingEntries);

  if (Number.isFinite(maxNumberOfEntries)) {
    await this.yieldToMain();

    this.setState({ count: maxNumberOfEntries });
  }
}, { threshold: 0.5 });

L'aggiunta di questo metodo di rendimento al codice PLP ha migliorato l'INP, poiché la tâche principale lunga è stata suddivisa in una serie di attività più piccole, il che consente di eseguire attività con priorità più elevata, come le interazioni utente e il successivo rendering, prima di quanto non avverrebbe altrimenti.

Uno screenshot di una sessione di profilazione delle prestazioni in Chrome DevTools per il PLP di Trendyol. L'attività lunga che in precedenza veniva eseguita per 737,6 millisecondi ora è suddivisa in più attività più piccole.
Le attività sono suddivise in attività più piccole.

Tieni presente che Trendyol utilizza il framework PuzzleJs per implementare un'architettura di micro-frontend utilizzando React v16.9.0. Con React 18, si potrebbe ottenere lo stesso rendimento, ma per una serie di motivi, al momento Trendyol non è in grado di eseguire l'upgrade.

Risultati aziendali

Per misurare l'impatto del miglioramento dell'INP implementato, abbiamo eseguito un test A/B per vedere in che modo le metriche aziendali sono state interessate. Nel complesso, le modifiche apportate alla scheda del prodotto hanno avuto un miglioramento significativo, inclusa una riduzione del 50% dell'INP e un aumento dell'1% delle percentuali di clic dalla pagina delle schede alla pagina dei dettagli del prodotto per sessione utente. Nella figura seguente puoi vedere come l'INP è migliorato nel tempo rispetto al PLP:

Uno screenshot dell'INP del 75° percentile di Trendyol nel corso di sei mesi. Entro la fine dei sei mesi, l'INP di Trendyol è sceso a circa 650 millisecondi da quasi 1400 millisecondi.
Miglioramenti del 75° percentile INP nel tempo.

Conclusione

L'ottimizzazione dell'INP è un processo complesso e iterativo, ma può essere semplificata con un flusso di lavoro chiaro. Un approccio semplice per il debug e il miglioramento dell'INP del tuo sito web dipende dal fatto che tu stia raccogliendo i tuoi dati sul campo. Se non lo hai ancora fatto, PSI e Lighthouse sono un buon punto di partenza. Una volta identificate le pagine con problemi, puoi utilizzare DevTools per approfondire e tentare di riprodurli.

Rinunciare di volta in volta al thread principale per offrire al browser più opportunità di svolgere attività urgenti renderà il tuo sito web più reattivo, garantendo ai clienti un'esperienza utente migliore. Le API di pianificazione più recenti come scheduler.yield() semplificano questa operazione.

Un ringraziamento speciale a Jeremy Wagner, Barry Pollard e Houssein Djirdeh di Google e al team di ingegneria di Trendyol per il loro contributo a questo lavoro.