Lighthouse 사용자 플로우

새로운 Lighthouse API를 사용하여 사용자 플로우 전반에 걸쳐 성능과 권장사항을 측정합니다.

브렌단 케니
브렌든 케니

Lighthouse는 초기 페이지 로드 중에 성능과 권장사항을 테스트하기에 좋은 도구입니다. 그러나 기존에는 Lighthouse를 사용하여 페이지 수명에 관한 다음과 같은 다른 측면을 분석하기 어려웠습니다.

  • 웜 캐시로 페이지 로드
  • 서비스 워커가 활성화된 페이지
  • 잠재적인 사용자 상호작용 고려

따라서 Lighthouse에서 중요한 정보를 놓칠 수 있습니다. 코어 웹 바이탈은 캐시가 비어 있는 페이지뿐 아니라 모든 페이지 로드를 기반으로 합니다. 또한 레이아웃 변경 횟수 (CLS)와 같은 측정항목은 페이지가 열린 전체 시간 동안 측정할 수 있습니다.

Lighthouse에는 페이지 수명 중 어느 시점에서든 실험실 테스트를 수행할 수 있는 새로운 사용자 플로우 API가 있습니다. Puppeteer는 페이지 로드를 스크립팅하고 합성 사용자 상호작용을 트리거하는 데 사용되며, Lighthouse는 여러 가지 방법으로 호출되어 이러한 상호작용 중에 주요 통계를 캡처할 수 있습니다. 즉, 페이지가 로드되는 동안 페이지와 상호작용하는 동안 실적을 측정할 수 있습니다. 접근성 검사는 초기 뷰뿐만 아니라 결제 흐름 내에서도 CI에서 실행하여 회귀가 발생하지 않도록 할 수 있습니다.

이제 실제로 작동하는 사용자 플로우를 위해 작성된 거의 모든 Puppeteer 스크립트에 Lighthouse가 삽입되어 전반적인 성능과 권장사항을 측정할 수 있습니다. 이 튜토리얼에서는 사용자 흐름의 다양한 부분(예: 탐색, 스냅샷, 기간)을 측정할 수 있는 새로운 Lighthouse 모드를 살펴봅니다.

설정

User Flow API는 아직 미리보기 상태이지만 현재 Lighthouse에서 사용할 수 있습니다. 아래 데모를 사용해 보려면 Node 버전 14 이상이 필요합니다. 빈 디렉터리를 만들고 다음을 실행합니다.

# Default to ES modules.
echo '{"type": "module"}' > package.json

# Init npm project without the wizard.
npm init -y

# Dependencies for these examples.
npm install lighthouse puppeteer open

새로운 Lighthouse '탐색' 모드는 실제로 지금까지 표준 Lighthouse 동작에 이름이 지정되어 있습니다. 즉, 페이지의 콜드 로드를 분석합니다. 이는 페이지 로드 성능을 모니터링하는 데 사용하는 모드이지만 사용자 플로우도 새로운 통계를 얻을 수 있는 가능성을 열어줍니다.

페이지 로드를 캡처하는 Lighthouse 스크립트를 작성하려면 다음 안내를 따르세요.

  1. Puppeteer를 사용하여 브라우저를 엽니다.
  2. Lighthouse 사용자 플로우를 시작합니다.
  3. 타겟 URL로 이동합니다.
import fs from 'fs';
import open from 'open';
import puppeteer from 'puppeteer';
import {startFlow} from 'lighthouse/lighthouse-core/fraggle-rock/api.js';

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const flow = await startFlow(page, {name: 'Single Navigation'});
  await flow.navigate('https://web.dev/performance-scoring/');

  await browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

가장 간단한 흐름입니다. 보고서를 열면 보고서가 한 단계만 포함된 요약 보기가 표시됩니다. 이 단계를 클릭하면 해당 탐색에 대한 기존 Lighthouse 보고서가 표시됩니다.

단일 탐색을 보여주는 Lighthouse 흐름 보고서
실시간으로 보고서 보기

Lighthouse의 일반적인 경우와 마찬가지로 이 페이지는 캐시 또는 로컬 저장소를 먼저 삭제한 상태로 로드하지만 사이트를 방문하는 실제 사용자의 방문에는 콜드 및 웜 캐시가 혼합되며, 이와 같은 콜드 로드와 여전히 웜 캐시로 페이지로 돌아가는 사용자 간에는 성능 차이가 크게 발생할 수 있습니다.

웜 로드 캡처

이 스크립트에 두 번째 탐색을 추가할 수도 있습니다. 이번에는 Lighthouse가 탐색에서 기본적으로 수행하는 캐시 및 저장소 삭제를 사용 중지합니다. 다음 예에서는 web.dev 자체에서 기사를 로드하여 캐싱이 얼마나 유용한지 확인합니다.

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const testUrl = 'https://web.dev/performance-scoring/';
  const flow = await startFlow(page, {name: 'Cold and warm navigations'});
  await flow.navigate(testUrl, {
    stepName: 'Cold navigation'
  });
  await flow.navigate(testUrl, {
    stepName: 'Warm navigation',
    configContext: {
      settingsOverrides: {disableStorageReset: true},
    },
  });

  await browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

그 결과 나타나는 흐름 보고서는 다음과 같습니다.

성능 점수가 더 높은 탐색 2개(콜드 및 웜 1개)를 보여주는 Lighthouse 흐름 보고서
실시간으로 보고서 보기

콜드 로드와 웜 로드의 조합을 통해 실제 사용자가 경험하는 상황을 보다 자세히 파악할 수 있습니다. 사용자가 한 번의 방문에서 여러 페이지를 로드하는 사이트의 경우, 이 기능을 통해 사용자가 현장에서 어떤 경험을 하고 있는지 좀 더 현실적으로 파악할 수 있습니다.

스냅샷

스냅샷은 단일 시점에 Lighthouse 감사를 실행하는 새로운 모드입니다. 일반적인 Lighthouse 실행과 달리 페이지가 새로고침되지 않습니다. 이렇게 하면 페이지를 설정하고 드롭다운이 열려 있거나 양식을 부분적으로 채운 등 정확한 상태에서 테스트할 수 있습니다.

이 예에서는 Squoosh 내 고급 설정의 일부 새로운 UI가 자동화된 Lighthouse 검사를 통과하는지 확인하려고 한다고 가정해 보겠습니다. 이러한 설정은 이미지가 로드되고 옵션 메뉴가 확장되어 고급 설정이 표시된 경우에만 표시됩니다.

Squoosh 고급 설정 메뉴
Squoosh 고급 설정 메뉴

이 프로세스는 Puppeteer로 스크립팅할 수 있으며, 각 단계에서 실제로 Lighthouse 스냅샷을 만들 수 있습니다.

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const flow = await startFlow(page, {name: 'Squoosh snapshots'});

  await page.goto('https://squoosh.app/', {waitUntil: 'networkidle0'});

  // Wait for first demo-image button, then open it.
  const demoImageSelector = 'ul[class*="demos"] button';
  await page.waitForSelector(demoImageSelector);
  await flow.snapshot({stepName: 'Page loaded'});
  await page.click(demoImageSelector);

  // Wait for advanced settings button in UI, then open them.
  const advancedSettingsSelector = 'form label[class*="option-reveal"]';
  await page.waitForSelector(advancedSettingsSelector);
  await flow.snapshot({stepName: 'Demo loaded'});
  await page.click(advancedSettingsSelector);

  await flow.snapshot({stepName: 'Advanced settings opened'});

  browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

결과 보고서에는 일반적으로 양호한 결과가 표시되지만 수동으로 확인해야 하는 몇 가지 접근성 기준이 있을 수 있습니다.

촬영한 스냅샷을 보여주는 Lighthouse 흐름 보고서
실시간으로 보고서 보기

기간

현장 (예: CrUX)과 실험실 (예: Lighthouse)의 성능 결과 간의 가장 큰 차이 중 하나는 사용자 입력이 부족하다는 것입니다. 이때 마지막 사용자 플로우 모드인 기간이 도움이 될 수 있습니다.

기간을 선택하면 일정 기간 동안 Lighthouse 감사가 실행되며 탐색이 포함될 수도 있고 포함되지 않을 수도 있습니다. 이렇게 하면 상호작용 중에 페이지의 상황을 캡처할 수 있습니다. 예를 들어 Lighthouse는 기본적으로 페이지 로드 중에 CLS를 측정하지만, 현장에서는 초기 탐색부터 페이지가 닫힐 때까지 CLS가 측정됩니다. 사용자 상호작용이 CLS의 트리거인 경우 이전에는 Lighthouse가 이를 포착하여 해결할 수 없었습니다.

공간을 예약하지 않은 상태에서 스크롤 중에 기사에 광고가 삽입되는 것을 시뮬레이션하는 테스트 사이트를 확인해 보세요. 긴 연속 카드에서는 슬롯이 표시 영역에 들어올 때 빨간색 정사각형이 가끔 추가됩니다. 빨간색 정사각형에는 공간이 예약되어 있지 않으므로 아래에 있는 카드가 화면 밖으로 이동해 레이아웃이 변경됩니다.

일반 Lighthouse 탐색의 CLS는 0입니다. 그러나 스크롤하면 페이지에서 레이아웃 변경 문제가 발생하고 CLS 값이 올라갑니다.

데모 사이트 사용해 보기

다음 스크립트는 두 작업이 모두 포함된 사용자 플로우 보고서를 생성하여 차이점을 보여줍니다.

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  // Get a session handle to be able to send protocol commands to the page.
  const session = await page.target().createCDPSession();

  const testUrl = 'https://pie-charmed-treatment.glitch.me/';
  const flow = await startFlow(page, {name: 'CLS during navigation and on scroll'});

  // Regular Lighthouse navigation.
  await flow.navigate(testUrl, {stepName: 'Navigate only'});

  // Navigate and scroll timespan.
  await flow.startTimespan({stepName: 'Navigate and scroll'});
  await page.goto(testUrl, {waitUntil: 'networkidle0'});
  // We need the ability to scroll like a user. There's not a direct puppeteer function for this, but we can use the DevTools Protocol and issue a Input.synthesizeScrollGesture event, which has convenient parameters like repetitions and delay to somewhat simulate a more natural scrolling gesture.
  // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture
  await session.send('Input.synthesizeScrollGesture', {
    x: 100,
    y: 600,
    yDistance: -2500,
    speed: 1000,
    repeatCount: 2,
    repeatDelayMs: 250,
  });
  await flow.endTimespan();

  await browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

이렇게 하면 일반 탐색을 탐색과 이후 스크롤이 모두 포함된 기간과 비교하는 보고서가 생성됩니다.

촬영한 스냅샷을 보여주는 Lighthouse 흐름 보고서
실시간으로 보고서 보기

각 단계를 자세히 살펴보면 탐색 전용 단계에 CLS가 0으로 표시됩니다. 유용한 사이트입니다.

모든 초록색 측정항목을 포함한 페이지 탐색만 다루는 Lighthouse 보고서

그러나 '탐색 및 스크롤' 단계는 다른 이야기를 합니다. 현재는 총 차단 시간과 누적 레이아웃 변경만 기간별로 사용할 수 있지만, 이 페이지의 지연 로드 콘텐츠가 사이트의 CLS를 명확하게 설명하고 있습니다.

실패한 CLS와 관련된 페이지 탐색 및 스크롤을 다루는 Lighthouse 보고서

이전에는 Lighthouse에서 이러한 문제가 있는 CLS 동작을 식별할 수 없었지만, 실제 사용자 환경에는 이러한 동작이 분명히 나타날 것입니다. 스크립트화된 상호작용에 대한 성능 테스트를 수행하면 실습 충실도가 크게 향상됩니다.

의견 요청

Lighthouse의 새로운 사용자 흐름 API는 많은 새로운 작업을 할 수 있지만 사용자에게 발생하는 시나리오의 종류를 측정하기에는 여전히 복잡할 수 있습니다.

궁금한 점이 있으면 Lighthouse 토론 포럼에 문의하세요. 버그나 제안사항이 있으면 Issue Tracker에 제출하세요.