この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: System Information API
SEOタイトル: Web System Information API 完全ガイド

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>System Information API</strong>はブラウザから OS / デバイス情報を取得する Web API 群の総称</li><li>主要 API: <strong>Battery Status</strong> / <strong>Network Information</strong> / <strong>Device Memory</strong> / <strong>navigator.hardwareConcurrency</strong></li><li>プライバシー強化により<strong>Battery Status は廃止</strong>、UA 文字列は <strong>User-Agent Client Hints (<code>navigator.userAgentData</code>)</strong>に置換中</li><li>Geolocation / Vibration / Screen Orientation / Gamepad なども広義の System Information</li><li>使う前に<strong>機能検出</strong> (<code>if ("connection" in navigator)</code>) と<strong>HTTPS 必須</strong>に注意</li></ul></td></tr></table>
<h2>System Information API とは</h2>

<p>Web ブラウザから JavaScript 経由で<strong>デバイスや OS の状態</strong>を取得するための一連の API のこと。単一の仕様ではなく、W3C が個別仕様として標準化した小さな API の集合を指します。</p>

<h2>主要 API 一覧</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>API</th><th>取れる情報</th><th>状態</th></tr></thead>
<tbody>
<tr><td>Battery Status API</td><td>バッテリー残量、充電中か</td><td><strong>廃止</strong> (Chrome は削除)</td></tr>
<tr><td>Network Information API</td><td>回線種別 (4g/wifi)、推定帯域</td><td>Chrome/Edge のみ</td></tr>
<tr><td>Device Memory API</td><td>RAM 容量 (GB)</td><td>Chrome/Edge</td></tr>
<tr><td><code>navigator.hardwareConcurrency</code></td><td>論理 CPU コア数</td><td>全主要ブラウザ</td></tr>
<tr><td>Geolocation API</td><td>緯度経度、精度</td><td>全主要ブラウザ (要許可)</td></tr>
<tr><td>Vibration API</td><td>バイブレーション実行</td><td>モバイル中心</td></tr>
<tr><td>Screen Orientation API</td><td>画面向き (portrait / landscape)</td><td>全主要ブラウザ</td></tr>
<tr><td>Gamepad API</td><td>ゲームパッド入力</td><td>全主要ブラウザ</td></tr>
<tr><td><code>navigator.userAgentData</code></td><td>UA-CH (ブラウザ/OS/モバイル判定)</td><td>Chrome/Edge</td></tr>
</tbody>
</table>

<h2>Network Information API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// 回線情報取得
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(&apos;change&apos;, () => {
    console.log(&apos;回線変化:&apos;, conn.effectiveType);
  });
}

// 利用例: 回線が遅ければ画質を落とす
function selectVideoQuality() {
  if (!navigator.connection) return &apos;high&apos;;
  const t = navigator.connection.effectiveType;
  if (t === &apos;4g&apos;) return &apos;high&apos;;
  if (t === &apos;3g&apos;) return &apos;medium&apos;;
  return &apos;low&apos;;
}</code></pre>
<h2>Device Memory API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// RAM 容量 (GB) を取得。0.25 / 0.5 / 1 / 2 / 4 / 8 のいずれか
if (&apos;deviceMemory&apos; in navigator) {
  console.log(navigator.deviceMemory + &apos; GB&apos;);

  // 低スペック端末向けに UI を簡素化
  if (navigator.deviceMemory < 2) {
    document.body.classList.add(&apos;lite-mode&apos;);
  }
}

// HTTP リクエストヘッダにも乗る (UA Client Hints 経由)
// Device-Memory: 4</code></pre>
<h2>CPU コア数</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// 論理コア数 (ハイパースレッディング含む)
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(&apos;heavy.js&apos;));
}</code></pre>
<h2>Battery Status API (廃止)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ 仕様としては存在するが Chrome 等は削除済 (フィンガープリンティング懸念)
if (&apos;getBattery&apos; 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 でバッテリー前提の制御をしたい場合は、
// ユーザに動作モード (省電力 / 通常) を選んでもらう方が現実的</code></pre>
<h2>Geolocation API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">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);</code></pre>
<h2>Screen Orientation API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// 現在の向き
const o = screen.orientation;
console.log(o.type);   // "portrait-primary" / "landscape-primary" 等
console.log(o.angle);  // 0 / 90 / 180 / 270

// 変化を監視
o.addEventListener(&apos;change&apos;, () => {
  console.log(&apos;新しい向き:&apos;, o.type);
});

// フルスクリーンで向きを固定 (要 fullscreen)
o.lock(&apos;landscape-primary&apos;).catch(err => console.error(err));</code></pre>
<h2>User-Agent Client Hints (新世代 UA)</h2>

<p>従来の <code>navigator.userAgent</code> 文字列はフィンガープリンティングや嘘 UA の温床だったため、構造化された<strong>UA-CH</strong>に置換が進んでいます:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// 同期で取れる軽量情報
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([
  &apos;platformVersion&apos;, &apos;architecture&apos;, &apos;bitness&apos;, &apos;model&apos;, &apos;fullVersionList&apos;
]).then(ua => {
  console.log(ua.platformVersion); // "10.0.0"
  console.log(ua.architecture);    // "x86" / "arm"
  console.log(ua.bitness);         // "64"
  console.log(ua.model);           // モバイル端末モデル
});</code></pre>
<h2>HTTP リクエストヘッダ経由 (Client Hints)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-http"># サーバ側から要求
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</code></pre>
<h2>プライバシー配慮</h2>

<ul>
<li><strong>HTTPS 必須</strong>: ほとんどの Information API は HTTP では動作しない</li>
<li><strong>許可ダイアログ</strong>: Geolocation は明示許可、Battery は完全廃止傾向</li>
<li><strong>フィンガープリンティング対策</strong>: 値を丸める (Device Memory が 0.25/0.5/1/2/4/8 の限定値) / Permissions Policy で制御</li>
<li><strong>サードパーティ iframe では制限</strong>: <code>allow="geolocation"</code> 属性必須</li>
</ul>

<h2>Permissions Policy で API 利用を制御</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-http"># サーバヘッダで子フレームの利用を制限
Permissions-Policy: geolocation=(self), camera=(), microphone=(), battery=()</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- iframe で許可を委譲 -->
<iframe src="https://maps.example.com"
        allow="geolocation; camera; microphone"></iframe></code></pre>
<h2>ローカルストレージとの違い</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>機能</th><th>System Information API</th><th>localStorage</th></tr></thead>
<tbody>
<tr><td>取得情報</td><td>OS / デバイスの<strong>現在状態</strong></td><td>Web アプリが保存したデータ</td></tr>
<tr><td>永続性</td><td>都度取得</td><td>ブラウザクリアまで残る</td></tr>
<tr><td>許可</td><td>API ごとに異なる</td><td>許可不要 (同一オリジン)</td></tr>
<tr><td>容量</td><td>該当せず</td><td>約 5-10 MB</td></tr>
</tbody>
</table>

<h2>FAQ</h2>

<p><strong>Q: 電池残量を表示できないと困る</strong><br />
A: PWA でユーザに「省電力モード」を手動 ON/OFF してもらう実装に変えるのが現実的。Battery API は復活しません。</p>

<p><strong>Q: ユーザの OS バージョンが知りたい</strong><br />
A: <code>navigator.userAgentData.getHighEntropyValues(['platformVersion'])</code>。許可制 (UA-CH) で取得できます。</p>

<p><strong>Q: iOS Safari で <code>navigator.connection</code> が undefined</strong><br />
A: Safari は未対応。回線判定機能は Chromium 系限定と考え、フォールバック設計を。</p>