タイトル: System Information API
SEOタイトル: Web System Information API 完全ガイド
| この記事の要点 |
|
System Information API とは
Web ブラウザから JavaScript 経由でデバイスや OS の状態を取得するための一連の API のこと。単一の仕様ではなく、W3C が個別仕様として標準化した小さな API の集合を指します。
主要 API 一覧
| API | 取れる情報 | 状態 |
|---|---|---|
| Battery Status API | バッテリー残量、充電中か | 廃止 (Chrome は削除) |
| Network Information API | 回線種別 (4g/wifi)、推定帯域 | Chrome/Edge のみ |
| Device Memory API | RAM 容量 (GB) | Chrome/Edge |
navigator.hardwareConcurrency | 論理 CPU コア数 | 全主要ブラウザ |
| Geolocation API | 緯度経度、精度 | 全主要ブラウザ (要許可) |
| Vibration API | バイブレーション実行 | モバイル中心 |
| Screen Orientation API | 画面向き (portrait / landscape) | 全主要ブラウザ |
| Gamepad API | ゲームパッド入力 | 全主要ブラウザ |
navigator.userAgentData | UA-CH (ブラウザ/OS/モバイル判定) | Chrome/Edge |
Network Information API
// 回線情報取得
const conn = navigator.connection ||
navigator.mozConnection ||
navigator.webkitConnection;
if (conn) {
console.log(conn.effectiveType); // "4g" / "3g" / "2g" / "slow-2g"
console.log(conn.downlink); // Mbps (例: 10)
console.log(conn.rtt); // ms (例: 50)
console.log(conn.saveData); // データセーバー ON か (boolean)
// 変化を監視
conn.addEventListener('change', () => {
console.log('回線変化:', conn.effectiveType);
});
}
// 利用例: 回線が遅ければ画質を落とす
function selectVideoQuality() {
if (!navigator.connection) return 'high';
const t = navigator.connection.effectiveType;
if (t === '4g') return 'high';
if (t === '3g') return 'medium';
return 'low';
}
Device Memory API
// RAM 容量 (GB) を取得。0.25 / 0.5 / 1 / 2 / 4 / 8 のいずれか
if ('deviceMemory' in navigator) {
console.log(navigator.deviceMemory + ' GB');
// 低スペック端末向けに UI を簡素化
if (navigator.deviceMemory < 2) {
document.body.classList.add('lite-mode');
}
}
// HTTP リクエストヘッダにも乗る (UA Client Hints 経由)
// Device-Memory: 4
CPU コア数
// 論理コア数 (ハイパースレッディング含む)
console.log(navigator.hardwareConcurrency); // 例: 8
// Web Worker の並列度を決めるのに便利
const workerCount = Math.min(navigator.hardwareConcurrency || 4, 8);
const workers = [];
for (let i = 0; i < workerCount; i++) {
workers.push(new Worker('heavy.js'));
}
Battery Status API (廃止)
// ❌ 仕様としては存在するが Chrome 等は削除済 (フィンガープリンティング懸念)
if ('getBattery' in navigator) {
navigator.getBattery().then(battery => {
console.log(battery.level); // 0.0-1.0
console.log(battery.charging); // true/false
console.log(battery.chargingTime); // 秒 (Infinity の場合あり)
console.log(battery.dischargingTime); // 秒
});
}
// 代替: PWA でバッテリー前提の制御をしたい場合は、
// ユーザに動作モード (省電力 / 通常) を選んでもらう方が現実的
Geolocation API
navigator.geolocation.getCurrentPosition(
(pos) => {
console.log(pos.coords.latitude); // 緯度
console.log(pos.coords.longitude); // 経度
console.log(pos.coords.accuracy); // 精度 (m)
console.log(pos.coords.altitude); // 高度 (m) (取れないと null)
console.log(pos.coords.heading); // 方角 (度) (移動中のみ)
console.log(pos.coords.speed); // 速度 (m/s)
},
(err) => console.error(err.message),
{ enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }
);
// 継続的な位置監視
const watchId = navigator.geolocation.watchPosition(
(pos) => console.log(pos),
(err) => console.error(err)
);
navigator.geolocation.clearWatch(watchId);
Screen Orientation API
// 現在の向き
const o = screen.orientation;
console.log(o.type); // "portrait-primary" / "landscape-primary" 等
console.log(o.angle); // 0 / 90 / 180 / 270
// 変化を監視
o.addEventListener('change', () => {
console.log('新しい向き:', o.type);
});
// フルスクリーンで向きを固定 (要 fullscreen)
o.lock('landscape-primary').catch(err => console.error(err));
User-Agent Client Hints (新世代 UA)
従来の navigator.userAgent 文字列はフィンガープリンティングや嘘 UA の温床だったため、構造化されたUA-CHに置換が進んでいます:
// 同期で取れる軽量情報
console.log(navigator.userAgentData.brands);
// [{ brand: "Chromium", version: "120" }, { brand: "Google Chrome", version: "120" }]
console.log(navigator.userAgentData.mobile); // true / false
console.log(navigator.userAgentData.platform); // "Windows" / "macOS" / "Android" 等
// 詳細情報は非同期 (許可制)
navigator.userAgentData.getHighEntropyValues([
'platformVersion', 'architecture', 'bitness', 'model', 'fullVersionList'
]).then(ua => {
console.log(ua.platformVersion); // "10.0.0"
console.log(ua.architecture); // "x86" / "arm"
console.log(ua.bitness); // "64"
console.log(ua.model); // モバイル端末モデル
});
HTTP リクエストヘッダ経由 (Client Hints)
# サーバ側から要求
Accept-CH: Sec-CH-UA-Platform, Sec-CH-UA-Mobile, Device-Memory, DPR
# クライアントが次回送るヘッダ
Sec-CH-UA: "Chromium";v="120", "Google Chrome";v="120"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"
Device-Memory: 8
DPR: 2.0
プライバシー配慮
- HTTPS 必須: ほとんどの Information API は HTTP では動作しない
- 許可ダイアログ: Geolocation は明示許可、Battery は完全廃止傾向
- フィンガープリンティング対策: 値を丸める (Device Memory が 0.25/0.5/1/2/4/8 の限定値) / Permissions Policy で制御
- サードパーティ iframe では制限:
allow="geolocation"属性必須
Permissions Policy で API 利用を制御
# サーバヘッダで子フレームの利用を制限
Permissions-Policy: geolocation=(self), camera=(), microphone=(), battery=()<!-- iframe で許可を委譲 -->
<iframe src="https://maps.example.com"
allow="geolocation; camera; microphone"></iframe>
ローカルストレージとの違い
| 機能 | System Information API | localStorage |
|---|---|---|
| 取得情報 | OS / デバイスの現在状態 | Web アプリが保存したデータ |
| 永続性 | 都度取得 | ブラウザクリアまで残る |
| 許可 | API ごとに異なる | 許可不要 (同一オリジン) |
| 容量 | 該当せず | 約 5-10 MB |
FAQ
Q: 電池残量を表示できないと困る
A: PWA でユーザに「省電力モード」を手動 ON/OFF してもらう実装に変えるのが現実的。Battery API は復活しません。
Q: ユーザの OS バージョンが知りたい
A: navigator.userAgentData.getHighEntropyValues(['platformVersion'])。許可制 (UA-CH) で取得できます。
Q: iOS Safari で navigator.connection が undefined
A: Safari は未対応。回線判定機能は Chromium 系限定と考え、フォールバック設計を。