JavaScript で navigator.connection
を使ってネットワーク情報を取得する
Network Information API(wicg.github.io
)のブラウザ対応度合いが進んでいたのでまとめてみます。先にソースコードを見たい方はCodePen のデモ(codepen.io
)をどうぞ。
この API はネットワークの接続情報を取得できるもので、navigator.connection
でアクセスします。読み取り専用のプロパティは
type
effectiveType
downlink
downlinkMax
rtt
saveData
の6つあり、その他にイベントハンドラーとして onchange
が存在します。
type
ネットワーク接続のタイプを示します。 Android Chrome などの対応ブラウザで以下にアクセスすると、接続タイプによって "wifi"(Wi-Fi接続時) や "cellular"(LTE接続時など) などが返ってきます。すべての値のリストは仕様の4.1 Underlying connection technology(wicg.github.io
)を参照ください。
<script>
console.log(navigator.connection.type);
</script>
例えば動画配信において、この値によって画質を切り替えるといった活用方法が考えられますが、注意したいのはあくまで接続タイプの判定でしかないことで、たとえ Wi-Fi だからといって高速回線とは限らないことです。
effectiveType
先の type
は接続の種類、例えば従量課金の可能性があるかどうかといった判定に使えますが、一方で回線の速度を判定基準にしたいケースも多いと思います。そんなときはこちらの effectiveType
を使うことで、実効速度を取得することができます。
取得できる値は以下の4種類。
取得値 | 最小RTT(ms) | 最大ダウンロード速度(Kbps) |
---|---|---|
slow-2g | 2000 | 50 |
2g | 1400 | 70 |
3g | 270 | 700 |
4g | 0 | ∞ |
値から分かるように、2017年時点の一般的な状況から設定されたもののようです。仕様書にも
The absolute values provided above are based on real user measurement on Chrome on Android, as captured in April 2017. The user agent MAY update these values in the future to reflect changes in the measurement data.
wicg.github.io
)
と、将来的に値が追加・変更される可能性が記されています。
なので、「3G(相当)以上の回線速度だったら」という条件で
if (navigator.connection.effectiveType === '3g' || navigator.connection.effectiveType === '4g')
という記述をしてしまうと、将来的に 5G など更なる大容量回線が出現したときに意図とは異なる挙動になってしまう可能性が考えられるので、そういう場合は downlink
, rtt
など数値で取得できるプロパティの方を利用した方がいいのかもしれませんね。
downlink
, downlinkMax
, rtt
それぞれ有効帯域幅の推定値(Mb/s)、その上限値(Mb/s)、RTT値(ミリ秒)を示します。詳細な定義は仕様を参照ください(手抜き)。
-
6.3
downlinkMax
attribute(wicg.github.io
) -
6.5
downlink
attribute(wicg.github.io
) -
6.6
rtt
attribute(wicg.github.io
)
なお、downlinkMax
は Infinity (無限大)が返ってくる可能性があります。
saveData
ユーザーがブラウザの設定でデータ使用量の削減モードを有効にしているかどうかを true / false で返すものです。
Chrome にはデータセーバー機能(support.google.com
)があり(iOS版を除く)、デスクトップ版は拡張機能「データセーバー」(chrome.google.com
)をインストール、 Android 版は「設定」→「データセーバー」をオンにすることで有効化されます。するとHTTPリクエストヘッダーに Save-Data: on
が付与され、サーバー側で判定することができます。
Chrome 65 からは navigator.connection.saveData
が実装されたため[1]、この情報を JavaScript からも使用することができます。
change
イベント
接続情報が変更されたときに change
イベントが発火します。
navigator.connection.addEventListener('change', () => {
/* 接続情報が変更されたときの処理 */
});
ただし、 Android版 Firefox 56 は change
ではなく typechange
イベントを認識し、 Chrome や Android版 Edge は change
と typechange
を両方認識します。
下記のようにすることで、将来的に現行仕様どおり change
のみを認識するブラウザが出現しても問題ないようにすることができます。
const connectionInfo = navigator.connection;
if ('onchange' in connectionInfo) {
connectionInfo.addEventListener('change', () => {
/* 接続情報が変更されたときの処理 */
});
} else if ('ontypechange' in connectionInfo) {
connectionInfo.addEventListener('typechange', () => {
/* 接続情報が変更されたときの処理(Android版 Firefox 向け) */
});
}
デモ
navigator.connection
対応ブラウザで閲覧してください。
- CodePen のデモ(
codepen.io
)
以下に Android Chrome Dev 65 (データセーバー機能を有効にした状態)でアクセスした結果を置いておきます。テストは電波が充分に届く場所でスマートフォンを携帯電話回線に繋いだ状態から、 Wi-Fi をオンにし、さらに機内モードへ変更しています。
navigator.connection の値 |
携帯電話回線(LTE) | Wi-Fi | 機内モード |
---|---|---|---|
type |
cellular | wifi | none |
effectiveType |
4g | 4g | 4g |
downlink |
1.75 Mb/s | 2.7 Mb/s | 10 Mb/s |
downlinkMax |
100 Mb/s | Infinity Mb/s | 0 Mb/s |
rtt |
150 ms | 150 ms | 0 ms |
saveData |
true | true | true |
脚注
-
1.
2018年1月現在は Dev channel または Canary build で確認可能。Intent to Ship: saveData attribute in Network Information API(
groups.google.com
)あたりを参照。 ↩ 戻る