このページでわかること
ページを開くと、スクリプトが約60個の小さなチェックを現在のブラウザに対して実行し、機能ごとに対応しているかどうかを一覧にします。結果はJavaScriptの言語機能、CSS、グラフィックス、メディアとコーデック、ストレージ、ネットワーク、デバイスAPI、セキュリティ、UIの各グループに分かれ、上部のまとめには対応している機能の数が出ます。
どのチェックも、ブラウザが目に見える動作をしないまま答えられる問いかけです。JavaScriptでは多くの場合、structuredCloneやPromise.withResolversのようなものが存在するか、あるいはvフラグ付きの正規表現のような新しい構文を受け付けるかを確かめます。CSSの行はCSS.supports()を通し、スタイルエンジンがプロパティや値、:has()のようなセレクターを理解するかを確認します。コーデックの行には、canPlayType()とMedia Sourceのチェックに対するブラウザ自身の答えを使います。
許可のダイアログを開いたり、デバイスの選択画面を出したり、ネットワーク越しに何かを送ったりするチェックはありません。Web Bluetooth、WebUSB、Web NFCのようなハードウェア系のAPIで「はい」と出るのは、ブラウザがそのインターフェースを公開しているという意味です。デバイスが接続されている、あるいは利用が許可されていることまでは示しません。
使い方
- 調べたいブラウザ、プロファイル、端末そのものでこのページを開きます。チェックは自動で始まります。
- まとめの件数を見てから、各グループで「いいえ」になっている行を探します。
- メディアのグループでは、「一部」と出たコーデックに注目します。ブラウザがprobablyではなくmaybeと答えたという意味です。
- 「テキストとしてコピー」ボタンを押すと、リスト全体をクリップボードへ写せます。
- 不具合報告や問い合わせ、チャットに貼り付け、ブラウザのバージョンとOSがまだ書かれていなければ書き足します。
テストは、問題が起きているのと同じウィンドウで行ってください。拡張機能や企業のポリシー、試験運用中のフラグによって、個々の機能がオンにもオフにもなります。
2つの行は、ブラウザだけでなくページ側の事情も映しています。セキュアコンテキストかどうかはページの読み込み方で、クロスオリジン分離はサーバーが送るヘッダーで決まるため、別のサイトではこの2行の答えが変わることがあります。
こんな場面で使えます
- サポート対応。「大きなファイルを保存しようとしても何も起きない」という問い合わせが来たら、このページを開いてコピーしたリストを貼ってもらいましょう。Origin Private File SystemやFetchのストリームの行が欠けていれば、1回の返信で決着がつくこともあります。
- 再生できない動画。あるノートPCでは再生できるクリップが、別のノートPCでは黒い画面のまま止まります。そんなときは両方の端末でHEVCとAV1の行を比べます。「いいえ」や「一部」なら、H.264版かVP9版もあわせて配信したほうがよいというサインです。
- 採用する機能の見極め。
:has()やコンテナクエリ、CSSのネストに頼る前に、ユーザーがまだ使っている最も古いブラウザを使い、このページを開いてみましょう。店頭の端末やスマートテレビも忘れずに確認します。 - アプリ内ブラウザ。チャットアプリやSNSアプリの中でタップしたリンクは、組み込みのWebビューで開くことがよくあります。その経路でこのページを開けば、Webビューが何に対応しているかがわかります。同じスマホのSafariやChromeとは結果が異なる場合があります。
- ハードウェアを扱うプロジェクト。Webページからマイコンに書き込めます、キーボードを設定できます、と案内する前に、Web Serial、WebUSB、WebHIDの行をユーザーに確認してもらいましょう。主要ブラウザの中にも、これらのインターフェースをまったく備えていないものがあります。
機能検出とユーザーエージェント判定の違い
以前は、User-Agent文字列を読み取ってブラウザ名から何ができるかを推測するのが一般的でした。このやり方は、決まったパターンで破綻します。Chromium系のブラウザは、ユーザーエージェントの文字列の大部分が共通です。iPhone版のChromeはCriOSというトークンを含みますが、通常はWebKitで描画するため、ここに並ぶ行のほとんどではSafariと同じ振る舞いをします。Chromeは文字列に含まれるバージョンやプラットフォームの詳細の一部を固定しており、そもそも文字列は数クリックで誰でも変えられます。
機能検出は、実際に動いているブラウザに直接たずねます。そのため、プログレッシブエンハンスメントも簡単になります。どこでも動く基本形を作り、チェックに通った環境にだけ、より良い方法を付け足せばよいのです。
if ('share' in navigator) {
shareButton.hidden = false; // OS標準の共有シート
} else {
copyLinkButton.hidden = false; // シンプルな代替手段
}
@supports (container-type: inline-size) {
.card-list { container-type: inline-size; }
}
コーデックも考え方は同じです。プレーヤーはvideo.canPlayType('video/mp4; codecs="av01.0.05M.08"')を呼び出し、答えが空文字列ならH.264のソースに切り替えればよいのです。空文字列はブラウザにとっての「いいえ」で、それ以外に返ってくるのはmaybeとprobablyだけです。
同じブラウザでも答えが変わる理由
ハードウェアとOS
多くの行は、ブラウザのビルド以外の要素にも左右されます。HEVCの再生にはハードウェアデコーダーやOS側のコーデック対応が必要なことが多く、同じバージョンのブラウザでも2台のノートPCで答えが食い違うことがあります。SafariがAV1に対応すると答えるのは、AV1のハードウェアデコーダーを積んだApple製デバイスだけです。WebGPUはOSによって提供開始の時期がずれており、グラフィックスドライバーがブロックリストに載っていると、ブラウザがWebGLを無効にすることもあります。オープンソースのブラウザビルドの中には、H.264やAACのようなライセンスが必要なコーデックを含まないものもあります。
セキュアコンテキスト
多くのAPIは、セキュアコンテキストの中にしか存在しません。httpsで配信されるページと、http://localhostやhttp://127.0.0.1のようなローカルアドレスがこれに当たります。Service Worker、非同期クリップボードAPI、Web Authentication、Web Share、Screen Wake Lock、WebGPU、各種デバイスAPIがこのグループです。同じサイトをLAN内のアドレスから暗号化なしのhttpで読み込むと、これらのオブジェクトはブロックされるのではなく、最初から存在しない状態になります。そのため、localhostでは動いていた機能がテストサーバーでは見当たらなくなる場合があります。いまの状態はwindow.isSecureContextで確認できます。SharedArrayBufferを使えるようにするクロスオリジン分離には、さらにCross-Origin-Opener-PolicyとCross-Origin-Embedder-Policyのレスポンスヘッダーが必要です。
このリスト自体もフィンガープリントになる
結果はブラウザ、バージョン、OS、ハードウェアによって変わるため、答えの並び全体を見れば、訪問者の環境をかなり絞り込めます。フィンガープリントを取るスクリプトが、canvasの描画やインストール済みフォントの調査と並べて同種のチェックを実行するのはそのためです。このページはチェックを手元で実行して何も送らず、iseeu.ccもIPアドレスや調べた内容のログを残しませんが、どんなサイトでも、結果を見せないまま同等のコードを実行できます。公開のIssueトラッカーにリストを貼る前には、ほかのシステム情報を共有するときと同じように扱ってください。
よくいただく質問
カメラやBluetooth、通知の許可を求められることはありますか?
ありません。どのチェックも、APIが存在するか、またはブラウザが対応をうたっているかを確かめるだけです。許可のダイアログやデバイスの選択画面を開くメソッドは一切呼び出さず、データがブラウザの外へ出ることもありません。たとえば「Notifications API」の行は、そのAPIがあるかどうかを見るだけで、通知を表示してよいかをたずねるものではありません。また、iseeu.ccはCookieを使わず、IPアドレスや調べた内容のログも残しません。
ここでは「はい」と出るのに、自分のサイトではその機能が動かないのはなぜですか?
ここでの「はい」は、ブラウザがそのAPIを公開している、またはその構文を理解すると答えた、という意味にとどまります。実際に使う場面では失敗することがあります。サイトが暗号化なしのhttpで読み込まれてセキュアコンテキスト限定のAPIが消えている、許可が拒否された、ポリシーでデバイスが禁止されている、WebGPUが使えるグラフィックスアダプターを見つけられない、といったケースです。コーデックの行はブラウザの申告をそのまま映したものなので、珍しいプロファイルや解像度ではデコードに失敗することもあります。
コーデックの行に出る「一部」とはどういう意味ですか?
canPlayTypeメソッドが「はい」と断言することはありません。再生できる見込みがかなり高いときはprobably、形式は認識できても実際に試すまで確かではないときはmaybe、再生できないときは空文字列を返します。このページではmaybeを「一部」として表示しています。「一部」と出たコーデックに頼る前に、自分のファイルで実際に再生テストをしてください。
同じバージョンのブラウザなのに、同僚の画面と答えが一致しないのはどうしてですか?
いくつかの行は、ブラウザのバージョンよりもOSやハードウェアに左右されるからです。HEVCやAV1はハードウェアデコーダーに頼ることが多く、WebGPUが使えるかどうかはプラットフォームやグラフィックスドライバーで変わり、ライセンスが必要なコーデックを含まずに配布されるビルドもあります。拡張機能、企業のポリシー、試験運用中のフラグ、プライベートウィンドウによって、個々の答えが変わることもあります。お互いにコピーしたリストを並べて見比べるのが、違いを見つけるいちばんの近道です。
httpで開くと、一部の機能が使えなくなるのはなぜですか?
比較的新しいAPIの多くを、ブラウザはセキュアコンテキスト、つまりhttpsで読み込んだページか、localhostのようなローカルアドレスのページでしか公開しないからです。暗号化なしのhttpのページでは、navigator.serviceWorkerやnavigator.clipboardといったオブジェクトがそもそもundefinedになります。これは意図された動作です。これらのAPIはデバイスや認証情報、長く動き続けるバックグラウンドのコードに手が届く一方、暗号化されていないページは通信の途中で書き換えられるおそれがあります。本番と同じ挙動を確かめたいなら、テスト環境もhttpsで配信してください。
このリストから、自分が誰なのかを特定されることはありますか?
対応機能のリストだけで表せるのは、あなた自身ではなく、ブラウザやOS、ハードウェアの組み合わせです。ただし、画面サイズやインストール済みのフォント、canvasの描画結果といったほかの手がかりと組み合わせると、ブラウザフィンガープリントの一部となり、再び訪れた人を見分ける材料になりえます。このページはチェックを手元で実行して何も送信しませんが、ほかのサイトが同じテストを黙って実行することはできます。注意すべきなのはこのリスト単体ではなく、ほかの情報と組み合わさったときです。
機能の有無は、User-Agent文字列を見て判断したほうがよいのでは?
機能を使ってよいかの判断には向きません。User-Agent文字列はChromium系のブラウザ同士でほぼ共通で、Chromeでは中身が削られており、簡単に書き換えられます。さらにiPhoneでは、ChromeもFirefoxも通常はWebKitで描画するため、文字列からの推測が外れます。機能を直接テストすれば、実際に動いているブラウザについての答えが得られます。とはいえ、不具合報告で正確なブラウザのバージョンを書き残すには、User-Agent文字列も役に立ちます。
この結果をサポート窓口や開発者に渡したいときは?
問題が起きているのと同じブラウザ、プロファイル、端末でこのページを開き、「テキストとしてコピー」を押して、問い合わせや不具合報告、チャットに貼り付けてください。ブラウザのバージョンとOSが書かれていなければ、あわせて書き添えます。公開のIssueトラッカーに貼る前には、ほかのシステム情報を共有するときと同じように扱ってください。
検出結果は、ブラウザが公開している、または対応を申告している内容です。サイトが実際にその機能を使おうとした時点で、ポリシーやハードウェアの不足、拒否された許可のために使えないこともあります。