이 케이스 스터디에서는 PageSpeed Insights(PSI), Chrome DevTools, scheduler.yield
API와 같은 Google 도구를 활용하여 Trendyol에서 사용하는 React의 INP를 디버그하고 개선하는 단계별 워크플로를 설명합니다.
전자상거래 웹사이트의 두 가지 중요한 구성요소는 제품 등록정보 페이지(PLP)와 제품 세부정보 페이지 (PDP)입니다. 전자상거래 트래픽은 이메일 캠페인, 소셜 미디어 또는 광고를 통해 제품 등록정보 페이지에서 발생하는 경우가 많습니다. 따라서 PLP 환경을 구매하는 데 걸리는 시간을 줄일 수 있도록 신중하게 설계하는 것이 중요합니다. 성공을 거두려면 사용자 환경 품질을 최우선으로 해야 합니다. Milliseconds Make Millions과 같은 연구 보고서에서는 이미 웹 성능이 소비자의 지출 의도와 온라인에서 브랜드와의 참여도에 미치는 상당한 영향을 밝혀냈습니다.
Trendyol은 약 3,000만 명의 고객과 240, 000명의 판매자를 보유한 전자상거래 플랫폼으로, 가치를 100억 달러가 넘는 튀르키예 최초의 비즈니스이자 세계 최고의 전자상거래 플랫폼 중 하나가 되었습니다.
Trendyol은 콘텐츠의 유연성을 유지하고 이전 버전의 React를 사용하는 동시에 대규모로 최상의 사용자 환경을 제공한다는 목표를 달성하기 위해 개선할 주요 측정항목으로 다음 페인트에 대한 상호작용(INP)에 중점을 두었습니다. 이 사례에서는 Trendyol이 PLP에서 INP를 개선하여 INP를 50% 감소시키고 검색 결과 비즈니스 측정항목을 1% 상승시킨 여정을 설명합니다.
Trendyol의 INP 조사 프로세스
INP는 사용자 입력에 대한 웹사이트의 응답성을 측정합니다. 양호한 INP는 브라우저가 모든 사용자 입력에 빠르고 안정적으로 반응하고 페이지를 다시 칠할 수 있음을 나타냅니다. 이는 우수한 사용자 환경의 핵심 구성요소입니다.
Trendyol은 PLP에서 INP를 개선하기 위한 여정을 개선하기 전에 사용자 환경을 철저히 분석했습니다. PSI 보고서에 따르면 PLP의 실제 사용자 환경은 다음 그림과 같이 모바일에서 963밀리초의 INP를 보였습니다.
우수한 응답성을 보장하려면 사이트 소유자는 200밀리초 미만의 INP를 목표로 해야 합니다. 즉, 해당 시점에 Trendyol의 INP는 '나쁨' 범위에 속했습니다.
다행히 PSI는 Chrome 사용자 환경 보고서(CrUX)에 포함된 페이지의 필드 데이터와 자세한 실험실 진단 데이터를 모두 제공합니다. 실험실 데이터를 살펴본 결과, Lighthouse의 JavaScript 실행 시간 감사에 따르면 search-result-v2
스크립트가 페이지의 다른 스크립트보다 더 오래 기본 스레드를 사용하고 있는 것으로 나타났습니다.
실제 병목 현상을 파악하기 위해 Chrome DevTools의 성능 패널을 사용하여 PLP 환경 문제를 해결하고 문제의 근원을 파악했습니다. Chrome DevTools에서 CPU 4배 감소로 모바일 성능을 에뮬레이션하면 기본 스레드에서 700~900밀리초의 긴 작업이 확인되었습니다. 기본 스레드가 50밀리초 이상 다른 작업으로 사용 중이면 사용자 입력에 적시에 응답하지 못하여 사용자 환경이 저하될 수 있습니다.
가장 긴 작업은 React 구성요소 내의 검색 결과 스크립트에서 Intersection Observer API 콜백으로 인해 발생했습니다. 이 시점에서 Google은 브라우저가 사용자 상호작용을 포함하여 우선순위가 더 높은 작업에 응답할 수 있는 기회를 더 많이 제공하기 위해 긴 작업을 작은 청크로 분할하는 방법을 찾기 시작했습니다.
Intersection Observer 콜백 내에서 React 재렌더링을 트리거하는 setState
작업을 사용하면 비용이 많이 들고, 이는 기본 스레드를 너무 오래 점유하여 저가형 기기에서 문제가 될 수 있습니다.
개발자가 작업을 더 작은 작업으로 분할하는 데 사용한 한 가지 메서드는 setTimeout
를 사용합니다. 이 기법을 사용하여 setState
호출의 실행을 별도의 태스크로 연기했습니다. setTimeout
는 JavaScript 실행 지연을 허용하지만 우선순위를 제어할 수 없습니다. 그 결과 기본 스레드에 양보한 후 스크립트 실행을 지속하기 위해 scheduler.yield
오리진 트라이얼에 참여하게 되었습니다.
/*
* 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 });
이 생성 메서드를 PLP 코드에 추가하면 INP가 개선됩니다. 긴 주요 작업이 일련의 작은 작업으로 분할되어 우선순위가 더 높은 작업(예: 사용자 상호작용 및 후속 렌더링 작업)이 그렇지 않은 경우보다 빠르게 진행될 수 있기 때문입니다.
Trendyol은 PuzzleJs 프레임워크를 사용하여 React v16.9.0을 사용하는 마이크로 프런트엔드 아키텍처를 구현합니다. React 18을 사용하면 동일한 성능을 얻을 수 있지만 여러 가지 이유로 Trendyol은 현재 업그레이드할 수 없습니다.
비즈니스 결과
구현된 INP 개선의 영향을 측정하기 위해 A/B 테스트를 실행하여 비즈니스 측정항목에 어떤 영향을 미치는지 확인했습니다. 전반적으로 PLP를 변경한 결과, INP가 50% 감소하고 사용자 세션당 등록정보 페이지에서 제품 세부정보 페이지로 연결되는 클릭률이 1% 증가하는 등 상당한 개선이 이루어졌습니다. 다음 그림은 시간 경과에 따라 PLP에서 INP가 어떻게 개선되었는지 보여줍니다.
결론
INP 최적화는 복잡하고 반복적인 프로세스이지만 명확한 워크플로를 사용하면 쉽게 만들 수 있습니다. 웹사이트의 INP를 디버그하고 개선하는 간단한 접근 방식은 자체 현장 데이터를 수집하는지에 따라 다릅니다. 그렇지 않다면 PSI와 Lighthouse를 시작으로 시작하세요. 문제가 있는 페이지를 식별하면 DevTools를 사용하여 더 깊이 파고들어 문제를 재현할 수 있습니다.
브라우저가 긴급한 작업을 더 많이 실행할 수 있도록 가끔 기본 스레드에 양보하면 웹사이트의 응답성이 향상되어 고객의 사용자 환경이 개선됩니다. scheduler.yield()
와 같은 최신 예약 API를 사용하면 이 작업이 더 쉬워집니다.
이 작업에 도움을 주신 Google의 제레미 바그너, 배리 폴러드, 후세인 지르데, Trendyol의 엔지니어링팀에 감사의 말을 전합니다.