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 e-commerce spesso proviene dalle pagine con schede di prodotto, attraverso campagne email, social media o pubblicità. 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 è essenziale per ottenere risultati. Pubblicazioni di ricerca come Milliseconds Make Millions hanno già rivelato l'impatto significativo del rendimento sul web sulla disponibilità 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, 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 locale, con un risultato di 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 utente. Un buon INP indica che il browser è in grado di rispondere rapidamente e in modo affidabile a tutti gli input degli utenti 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 successiva.

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 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 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 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 la PLP di Trendyol. L'attività lunga rappresentata viene eseguita per 737, 6 millisecondi e fa parte di un callback 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 sullo 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.

È emerso che 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 il differimento dell'esecuzione di JavaScript, non fornisce alcun controllo sulla priorità. Questo ci ha portato a partecipare alla prova dell'origine di scheduler.yield per garantire il proseguimento dell'esecuzione del nostro 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.
Attività suddivisa in più piccole.

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

Risultati aziendali

Per misurare l'impatto del miglioramento INP implementato, abbiamo eseguito un test A/B per capire l'impatto sulle metriche aziendali. 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 INP è migliorato nella PLP nel tempo:

Uno screenshot dell'INP del 75° percentile di Trendyol in un periodo di sei mesi. Entro la fine dei sei mesi, l'INP di Trendyol è sceso a circa 650 millisecondi da quasi 1400 millisecondi.
Miglioramenti INP al 75° percentile 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 al debug e al miglioramento dell'INP del tuo sito web dipende dal fatto che tu stia raccogliendo o meno i tuoi dati sul campo. Se non lo hai ancora fatto, PSI e Lighthouse sono un buon punto di partenza. Dopo aver identificato le pagine con problemi, puoi utilizzare DevTools per cercare di scavare più a fondo e cercare di riprodurre i problemi.

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 tecnico di Trendyol per il loro contributo a questo progetto.