Pupeter+Lighthouse+GiitHubAction을 통해 인증된 웹 응용 프로그램을 정기적으로 측정하는 Webperf
뭐 했어요?
이처럼 GiitHub Actions에서 인증이 있는 웹 애플리케이션에 대해 Pupeteer를 통해 주기적으로 Lighthouse를 실행해 결과를 Datadog에 보내는 프로젝트를 제작했다.
실제 그 항목의 측정값을 사용한 Datadog의 계기판은 이쪽에 있습니다.
Webperf의 주요 지표는 시간순으로 표시됩니다.
샘플 항목은 여기 있습니다.
다음은 설치에 대한 간단한 설명입니다.
Pupeter+Lighthouse 기반 성능 측정
Puppeeter+Lighthouse의 성능 측정은 이쪽 코드로 진행됩니다.
webperf-watcher-sample/blob/master/src/main.ts
src/main.ts
//...
const login = async (browser: puppeteer.Browser) => {
const page = await browser.newPage();
await page.goto(`${BASE_URL}/login`);
const navigationPromise = page.waitForNavigation();
await page.type("input#id", LOGIN_ID);
await page.type("input#password", LOGIN_PASS);
await page.click(".login-button");
await navigationPromise;
};
// ...
const main = async () => {
// chrome-launcher でChromeを起動しPuppeteerに接続
const chrome = await chromeLauncher.launch(CHROME_OPTIONS);
const res = await fetch(`http://localhost:${chrome.port}/json/version`, {
method: "GET",
});
const { webSocketDebuggerUrl } = await res.json();
const browser = await puppeteer.connect({
browserWSEndpoint: webSocketDebuggerUrl,
});
// ログインの実行
await login(browser);
const ddClient = new DDClient(DD_API_KEY);
for (const url of TARGET_URLS) {
// lighthouseの実効(直列実効でないと落ちるので注意)
const { lhr } = await lighthouse(
url,
{ ...CHROME_OPTIONS, port: chrome.port },
LIGHTHOUSE_OPTIONS
);
const json = reportGenerator.generateReport(lhr, "json");
const audits = JSON.parse(json as string).audits;
// ...
}
await browser.disconnect();
await chrome.kill();
};
Node.js에서 크롬Chrome Launcher을 시작하여Headless 크롬을 열고 Pupeteer와 연결하고 크롬을 이용하여Lighthouse를 실행합니다.Pupeteer와 Lighthouse의 합작은 아래 창고를 참고했다.
실제 설치 요점은
main
함수가 Lighthouse가 실행되기 전에 로그인 처리를 하고 Chrome에 인증 정보를 기록하는 것입니다.사전 인증을 하면 인증된 페이지라도 로그인 화면으로 리디렉션되지 않아 라이트하우스에서 측정할 수 있다.
데이터dog에 도량 보내기
Datadog에 측정 값을 보낼 때는 Datadog의 HTTP REST API가 사용됩니다.
이 예에서는 Datadog을 사용하지만 Google 스프레드시트든 BigQuery든 데이터를 통합하고 시각화할 수만 있다면 됩니다.
이쪽 코드는 측정값의 발송 처리입니다.Lighthouse 측정 데이터에서 정의된 속성
TARGET_METRICS
을 추출하여 뒤에 설명된 데이터 dog 클라이언트로 보냅니다.webperf-watcher-sample/blob/master/src/main.ts
src/main.ts
// ..bundleRenderer.renderToStream
const main = () => {
// ...
const { lhr } = await lighthouse(
url,
{ ...CHROME_OPTIONS, port: chrome.port },
LIGHTHOUSE_OPTIONS
);
const json = reportGenerator.generateReport(lhr, "json");
const audits = JSON.parse(json as string).audits;
// Datadogへの送信
await Promise.all(
TARGET_METRICS.map(async (metrics) => {
await ddClient.sendMetrics(
metricsName(url, audits[metrics]),
audits[metrics]
);
})
);
//...
}
// ...
견본 공사에서 다음과 같은 도량을 발송하였다.metrics
description
FCP
First Contentful Paint. DOM 컨텐트가 재현될 때까지의 시간(디테일
LCP
Largest Contentful Paint. 웹 Vitals의 지표 중 하나입니다.최대 컨텐트가 표시될 때까지 브라우저가 표시되는 시간디테일
TTI
Time to Interactive. 페이지가 완전히 상호작용할 때까지 디테일
Speed Index
페이지 그리기 속도에 대한 지표 표시디테일
MPFID
Max Potential First Input Delay. 웹 Vitals의 지표 중 하나입니다.사용자가 겪을 수 있는 최악의 경우 첫 번째 입력 지연디테일
TBT
Total Blocking Time. FCP에서 TTI로 사용자 입력 응답 시간 단축디테일
Datadog 고객은 여기에 있습니다.메트릭 이름과 측정값을 받아들여 내부 Datadog의 REST API에서 제공하는 Submit Metrics의 API를 두드립니다.
webperf-watcher-sample/blob/master/src/lib/ddClient.ts
src/lib/ddClient.ts
export class DDClient {
private apiUrl: string;
constructor(apiKey: string) {
this.apiUrl = `https://api.datadoghq.com/api/v1/series?api_key=${apiKey}`;
}
async sendMetrics(metricsName: string, data: AuditsResult) {
const requestBody = JSON.stringify({
series: [
{
metric: metricsName,
points: [
[
`${Math.floor(Date.now() / 1000)}`,
`${Math.round(data.numericValue / 10) * 10}`,
],
],
type: "gauge",
},
],
});
return await this.post(requestBody);
}
private async post(requestBody: string) {
return await fetch(this.apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: requestBody,
});
}
}
상기 데이터dog 송신 양도 때문에 그 양도로만 계기판을 제작합니다.다음 대시보드에서 타임라인 위젯를 사용할 때 시리즈 데이터로 시각화됩니다.
GiitHub Action에서 정기적으로 수행
정기적인 실행은 GiitHub Action의 cron 트리거에 의해 이루어집니다.
GiitHub Actions의 Ubuntu 이미지에서 크롬이 표준이기 때문에 특별한 설정 없이 실행할 수 있습니다.
다음 예제에서는 시간당 측정 스크립트를 실행합니다.
.github/workflows/mesure-webperf.yml
.github/workflows/mesure-webperf.yml
name: Measure webperf
on:
schedule:
- cron: '0 */1 * * *'
jobs:
measure-webperf:
runs-on: ubuntu-18.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v1
- name: Install packages.
run: yarn install
- name: Measure webperf.
run: yarn start
env:
LOGIN_ID: ${{ secrets.LOGIN_URL }}
LOGIN_PASS: ${{ secrets.LOGIN_PASS }}
DD_API_KEY: ${{ secrets.DD_API_KEY }}
cron에서 실행되는 GiitHub Action의 작업에 대해 timeout-minutes를 설정해야 합니다.GTHub Actions의 표준 제한 시간은 6h입니다.시간 초과 설정을 깜빡하고 하루 만에 GiitHub Action의 무료 파일을 묻고 이런 위업을 이뤘습니다.😇
마지막 고비
마지막으로 설치할 때 막힌 부분의 공유입니다.
브라우저보다 10초 느리게 실행
처음에는 왠지 스크립트에서 Lighthouse를 실행한 후 브라우저에서 직접 측정한 것보다 어떤 득점이 10여 초 느린 현상이 고민스러웠다.
헤드리스 크롬 특유의 문제인 줄 알았는데 결과적으로 라이트하우스의 옵션 설정이 잘못된 게 원인이었다.
Node.js의 Lighthouse는 기본적으로 저속 네트워크 회선을 모방하여 측정합니다.
GoogleChrome/lighthouse/blob/v6.4.1/lighthouse-core/config/constants.js#L20-L29
일반적인 브라우저가 실행될 때와 같은 네트워크 모드로 바뀌면 문제가 해결된다.설정 값은 Lighthouse의 코드 베이스의 다음 부분을 참조합니다.
GoogleChrome/lighthouse/blob/v6.4.1/lighthouse-core/config/constants.js#L43-L51
샘플 항목의 설정 예는 이쪽
throttling
의 부분이다.webperf-watcher-sample/blob/master/src/constants.ts
src/constants.ts
// ...
export const LIGHTHOUSE_OPTIONS = {
// ...
settings: {
// ...
throttling: {
rttMs: 40,
throughputKbps: 10 * 1024,
cpuSlowdownMultiplier: 1,
requestLatencyMs: 0,
downloadThroughputKbps: 0,
uploadThroughputKbps: 0,
},
// ...
},
};
//...
끝말
Lighthouse+Pupeteer+GiitHub Action이 제작한 전단 성능 측정 항목을 간단하게 소개한다.
상당히 쉽기 때문에 추천합니다.측정일 뿐 실제 공연과 조정에는 이르지 못했지만 앞으로 노력하겠다.
참고 자료
Reference
이 문제에 관하여(Pupeter+Lighthouse+GiitHubAction을 통해 인증된 웹 응용 프로그램을 정기적으로 측정하는 Webperf), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ryo_kawamata/articles/webperf-watcher텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)