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

Questo case study descrive un flusso di lavoro dettagliato per il debug e il miglioramento di INP in React utilizzato da Trendyol sfruttando 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 della scheda di prodotto e la pagina dei dettagli del prodotto. Il traffico e-commerce proviene spesso da pagine con schede di prodotto, tramite campagne email, social media o pubblicità. Di conseguenza, è fondamentale assicurarsi che l'esperienza PLP sia progettata con cura in modo da ridurre il tempo necessario per effettuare un acquisto. Dare la priorità alla qualità dell'esperienza utente è essenziale per ottenere risultati ottimali. Pubblicazioni di ricerca come Milliseconds Make Millions hanno già rivelato il significativo impatto del rendimento sul web sulla propensione dei consumatori a spendere denaro e a interagire con i brand online.

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

Per raggiungere l'obiettivo di fornire la migliore esperienza utente possibile su larga scala, mantenendo al contempo la flessibilità dei contenuti e lavorando con una versione precedente di React, Trendyol si è concentrata su Interaction to Next Paint (INP) come metrica chiave per migliorarla. Questo case study descrive il percorso di Trendyol per migliorare l'INP nella sua piattaforma PPP, generando una riduzione del 50% dell'INP e un aumento dell'1% della metrica aziendale dei risultati di ricerca.

Processo di indagine INP di Trendyol

L'INP misura l'adattabilità di un sito web all'input degli utenti. Un INP valido indica che il browser è in grado di rispondere in modo rapido e affidabile a tutti gli input dell'utente e di ridipingere la pagina, il che è un componente fondamentale di una buona esperienza utente.

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

L'INP di Trendyol in base alla lettura CrUX in PageSpeed Insights. L'INP di Trendyol al 5 settembre 2023 era di 963 millisecondi, che rientra nella fascia "scarsa".
INP di Trendyol dal 5 settembre 2023 da PSI.

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

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

Una lettura delle fonti di attività lunghe in Lighthouse per il sito web di Trendyol. Una delle principali fonti di attività lunghe è uno script che gestisce i risultati di ricerca sul PLP di Trendyol.
Controllo del tempo di esecuzione JavaScript di Trendyol da Lighthouse del 5 settembre 2023 da PSI.

Per identificare i colli di bottiglia nel mondo reale, abbiamo utilizzato il riquadro delle prestazioni in Chrome DevTools per risolvere i problemi relativi all'esperienza PLP e identificare l'origine del problema. L'emulazione delle prestazioni su dispositivi mobili con un rallentamento della CPU 4 volte maggiore in Chrome DevTools ha rivelato un'attività di 700-900 millisecondi sul thread principale. Se il thread principale è occupato da altre attività per oltre 50 millisecondi, potrebbe non essere in grado di rispondere in modo tempestivo all'input utente, causando un'esperienza utente scadente.

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

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

Ho scoperto che l'utilizzo dell'operazione setState che attiva il rendering di React all'interno del callback di Intersection Observationr ha un costo elevato, il che potrebbe essere problematico per i dispositivi di fascia bassa a causa di un utilizzo troppo lungo del thread principale.

Un metodo usato dagli sviluppatori per suddividere le attività in attività più piccole è setTimeout. Abbiamo utilizzato questa tecnica per posticipare l'esecuzione della chiamata setState in un'attività separata. Sebbene setTimeout consenta di posticipare l'esecuzione di JavaScript, non fornisce alcun controllo sulla priorità. Questo ci ha portato a partecipare alla prova dell'origine scheduler.yield nel tentativo di garantire il proseguimento dell'esecuzione del nostro script dopo aver ceduto 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é l'attività lunga principale è stata suddivisa in una serie di attività più piccole, consentendo un lavoro con priorità più elevata, come le interazioni degli utenti e il successivo lavoro di rendering, prima di quanto sarebbe altrimenti.

Uno screenshot di una sessione di profilazione delle prestazioni in Chrome DevTools per il PLP di Trendyol. L'attività lunga che prima era in esecuzione da 737,6 millisecondi è ora suddivisa in diverse attività più piccole.
Attività suddivisa 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, è possibile ottenere le stesse prestazioni, ma per una serie di motivi, Trendyol non può eseguire l'upgrade in questo momento.

Risultati aziendali

Per misurare l'impatto del miglioramento INP implementato, abbiamo eseguito un test A/B per vedere l'impatto sulle metriche aziendali. Nel complesso, le nostre modifiche al PLP hanno portato a un miglioramento significativo, tra cui 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 che segue puoi vedere come INP è migliorato nel PLP nel corso del tempo:

Uno screenshot del 75° percentile INP di Trendyol in sei mesi. Alla fine dei sei mesi, l'INP di Trendyol è sceso a quasi 650 millisecondi da quasi 1.400 millisecondi.
Miglioramenti INP del 75° percentile nel tempo.

Conclusione

L'ottimizzazione dell'INP è un processo complesso e iterativo, ma può essere reso più semplice con un flusso di lavoro chiaro. Un approccio semplice al debug e al miglioramento dell'INP del tuo sito web dipende dalla raccolta o meno dei dati dei campi. In caso contrario, PSI e Lighthouse sono un buon punto di partenza. Una volta identificate le pagine che presentano problemi, puoi utilizzare DevTools per analizzare più a fondo e tentare di riprodurre i problemi.

Rilanciare di tanto in tanto nel thread principale per offrire al browser più opportunità di svolgere operazioni urgenti renderà il sito più reattivo, garantendo così che i clienti abbiano un'esperienza utente migliore. Le API di pianificazione più recenti come scheduler.yield() semplificano questa attività.

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