Chrome、Opera、Yandex の各ブラウザで使用可能な Save-Data
Client Hint リクエスト ヘッダーを使用すると、デベロッパーは、ブラウザでデータ節約モードにオプトインしているユーザーに、軽量かつ高速なアプリケーションを配信できます。
軽量のページの必要性
ウェブページを高速で軽量にすることで、より満足度の高いユーザー エクスペリエンスを提供し、コンテンツの理解と定着率を向上させ、コンバージョンと収益の増加を実現することには誰もが同意しています。Google の調査によると、「最適化したページの読み込みは元のページより 4 倍速く、使用するバイト数は 80% 少なくなります。ページの読み込みが非常に速いため、ページへのトラフィックも 50% 増加しました」
2G 接続の数はついに減少していますが、2015 年には 2G が依然として主要なネットワーク テクノロジーでした。3G および 4G ネットワークの普及と可用性は急速に拡大していますが、それに伴う所有コストとネットワークの制約は、何億人ものユーザーにとって依然として重要な要因です。
これらはページの最適化の強力な引数です。
プロキシ ブラウザやコード変換サービスなど、デベロッパーの関与なしにサイトの速度を向上させる別の方法があります。このようなサービスは広く普及していますが、画像とテキストの圧縮がシンプル(場合によっては許容できない)、安全なページ(HTTPS)を処理できない、検索結果からアクセスしたページのみを最適化できるなど、大きなデメリットがあります。これらのサービスの人気が高いということは、ウェブ デベロッパーが、高速で軽量なアプリケーションやページに対する高いユーザー需要に適切に対応できていないことを示しています。しかし その目標の達成は複雑で 難しい場合もあります
Save-Data
リクエスト ヘッダー
ごく簡単なテクニックの 1 つは、Save-Data
リクエスト ヘッダーを使用してブラウザをサポートすることです。ウェブページでこのヘッダーを識別することで、費用とパフォーマンスの制約があるユーザー向けに、最適化されたユーザー エクスペリエンスをカスタマイズして提供できます。
サポートされているブラウザ(下記)では、*データ節約モードを有効にすることができます。このモードでは、ページのレンダリングに必要なデータの量を減らすために、一連の最適化を適用する権限をブラウザに付与できます。この機能が公開またはアドバタイズされると、ブラウザは低解像度の画像をリクエストする、一部のリソースの読み込みを遅らせる、画像やテキスト リソースの圧縮などの他のコンテンツ固有の最適化を適用するサービスを介してリクエストをルーティングすることがあります。
ブラウザ サポート
- Chrome 49 以降では、モバイルで「データセーバー」オプションを、パソコンのブラウザで「データセーバー」拡張機能をユーザーが有効にした場合に、
Save-Data
をアドバタイズします。 - Opera 35+ は、ユーザーがパソコンで「Opera Turbo」モード、または Android ブラウザで「データ節約」オプションを有効にすると、
Save-Data
をアドバタイズします。 - パソコンまたはモバイル ブラウザでターボモードが有効になっている場合、Yandex 16.2 以降は
Save-Data
をアドバタイズします。
Save-Data
設定の検出
ユーザーに「軽量」なエクスペリエンスを提供するタイミングを判断するために、アプリケーションは Save-Data
Client Hint リクエスト ヘッダーを確認できます。このリクエスト ヘッダーは、転送コストが高い、接続速度が遅いなどの理由によるデータ使用量の削減に対するクライアントの設定を示します。
ユーザーがブラウザでデータ節約モードを有効にすると、ブラウザはすべての送信リクエスト(HTTP と HTTPS の両方)に Save-Data
リクエスト ヘッダーを追加します。この記事の執筆時点で、ブラウザはヘッダー(Save-Data: on
)で *オン トークンを 1 つだけアドバタイズしますが、これは今後、他のユーザー設定を示すために拡張される可能性があります。
また、JavaScript で Save-Data
がオンになっているかどうかを検出することもできます。
if ('connection' in navigator) {
if (navigator.connection.saveData === true) {
// Implement data saving operations here.
}
}
navigator
オブジェクト内に connection
オブジェクトが存在するかどうかを確認することは非常に重要です。このオブジェクトは Network Information API を表すため、このオブジェクトは Chrome、Chrome for Android、Samsung のインターネット ブラウザにのみ実装されています。そこから、navigator.connection.saveData
が true
と等しいかどうかを確認するだけで、その条件でデータ保存オペレーションを実装できます。
アプリケーションで Service Worker を使用している場合は、リクエスト ヘッダーを検査し、関連するロジックを適用してエクスペリエンスを最適化できます。または、Save-Data
リクエスト ヘッダーでアドバタイズされた設定を検索し、別のレスポンス(別のマークアップ、小さい画像や動画など)を返すこともできます。
導入のヒントとベスト プラクティス
Save-Data
を使用する場合は、それをサポートする UI デバイスを提供し、ユーザーがエクスペリエンスを簡単に切り替えられるようにします。たとえば、次のような情報が得られます。Save-Data
がサポートされていることをユーザーに通知し、使用を促す。- 適切なプロンプトや直感的なオン/オフのボタンやチェックボックスを使用して、ユーザーがモードを特定して選択できるようにします。
- データ節約モードを選択したら、そのモードを無効にしたり、必要に応じて全機能に戻すための方法を、わかりやすく明示します。
- 軽量のアプリケーションとは、さほど小さいアプリケーションではありません。重要な機能やデータが省略されているわけではなく、関連する費用とユーザー エクスペリエンスをよりよく理解しているだけです。例:
- フォト ギャラリー アプリでは、低解像度のプレビューを配信することや、コード負荷の少ないカルーセル メカニズムを使用することができます。
- 検索アプリケーションは、一度に返す結果の数を減らしたり、メディアを多用する結果の数を制限したり、ページのレンダリングに必要な依存関係の数を減らしたりすることがあります。
- ニュース向けのサイトでは、記事の表示数が少なくなったり、人気度の低いカテゴリが省略されたり、メディア プレビューが小さく表示されたりする場合があります。
Save-Data
リクエスト ヘッダーをチェックするためのサーバー ロジックを提供します。また、有効な場合は、代替の軽量なページ レスポンスを提供することを検討してください(必要なリソースと依存関係の数を減らす、より積極的なリソース圧縮を適用するなど)。Save-Data
ヘッダーに基づいて代替レスポンスを提供する場合は、これを Vary リスト(Vary: Save-Data
)に追加して、Save-Data
リクエスト ヘッダーが存在する場合にのみこのバージョンをキャッシュに保存して提供する必要があることをアップストリーム キャッシュに伝えます。詳しくは、キャッシュの操作に関するベスト プラクティスをご覧ください。
- Service Worker を使用している場合、アプリケーションは、
Save-Data
リクエスト ヘッダーの存在を確認するか、navigator.connection.saveData
プロパティの値を確認することで、データ節約オプションが有効になったことを検出できます。有効にする場合は、フェッチするバイト数を減らすようにリクエストを書き換えるか、すでにフェッチ済みのレスポンスを使用できるかどうかを検討してください。 - ユーザーの接続タイプやテクノロジーに関する情報など、他のシグナルで
Save-Data
を拡張することを検討してください(NetInfo API を参照)。たとえば、Save-Data
が有効になっていない場合でも、2G 接続のすべてのユーザーに軽量のエクスペリエンスを提供できます。逆に、ユーザーが「高速」の 4G 接続を使用しているからといって、ローミングなどでデータの保存に興味がないとは限りません。さらに、Save-Data
の存在をDevice-Memory
クライアント ヒントで拡張すると、メモリが限られているデバイスのユーザーに合わせてさらに適応できます。ユーザー デバイスのメモリもnavigator.deviceMemory
クライアント ヒントでアドバタイズされます。
レシピ
Save-Data
で実現できることは、考えられる範囲に限られます。何が可能になるかを理解するため、いくつかのユースケースを見ていきましょう。この記事を読みながら、独自のユースケースを思いつくかもしれません。自由に実験して、何ができるかを確認しましょう。
サーバーサイドのコードで Save-Data
を確認しています
Save-Data
の状態は JavaScript で navigator.connection.saveData
プロパティを介して検出できるものですが、サーバー側で検出するほうが望ましい場合もあります。JavaScript の実行が失敗する場合があります。さらに、サーバーサイドでの検出は、クライアントに送信される前にマークアップを変更する唯一の方法です。これは、Save-Data
の最も有益なユースケースのいくつかに関係します。
サーバー側のコードで Save-Data
ヘッダーを検出するための特定の構文は、使用する言語によって異なりますが、基本的な考え方はどのアプリケーション バックエンドでも同じです。たとえば PHP では、リクエスト ヘッダーは HTTP_
で始まるインデックスの $_SERVER
スーパーグローバル配列に格納されます。つまり、次のように $_SERVER["HTTP_SAVE_DATA"]
変数の存在と値を確認することで、Save-Data
ヘッダーを検出できます。
// false by default.
$saveData = false;
// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
// `Save-Data` detected!
$saveData = true;
}
マークアップがクライアントに送信される前にこのチェックを配置すると、$saveData
変数に Save-Data
状態が含まれ、ページの任意の場所で使用できるようになります。このメカニズムを図解しながら、このメカニズムを使用してユーザーに送信するデータの量を制限する方法の例をいくつか見てみましょう。
高解像度の画面用に低解像度の画像を配信する
ウェブ上の画像の一般的なユースケースでは、2 つのセットで画像を提供します。1 つは「標準」画面(1 倍)用の画像、もう 1 つは高解像度画面(2 倍速)用の 2 倍の画像(2 倍)です。Retina ディスプレイなど)。このような高解像度の画面は、必ずしもハイエンド デバイスに限らず、次第に一般的になってきています。アプリの軽量化が望ましい場合は、大きな(2 倍)のバリエーションではなく、低解像度(1 倍)の画像をこれらの画面に送信するほうが賢明な場合があります。Save-Data
ヘッダーが存在する場合にこれを実現するには、クライアントに送信するマークアップを変更します。
if ($saveData === true) {
// Send a low-resolution version of the image for clients specifying `Save-Data`.
?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
// Send the usual assets for everyone else.
?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}
このユースケースは、送信データの量を減らしてほしいという要望に応えるためにどれほどの労力がかからないかを示す最適な例です。バックエンドでマークアップを変更したくない場合は、Apache の mod_rewrite
などの URL 書き換えモジュールを使用して同じ結果を得ることもできます。比較的少ない構成でこれを実現する方法の例があります。
<html>
要素にクラスを追加するだけで、この概念を CSS の background-image
プロパティにも拡張できます。
<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">
ここから、CSS の <html>
要素の save-data
クラスをターゲットにして、画像の配信方法を変更できます。上記の HTML の例のように、低解像度の背景画像を高解像度の画面に送信したり、特定のリソースを完全に省略したりできます。
重要でない画像は除外
ウェブ上にある画像コンテンツの中には、単に重要でないものが存在します。このような画像はコンテンツの面白さには欠かせませんが、従量制データプランから可能な限り絞ろうとしている人には好ましくありません。Save-Data
の最も単純なユースケースでは、前述の PHP 検出コードを使用して、重要でない画像のマークアップを完全に省略できます。
<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
// Only send this image if `Save-Data` hasn't been detected.
?><img src="meme.jpg" alt="One does not simply consume data."><?php
}
次の図に示すように、この手法には明らかな効果があります。
もちろん、画像を省略することだけではありません。Save-Data
を使用して、特定の書体など、重要でない他のリソースの送信を避けることもできます。
必須ではないウェブフォントは除外
ウェブフォントは通常、ページの合計ペイロードの大部分を画像ほど占めるものではありませんが、ウェブフォントは依然として広く使用されています。また、大量のデータを消費しません。さらに、ブラウザによるフォントの取得とレンダリングの方法は、FOIT、FOUT、ブラウザのヒューリスティックなどの概念により、レンダリングを微妙に異なるものにするため、想像するよりも複雑です。
ユーザー エクスペリエンスの無駄を省くために、必須ではないウェブフォントを除外したほうがよい場合もあります。Save-Data
を使用すると、この作業をかなり簡単に行うことができます。
たとえば、サイトに Google Fonts の Fira Sans を含めているとします。Fira Sans は優れたボディコピー フォントですが、データを保存しようとするユーザーにとってはそれほど重要ではないかもしれません。Save-Data
ヘッダーが存在する場合に save-data
のクラスを <html>
要素に追加することで、最初は重要でない書体を呼び出し、Save-Data
ヘッダーが存在する場合はそれを無効にするスタイルを作成できます。
/* Opt into web fonts by default. */
p,
li {
font-family: 'Fira Sans', 'Arial', sans-serif;
}
/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
font-family: 'Arial', sans-serif;
}
この方法を使用すると、Google Fonts の <link>
スニペットをそのまま使用できます。ブラウザは、まず DOM にスタイルを適用し、次にスタイルシート内のリソースを呼び出す HTML 要素があるかどうかをチェックすることで、CSS リソース(ウェブフォントを含む)を投機的に読み込むためです。Save-Data
がオンの場合、スタイル付き DOM は呼び出されないため、Fira Sans は読み込まれません。その代わりに Arial が動作します。Fira Sans ほど便利ではありませんが、データプランを伸ばそうとしているユーザーには向いています。
まとめ
Save-Data
ヘッダーは微妙なニュアンスはありません。オンかオフかがあり、理由に関係なく、その設定に基づいて適切なエクスペリエンスを提供する負担をアプリが負います。
たとえば、接続状況が良くない状態であっても、アプリのコンテンツや機能が失われる疑いがある場合、一部のユーザーはデータ節約モードを許可しないことがあります。逆に、接続状況が良好な場合でも、ページのサイズをできる限り小さくしてシンプルにするために、この機能を有効にするユーザーもいます。アプリでは、明示的なユーザー アクションによって明確に示されるまで、ユーザーが完全で無制限のエクスペリエンスを求めていると想定することをおすすめします。
サイト所有者およびウェブ デベロッパーとして、Google のコンテンツ管理の責任を担って、データと費用に制約があるユーザーのユーザー エクスペリエンスを向上させましょう。
Save-Data
の詳細と優れた実例については、ユーザーをサポートするSave Data
をご覧ください。