프로그래밍 방식으로 Lighthouse 실행 소개

게시 됨: 2022-03-10
빠른 요약 ↬ Google의 Lighthouse 분석 제품군을 프로그래밍 방식으로 실행할 수 있다는 것은 특히 더 크거나 복잡한 웹 애플리케이션에 많은 이점을 제공합니다. Lighthouse를 프로그래밍 방식으로 사용하면 엔지니어가 Lighthouse의 간단한 응용 프로그램(예: Lighthouse CI)에서 허용하는 것보다 더 많은 사용자 지정이 필요한 사이트에 대한 품질 모니터링을 설정할 수 있습니다. 이 기사에는 Lighthouse에 대한 간략한 소개가 포함되어 있으며, 이를 프로그래밍 방식으로 실행할 때의 이점에 대해 설명하고 기본 구성을 안내합니다.

Lighthouse는 Google의 웹사이트 품질 분석 도구 모음입니다. 이를 통해 사이트의 성능, 접근성, SEO 등을 평가할 수 있습니다. 또한 고도로 구성 가능하므로 가장 단순한 것부터 매우 복잡한 것까지 모든 사이트에 유용할 만큼 충분히 유연합니다. 이러한 유연성에는 테스트를 실행하는 여러 가지 방법이 포함되므로 사이트 또는 응용 프로그램에 가장 적합한 방법을 선택할 수 있습니다.

Lighthouse를 실행하는 가장 간단한 방법 중 하나는 Chrome의 DevTools Lighthouse 패널을 사용하는 것입니다. Chrome에서 사이트를 연 다음 Chrome의 DevTools를 열면 "Lighthouse" 탭이 표시되어야 합니다. 여기에서 "보고서 생성"을 클릭하면 사이트의 품질 측정항목에 대한 전체 보고서를 얻을 수 있습니다.

그러나 이 기사에서 내가 초점을 맞추고 있는 것은 스펙트럼의 반대편에 있습니다. JavaScript를 사용하여 프로그래밍 방식으로 Lighthouse를 실행하면 사용자 지정 실행을 구성하고, 테스트할 기능을 선택 및 선택하고, 결과를 수집 및 분석하고, 사이트 및 응용 프로그램에 고유한 구성 옵션을 지정할 수 있습니다.

예를 들어, 여러 URL을 통해 액세스할 수 있는 사이트에서 작업할 수 있습니다. 각 URL에는 고유한 데이터와 스타일이 있으며 분석할 수 있는 마크업이 있을 수도 있습니다. 또는 각 테스트 실행에서 데이터를 수집하고 다른 방식으로 컴파일하거나 분석할 수 있습니다. 사이트 또는 응용 프로그램에 가장 적합한 것을 기반으로 Lighthouse 분석을 실행하는 방법을 선택할 수 있는 기능이 있으면 사이트 품질을 모니터링하고 사이트에 문제가 너무 많이 발생하거나 발생하기 전에 문제가 있는 부분을 더 쉽게 찾아낼 수 있습니다. 사이트의 사용자.

Lighthouse를 프로그래밍 방식으로 실행하는 것이 모든 사이트에 최선의 선택은 아니며 Lighthouse 팀이 도구를 사용하기 위해 구축한 다양한 방법을 모두 탐색하는 것이 좋습니다. 그러나 프로그래밍 방식으로 Lighthouse를 사용하기로 결정했다면 아래의 정보와 튜토리얼이 시작되기를 바랍니다.

등대 옵션 사용자 정의

프로그래밍 방식으로 Lighthouse를 실행하는 것의 장점은 Lighthouse 자체를 구성할 수 있을 뿐만 아니라 Lighthouse 테스트와 관련하여 원하거나 수행해야 하는 모든 것입니다. Lighthouse에는 시작하는 데 도움이 되는 몇 가지 훌륭한 문서가 있습니다. 그러나 프로그래밍 방식으로 실행하는 것을 최대한 활용하려면 Lighthouse의 작동 방식에 대해 자세히 알아보고 테스트 실행을 구성하고 테스트 결과를 보고해야 하는 두 가지 주요 위치가 있습니다.

Lighthouse 테스트 실행 구성

Lighthouse 테스트 실행 구성은 원하는 만큼 간단하거나 복잡할 수 있는 작업 중 하나입니다.

Lighthouse를 프로그래밍 방식으로 실행할 때 사용자 지정 옵션을 제공할 수 있는 세 곳이 있습니다. 테스트할 URL, Chrome 옵션 및 Lighthouse 구성 개체입니다. Lighthouse 문서에서 Lighthouse를 실행하기 위한 함수에서 이 세 가지 매개변수를 모두 볼 수 있습니다.

 function launchChromeAndRunLighthouse(url, opts, config = null) { return chromeLauncher.launch({chromeFlags: opts.chromeFlags}).then(chrome => { opts.port = chrome.port; return lighthouse(url, opts, config).then(results => { return chrome.kill().then(() => results.lhr) }); }); }

이러한 매개변수를 생성하는 데 필요한 모든 코드를 사용할 수 있습니다. 예를 들어 테스트하려는 여러 페이지 또는 URL이 있는 사이트가 있다고 가정해 보겠습니다. CI 작업의 일부로 CI 환경에서 해당 테스트를 실행하고 작업이 실행될 때마다 필요한 모든 페이지를 확인하고 싶을 수도 있습니다. 이 설정을 사용하면 JavaScript를 사용하여 URL을 만들고 각각에 대해 Lighthouse를 실행할 루프를 만들 수 있습니다.

필요한 모든 Chrome 옵션은 chrome-launcher에 전달되는 객체에 지정할 수 있습니다. 문서의 예에서 opts 개체에는 chrome-launcher에 전달할 수 있는 chromeFlags 라는 배열과 chrome-launcher에서 사용 중인 포트를 저장한 다음 Lighthouse에 전달할 수 있는 포트가 포함되어 있습니다.

마지막으로 Lighthouse 구성 개체를 사용하면 Lighthouse 관련 옵션을 추가할 수 있습니다. Lighthouse 패키지는 있는 그대로 사용하거나 확장 및 수정할 수 있는 기본 구성 개체를 제공합니다. 이 개체를 사용하여 테스트하려는 Lighthouse 테스트 범주 지정을 포함하여 다양한 작업을 수행할 수 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓

emulatedFormFactor 를 사용하여 테스트를 모바일 또는 데스크탑 에뮬레이터에서 실행할지 여부를 지정할 수 있습니다. extraHeaders 를 사용하여 브라우저에서 사용해야 하는 쿠키를 추가할 수 있습니다. 예를 들어 결과를 HTML로 출력하는 데스크톱 에뮬레이터에서 접근성 범주만 실행하는 테스트에는 다음과 같은 구성 개체가 있을 수 있습니다.

 const lighthouseOptions = { extends: 'lighthouse:default', settings: { onlyCategories: ['accessibility'], emulatedFormFactor:'desktop', output: ['html'], }, }

이 예는 최소 구성을 나타냅니다. 할 수 있는 일이 훨씬 더 많습니다. Lighthouse 구성 문서에는 훨씬 더 많은 정보가 있습니다. 또한 좀 더 복잡한 구현을 위한 샘플 구성 개체 집합이 있습니다.

맞춤 결과 보고

Lighthouse를 프로그래밍 방식으로 실행할 때 세 가지 형식의 옵션 중 하나 이상으로 결과를 반환할 수 있으며 이것이 제 생각에 가장 흥미로운 부분입니다. 원시 LHR(Lighthouse Result) 개체에 액세스할 수 있습니다.

HTML, JSON, CSV

Lighthouse는 HTML, JSON 또는 CSV의 세 가지 방식으로 결과 형식을 자동으로 지정합니다. 이는 예를 들어 Chrome DevTools 내에서 Lighthouse 테스트를 실행하는 경우 표시되는 기본 Lighthouse 보고 템플릿을 기반으로 하는 모두 사전 구성된 결과입니다. 이전 섹션의 lighthouseOptions 구성 개체에서 단일 문자열이 있는 배열을 포함하는 outputhtml 을 볼 수 있습니다. 이것은 결과가 HTML 형식으로만 반환되기를 원함을 지정합니다. 결과를 HTML과 JSON으로 모두 원하는 경우 해당 배열은 ['html', 'json'] 처럼 보일 것입니다.

Lighthouse가 실행되면 두 개의 키( reportlhr )가 포함된 결과 개체를 반환합니다. 다음 섹션에서 lhr 키의 내용에 대해 이야기할 것이지만 report 키에는 요청한 대로 형식이 지정된 결과가 포함된 배열이 포함되어 있습니다. 따라서 예를 들어 ['html', 'json'] 을 요청한 경우 results.report[0] 에는 HTML 형식의 결과가 포함되고 results.report[1] 에는 JSON 형식의 결과가 포함됩니다.

LHR 개체

Lighthouse를 프로그래밍 방식으로 실행하면 훨씬 더 유연한 결과 개체인 LHR 개체에 액세스할 수도 있습니다. 이 개체에는 Lighthouse 실행의 원시 결과와 일부 메타데이터가 포함되어 있습니다. 더 완전한 문서는 Lighthouse Github 리포지토리에서 찾을 수 있습니다.

사용자 지정 보고서 생성 및 분석을 위해 여러 실행에서 데이터 수집을 포함하여 다양한 방법으로 이러한 결과를 사용할 수 있습니다.

예: 모바일 및 데스크톱에 대한 접근성 테스트 실행

사용자가 작은 화면을 사용하는지 큰 화면을 사용하는지에 따라 다른 구성 요소를 로드하는 사이트가 있다고 가정해 보겠습니다. 즉, 사이트 버전마다 HTML이 약간씩 다릅니다. 저는 두 사이트 버전 모두 Lighthouse 접근성 테스트에서 95점을 받았고 해당 표준을 충족하지 않는 main 브랜치에 코드가 커밋되지 않았는지 확인하고 싶습니다.

참고 : Sparkbox 홈페이지를 분석하는 아래 코드의 작동 예를 보려면 여기에서 저장소를 찾을 수 있습니다.

접근성 카테고리를 두 번 실행하도록 Lighthouse를 구성하여 각각에 대해 서로 다른 구성 개체를 제공할 수 있습니다. 하나는 emulatedFormFactordesktop 으로 설정하고 다른 하나는 mobile 로 설정합니다. 이를 수행하는 쉬운 방법은 아래와 같이 두 객체가 모두 포함된 배열을 만드는 것입니다.

 const lighthouseOptionsArray = [ { extends: 'lighthouse:default', settings: { onlyCategories: ['accessibility'], emulatedFormFactor:'desktop', output: ['html', 'json'], }, }, { extends: 'lighthouse:default', settings: { onlyCategories: ['accessibility'], emulatedFormFactor:'mobile', output: ['html', 'json'], }, }, ]

그런 다음 이 배열을 반복하는 함수를 만들고 배열 내부에서 찾은 각 개체에 대해 Lighthouse 테스트를 실행할 수 있습니다.

한 가지 주의할 점은 각 실행 사이에 지연을 도입해야 한다는 것입니다. 그렇지 않으면 Chromium이 혼란스러워지고 실행에 오류가 발생할 수 있습니다. 이를 위해 setTimeout 간격이 완료되면 약속을 반환하는 wait 함수를 추가했습니다.

 function wait(val) { return new Promise(resolve => setTimeout(resolve, val)); } function launchLighthouse(optionSet, opts, results) { return chromeLauncher .launch({ chromeFlags: opts.chromeFlags }) .then(async chrome => { opts.port = chrome.port; try { results = await lighthouse(url, opts, optionSet); } catch (e) { console.error("lighthouse", e); } if (results) reportResults(results, runEnvironment, optionSet, chrome); await wait(500); chrome.kill(); }); } async function runLighthouseAnalysis() { let results; const opts = { chromeFlags: ["--no-sandbox", "--headless"] }; for (const optionSet of lighthouseOptionsArray) { console.log("****** Starting Lighthouse analysis ******"); await launchLighthouse(optionSet, opts, results); } }

이 경우 결과를 reportResults 함수로 보냅니다. 거기에서 결과를 로컬 파일에 저장하고, 결과를 콘솔에 인쇄하고, 테스트가 접근성 임계값을 통과하는지 여부를 결정하는 함수로 결과를 보냅니다.

 async function reportResults(results, runEnvironment, optionSet, chrome) { if (results.lhr.runtimeError) { return console.error(results.lhr.runtimeError.message); } await writeLocalFile(results, runEnvironment, optionSet); printResultsToTerminal(results.lhr, optionSet); return passOrFailA11y(results.lhr, optionSet, chrome); }

이 프로젝트의 경우 CI 테스트 실행을 위해 지정된 디렉터리에 JSON 결과를 저장하고 로컬 테스트 실행을 위해 지정된 디렉터리에 HTML 파일을 저장할 수 있기를 원합니다. Lighthouse가 이러한 다양한 유형의 결과를 반환하는 방식은 요청된 순서대로 배열에 있습니다.

따라서 이 예의 lighthouseOptions 개체에서 배열은 먼저 HTML을 요청한 다음 JSON을 요청합니다. 따라서 report 배열에는 HTML 형식의 결과가 먼저 포함되고 JSON 형식의 결과가 두 번째로 포함됩니다. 그런 다음 writeToLocalFile 함수는 사용자 정의된 이름을 가진 파일에 올바른 버전의 결과를 저장합니다.

 function createFileName(optionSet, fileType) { const { emulatedFormFactor } = optionSet.settings; const currentTime = new Date().toISOString().slice(0, 16); const fileExtension = fileType === 'json' ? 'json' : 'html'; return `${currentTime}-${emulatedFormFactor}.${fileExtension}`; } function writeLocalFile(results, runEnvironment, optionSet) { if (results.report) { const fileType = runEnvironment === 'ci' ? 'json' : 'html'; const fileName = createFileName(optionSet, fileType); fs.mkdirSync('reports/accessibility/', { recursive: true }, error => { if (error) console.error('error creating directory', error); }); const printResults = fileType === 'json' ? results.report[1] : results.report[0]; return write(printResults, fileType, `reports/accessibility/${fileName}`).catch(error => console.error(error)); } return null; }

또한 테스트 실행이 완료되면 결과를 터미널에 인쇄하고 싶습니다. 이렇게 하면 파일을 열지 않고도 결과를 빠르고 쉽게 볼 수 있습니다.

 function printResultsToTerminal(results, optionSet) { const title = results.categories.accessibility.title; const score = results.categories.accessibility.score * 100; console.log('\n********************************\n'); console.log(`Options: ${optionSet.settings.emulatedFormFactor}\n`); console.log(`${title}: ${score}`); console.log('\n********************************'); }

마지막으로 접근성 점수가 임계값인 95점을 충족하지 못하는 경우 테스트 실행에 실패할 수 있기를 원합니다.

 function passOrFailA11y(results, optionSet, chrome) { const targetA11yScore = 95; const { windowSize } = optionSet; const accessibilityScore = results.categories.accessibility.score * 100; if (accessibilityScore) { if (windowSize === 'desktop') { if (accessibilityScore < targetA11yScore) { console.error(`Target accessibility score: ${targetA11yScore}, current accessibility score ${accessibilityScore}`); chrome.kill(); process.exitCode = 1; } } if (windowSize === 'mobile') { if (accessibilityScore < targetA11yScore) { console.error(`Target accessibility score: ${targetA11yScore}, current accessibility score ${accessibilityScore}`); chrome.kill(); process.exitCode = 1; } } } }

Lighthouse를 사용하여 사이트 품질을 모니터링하는 데 도움이 될 수 있는 다양한 방법을 모두 탐색해 보시기 바랍니다.

최종 메모

의도적으로 위의 예제를 비교적 단순하게 유지했지만, 이 예제가 Lighthouse를 프로그래밍 방식으로 실행할 때 달성할 수 있는 작업에 대한 좋은 개요를 제공하기를 바랍니다. 이 유연하고 강력한 도구를 사용하는 새로운 방법을 찾는 데 영감을 주기를 바랍니다.

피터 드러커가 말했듯이:

"측정할 수 없으면 개선할 수 없습니다."

특히 복잡한 사이트의 경우 웹 사이트 품질을 측정할 뿐만 아니라 모니터링할 수 있다는 것은 더 나은 웹을 구축하는 데 큰 도움이 될 것입니다.

SmashingMag에 대한 추가 정보:

  • 모바일 우선 경험을 위한 A/B 테스트
  • 효과를 위해 디자인 개념을 테스트하는 방법
  • 수동 접근성 테스트의 중요성
  • Tensorflow.js를 사용한 프론트엔드 개발자를 위한 머신 러닝
  • 작업 속도를 높이는 다음 팁으로 UI 디자인 시작하기

물론 Smashing Workshops에서 새로운 통찰력을 탐구하는 Smashing Cat.

유용한 프론트엔드 및 UX 비트, 일주일에 한 번 제공됩니다.

작업을 더 잘 수행하는 데 도움이 되는 도구가 있습니다. 이메일을 통해 Vitaly의 스마트 인터페이스 디자인 체크리스트 PDF 를 구독하고 받으십시오.

프론트엔드 및 UX에서. 190,000명의 사람들이 신뢰합니다.