테라가 광고 클릭률을 30% 높이고 최대 콘텐츠 렌더링 시간을 늘리는 데 프리패치를 사용한 방법

리소스를 미리 가져오면 페이지 로드 시간이 단축되고 비즈니스 측정항목이 개선됩니다.

Guilherme Moser de Souza
Guilherme Moser de Souza

미리 가져오기는 가까운 미래에 필요할 수 있는 리소스(또는 전체 페이지)를 다운로드하여 페이지 로딩 속도를 높이는 데 사용되는 기술입니다. 연구에 따르면 로드 시간이 빨라질수록 전환율이 높아지고 사용자 환경이 개선되는 것으로 나타났습니다.

Terra는 브라질 최대의 콘텐츠 포털 중 하나로, 매월 6,300만 명이 넘는 순 방문자가 엔터테인먼트, 뉴스, 스포츠를 제공합니다. Google은 Terra의 엔지니어링팀과 협력하여 웹사이트의 특정 섹션에 미리 가져오기 기법을 사용하여 기사 로드 시간을 개선했습니다.

이 케이스 스터디에서는 Terra의 여정 구현을 통해 모바일의 광고 클릭률 (CTR)이 11%, 데스크톱의 광고 CTR이 30% 증가하고 최대 콘텐츠 렌더링 시간 (LCP)이 50% 감소한 사례를 설명합니다.

미리 가져오기 전략

미리 가져오기는 한동안 사용되어 왔지만, 당장 필요하지 않은 리소스에 대해 추가 대역폭을 사용하기 때문에 주의해서 사용하는 것이 중요합니다. 이 기법은 불필요한 데이터 사용을 방지하기 위해 신중하게 적용해야 합니다. Terra의 경우 다음 조건이 충족되면 기사가 미리 로드됩니다.

  • 미리 가져온 기사 링크 공개 상태: Terra는 Intersection Observer API를 사용하여 미리 가져오려는 기사가 포함된 섹션의 조회가능성을 감지했습니다.
  • 데이터 사용량 증가를 위한 유리한 조건: 앞서 언급했듯이 미리 가져오기는 추가 데이터를 소비하는 예측 성능 개선이며 모든 상황에서 바람직한 결과는 아닐 수도 있습니다. 대역폭 낭비 가능성을 줄이기 위해 Terra는 Device Memory API와 함께 Network Information API를 사용하여 다음 도움말을 가져올지 결정합니다. Terra는 다음과 같은 경우에만 다음 기사를 가져옵니다.
    • 연결 속도가 3G 이상이고 기기에 메모리가 4GB 이상 있습니다.
    • 또는 기기가 iOS를 실행하는 경우
  • CPU 유휴 상태: 마지막으로 Terra는 CPU가 유휴 상태이고 추가 작업을 실행할 수 있는지 확인합니다. 이를 위해 requestIdleCallback를 사용합니다. 이 함수는 기본 스레드가 유휴 상태일 때 처리할 콜백을 가져오거나 특정(선택사항) 기한(둘 중 먼저 오는 값)까지 기다립니다.

이러한 조건을 준수하면 Terra가 필요한 경우에만 데이터를 가져오므로 대역폭과 배터리 수명이 절약되고 사용되지 않는 미리 가져오기의 영향이 최소화됩니다.

이러한 조건이 충족되면 Terra는 아래에 파란색으로 강조표시된 '관련 콘텐츠' 및 '추천' 섹션에 있는 기사를 미리 가져옵니다.

링크가 미리 로드된 Terra 웹사이트의 두 섹션 스크린샷 왼쪽에는 '관련 콘텐츠'가 강조표시되어 있고 오른쪽에는 '추천' 섹션이 강조표시되어 있습니다.

비즈니스 영향

이 기법의 영향을 측정하기 위해 테라는 먼저 기사 페이지의 '관련 콘텐츠' 섹션에 이 기능을 출시했습니다. UTM 코드를 사용하면 비교 목적으로 미리 로드된 기사와 미리 로드되지 않은 기사를 구분할 수 있었습니다. 2주간의 성공적인 A/B 테스트를 마친 후 Terra는 미리 가져오기 기능을 '추천 항목' 섹션에 추가하기로 했습니다.

기사를 미리 로드한 결과 광고 측정항목이 전반적으로 증가하고 LCP 및 TTFB (Time To First Byte) 시간이 감소했습니다.

측정항목 모바일 데스크톱
Google Ads CTR +11% +30%
광고 조회가능성 +10.5% +6%
LCP -51% -73%
TTFB -83% -84%

주의해서 사용하면 페이지 로드 시간이 크게 개선되고 광고 측정항목이 증가하며 LCP 시간이 줄어듭니다.

기술 세부정보

미리 가져오기는 quicklink 또는 Guess.js와 같은 라이브러리를 통해 rel=prefetch 또는 rel=preload과 같은 리소스 힌트를 사용하거나 최신 Speculation Rules API를 사용하여 달성할 수 있습니다. Terra는 Intersection Observer 인스턴스와 함께 낮은 우선순위fetch API를 사용하여 이를 구현하기로 했습니다. Terra는 아직 rel=prefetch 또는 Speculation Rules API와 같은 다른 미리 로드 방법을 지원하지 않는 Safari를 지원할 수 있고 Terra의 요구사항에 모든 기능을 갖춘 JavaScript 라이브러리가 필요하지 않았기 때문에 이 방법을 선택했습니다.

아래 JavaScript는 Terra에서 사용하는 코드와 거의 같습니다.

function prefetch(nodeLists) {
  // Exclude slow ECTs < 3g
  if (navigator.connection &&
    (navigator.connection.effectiveType === 'slow-2g'
      || navigator.connection.effectiveType === '2g')
  ) {
    return;
  }

  // Exclude low end device which is device with memory <= 2GB
  if (navigator.deviceMemory && navigator.deviceMemory <= 2) {
    return;
  }

  const fetchLinkList = {};

  const observer = new IntersectionObserver(function (entries) {
    entries.forEach(function (entry) {
      if (entry.isIntersecting) {
        if (!fetchLinkList[entry.target.href]) {
          fetchLinkList[entry.target.href] = true;

          fetch(entry.target, {
            priority: 'low'
          });
        }

        observer.unobserve(entry = entry.target);
      }
    });
  });
}

const idleCallback = window.requestIdleCallback || function (cb) {
  let start = Date.now();

  return setTimeout(function () {
    cb({
      didTimeout: false,
      timeRemaining: function () {
        return Math.max(0, 50 - (Date.now() - start));
      }
    });
  }, 1);
}

idleCallback(function () {
  prefetch(nodeLists)
})
  • prefetch 함수는 미리 가져오기를 시작하기 전에 먼저 최소 연결 품질과 기기 메모리를 확인합니다.
  • 그런 다음 IntersectionObserver를 사용하여 요소가 표시 영역에 표시되는 시점을 모니터링하고 미리 가져올 수 있도록 URL을 목록에 추가합니다.
  • prefetch 프로세스는 requestIdleCallback로 예약되며, 기본 스레드가 유휴 상태일 때 prefetch 함수를 실행하는 것을 목표로 합니다.

결론

미리 가져오기를 주의해서 사용하면 향후 탐색 요청의 로드 시간을 크게 줄일 수 있으므로 사용자 여정에서 어려움을 줄이고 참여를 높일 수 있습니다. 미리 가져오기를 수행하면 사용할 수 없는 추가 바이트가 로드되므로 Terra는 네트워크 상태가 좋고 이 정보를 사용할 수 있는 지원 기기에서만 미리 가져오기 위해 추가 조치를 취했습니다.

이 작업에 도움을 주신 Gilberto Cocchi, Harry Theodoulou, Miguel Carlos Martínez Díaz, Barry Pollard, Jeremy Wagner, Terra 엔지니어링팀의 Leonardo Bellini, Lucca Paradeda에게 감사의 인사를 전합니다.