viviONグループでは、DLsiteやcomipoなど、二次元コンテンツを世の中に届けるためのサービスを運営しています。
ともに働く仲間を募集していますので、興味のある方はこちらまで。
はじめに
Webページのメモリ使用量をモニタリングする必要があったので、PlaywrightとCDPを用いて計測してみました。
Playwrightの解説は割愛します。
使用環境
- node 20+
- playwright@1.47.0
Chrome DevTools Protocol(CDP)とは
Chrome DevTools Protocol(CDP)は、Chromium、Chrome、その他のBlinkベースのブラウザを外部から操作するためのプロトコルです。CDPを利用することで、パフォーマンスの計測など、Devtoolで提供されている機能をプログラム経由で制御することが可能になります。
PlaywrightとCDPを用いてWebページのメモリ使用量を計測する
Playwrightを用いてWebページにアクセスし、CDP経由でメモリ使用量を計測してみます。
サンプルスクリプト
以下が今回解説するスクリプトです。
import { chromium } from "playwright";
async function main() {
const browser = await chromium.launch();
const page = await browser.newPage();
const client = await page.context().newCDPSession(page);
await client.send("Performance.enable");
await page.goto("https://example.com");
// 必要であれば計測前にGCを実行する
// await client.send('HeapProfiler.collectGarbage')
const performanceMetrics = await client.send("Performance.getMetrics");
const memoryMetrics = performanceMetrics.metrics.filter(
(metric) =>
metric.name === "JSHeapUsedSize" || metric.name === "JSHeapTotalSize"
);
console.log("Memory Metrics:", memoryMetrics);
await browser.close();
}
main();
スクリプトを実行すると、以下のメトリクスを取得できます。
[
{
name: "JSHeapUsedSize",
value: 874812,
}, {
name: "JSHeapTotalSize",
value: 2260992,
}
]
解説
-
chromium.launch()
でChromiumブラウザを起動し、新規ページを作成しますconst browser = await chromium.launch(); const page = await browser.newPage();
-
context.newCDPSession
を使用して、ページに対するCDPセッションを開始しますconst client = await page.context().newCDPSession(page);
-
メトリクスの計測を有効にする
CDPの
Performance.enable
を呼び出してメトリクスの計測を有効にします。await client.send('Performance.enable');
-
対象のページに移動する
page.goto
を使用して対象のWebページに移動します。await page.goto('https://example.com')
-
パフォーマンスメトリクスを取得する
CDPの
Performance.getMetrics
を呼び出してメトリクスを取得します。
必要であれば事前にHeapProfiler.collectGarbage
を呼び出して、不要になったメモリを解放してください。// 必要であれば計測前にGCを実行する // await client.send('HeapProfiler.collectGarbage') const performanceMetrics = await client.send('Performance.getMetrics'); const memoryMetrics = performanceMetrics.metrics.filter( (metric) => ['JSHeapUsedSize', 'JSHeapTotalSize'].includes(metric.name) ); console.log('Memory Metrics:', memoryMetrics);
今回はメモリ関連以外のメトリクスは除外していますが、以下が計測可能な全てのメトリクスです。
全てのメトリクス
[
{
name: "Timestamp",
value: 896268.163451,
}, {
name: "AudioHandlers",
value: 0,
}, {
name: "AudioWorkletProcessors",
value: 0,
}, {
name: "Documents",
value: 3,
}, {
name: "Frames",
value: 1,
}, {
name: "JSEventListeners",
value: 0,
}, {
name: "LayoutObjects",
value: 15,
}, {
name: "MediaKeySessions",
value: 0,
}, {
name: "MediaKeys",
value: 0,
}, {
name: "Nodes",
value: 43,
}, {
name: "Resources",
value: 0,
}, {
name: "ContextLifecycleStateObservers",
value: 3,
}, {
name: "V8PerContextDatas",
value: 4,
}, {
name: "WorkerGlobalScopes",
value: 0,
}, {
name: "UACSSResources",
value: 0,
}, {
name: "RTCPeerConnections",
value: 0,
}, {
name: "ResourceFetchers",
value: 3,
}, {
name: "AdSubframes",
value: 0,
}, {
name: "DetachedScriptStates",
value: 2,
}, {
name: "ArrayBufferContents",
value: 0,
}, {
name: "LayoutCount",
value: 0,
}, {
name: "RecalcStyleCount",
value: 0,
}, {
name: "LayoutDuration",
value: 0,
}, {
name: "RecalcStyleDuration",
value: 0,
}, {
name: "DevToolsCommandDuration",
value: 0.000014,
}, {
name: "ScriptDuration",
value: 0,
}, {
name: "V8CompileDuration",
value: 0,
}, {
name: "TaskDuration",
value: 0.000016,
}, {
name: "TaskOtherDuration",
value: 0.000002,
}, {
name: "ThreadTime",
value: 0.000052,
}, {
name: "ProcessTime",
value: 0.076343,
}, {
name: "JSHeapUsedSize",
value: 874812,
}, {
name: "JSHeapTotalSize",
value: 2260992,
}, {
name: "FirstMeaningfulPaint",
value: 0,
}, {
name: "DomContentLoaded",
value: 896268.128472,
}, {
name: "NavigationStart",
value: 896267.363206,
}
]
まとめ
今回はPlaywrightとCDPを用いてWebページのメモリ使用量を計測する方法を紹介しました。
Webページのメモリ使用量を継続的にモニタリングすることは多くないですが、ぜひ試してみてください。
参考
- https://chromedevtools.github.io/devtools-protocol/
- https://playwright.dev/docs/api/class-cdpsession
一緒に二次元業界を盛り上げていきませんか?
株式会社viviONでは、フロントエンドエンジニアを募集しています。
また、フロントエンドエンジニアに限らず、バックエンド・SRE・スマホアプリなど様々なエンジニア職を募集していますので、ぜひ採用情報をご覧ください。