データの保存で高速かつ軽量なアプリケーションを提供

Chrome、Opera、Yandex ブラウザで使用できる Save-Data クライアント ヒント リクエスト ヘッダーを使用すると、ブラウザでデータ節約モードを有効にしているユーザーに、より軽量で高速なアプリケーションを配信できます。

軽量版の必要性

Weblight の統計情報

ウェブページが軽くて読みやすくなるほど、ユーザー エクスペリエンスが向上し、コンテンツの理解と定着率が上がり、コンバージョンと収益の増加につながることは誰もが同意見です。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 クライアント ヒント リクエスト ヘッダーを確認します。このリクエスト ヘッダーは、転送コストが高い、接続速度が遅いなどの理由でデータ使用量を削減することをクライアントが好むことを示しています。

ユーザーがブラウザで省データ モードを有効にすると、ブラウザはすべての送信リクエスト(HTTP と HTTPS の両方)に Save-Data リクエスト ヘッダーを追加します。このドキュメントの作成時点で、ブラウザはヘッダー(Save-Data: on)で 1 つの *on- トークンのみをアドバタイズしますが、将来的には他のユーザー設定を示すために拡張される可能性があります。

また、JavaScript で Save-Data がオンになっているかどうかを検出することもできます。

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

navigator オブジェクト内に connection オブジェクトが存在するかどうかを確認することが重要です。これは Network Information API を表します。この API は Chrome、Chrome for Android、Samsung インターネット ブラウザにのみ実装されます。そこから、navigator.connection.saveDatatrue と等しいかどうかを確認するだけでよく、その条件でデータ保存オペレーションを実装できます。

データセーバー拡張機能とともに Chrome のデベロッパー ツールに表示される Save-Data ヘッダー
デスクトップ版 Chrome でデータセーバー拡張機能を有効にします。

アプリケーションで Service Worker を使用している場合は、リクエスト ヘッダーを検査し、関連するロジックを適用してエクスペリエンスを最適化できます。または、Save-Data リクエスト ヘッダーでアドバタイズされた設定を探して、代替レスポンス(異なるマークアップ、サイズの小さい画像や動画など)を返すこともできます。

導入のヒントとベスト プラクティス

  1. Save-Data を使用する場合は、それをサポートする UI デバイスをいくつか用意し、ユーザーが簡単にエクスペリエンスを切り替えられるようにします。たとえば、次のような情報が得られます。
    • Save-Data がサポートされていることをユーザーに通知し、使用を推奨します。
    • 適切なプロンプトと直感的なオン/オフボタンやチェックボックスを使用して、ユーザーがモードを識別して選択できるようにします。
    • データ節約モードが選択されているときは、そのモードを無効にし、必要に応じて完全なエクスペリエンスに戻すための簡単でわかりやすい方法を提示します。
  2. 軽量のアプリケーションは、小さいアプリケーションではないことに注意してください。重要な機能やデータを省略するのではなく、発生する費用とユーザー エクスペリエンスをより意識するだけです。例:
    • フォト ギャラリー アプリでは、プレビューの解像度を低くしたり、コードを多用しないカルーセル メカニズムを使用したりすることがあります。
    • 検索アプリケーションは、一度に返す結果の数を減らしたり、メディア使用量の多い結果の数を制限したり、ページのレンダリングに必要な依存関係の数を減らしたりすることがあります。
    • ニュース指向のサイトでは、表示される記事の数を減らしたり、人気の低いカテゴリを除外したり、小さいメディア プレビューを表示したりすることがあります。
  3. Save-Data リクエスト ヘッダーを確認するサーバー ロジックを用意し、有効になっている場合は代替の軽量なページ レスポンスを提供することを検討します。たとえば、必要なリソースと依存関係の数を減らす、より積極的なリソース圧縮を適用するなどです。
    • Save-Data ヘッダーに基づいて代替レスポンスを提供する場合は、必ず Vary リスト(Vary: Save-Data)にそれを追加して、Save-Data リクエスト ヘッダーが存在する場合にのみこのバージョンをキャッシュに保存して配信する必要があることをアップストリーム キャッシュに伝えます。詳細については、キャッシュの操作のベスト プラクティスをご覧ください。
  4. Service Worker を使用している場合、アプリケーションでデータ保存オプションが有効になるタイミングは、Save-Data リクエスト ヘッダーの有無を確認するか、navigator.connection.saveData プロパティの値を確認することで検出できます。有効にする場合は、フェッチするバイト数を減らすようにリクエストを書き換えるか、取得済みのレスポンスを使用できるかを検討します。
  5. ユーザーの接続タイプやテクノロジーに関する情報など、他のシグナルで Save-Data を拡張することを検討してください(NetInfo API を参照)。たとえば、Save-Data が有効になっていない場合でも、2G 接続を使用するすべてのユーザーに軽量のエクスペリエンスを提供できます。逆に、ユーザーが「高速」な 4G 接続を使用しているからといって、ローミング時などに、ユーザーがデータを保存することに関心がないというわけではありません。さらに、Device-Memory クライアント ヒントで Save-Data のプレゼンスを強化し、メモリが限られているデバイスのユーザーに適応できます。ユーザーのデバイスメモリも 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 倍)と、高解像度画面(例: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 が存在しない場合に読み込まれる重要性の低い画像と、Save-Data が存在する場合に同じ画像が省略されている画像の比較。
Save-Data が存在しない場合に読み込まれる重要性の低い画像と、Save-Data が存在する場合は同じ画像を省略した画像の比較。

もちろん、画像を省略できることだけが考えられるわけではありません。Save-Data を操作して、特定の書体など、他の重要でないリソースの送信を回避することもできます。

必須ではないウェブフォントを省略する

通常、ウェブフォントがページの総ペイロードに占める割合は、画像の場合ほど多くありませんが、依然として広く使用されています。データの消費量もそれほど多くありません。さらに、ブラウザがフォントをフェッチしてレンダリングする方法は想像以上に複雑で、FOITFOUT、ブラウザのヒューリスティックなどの概念により、レンダリングが微妙に複雑になります。

無駄のないユーザー エクスペリエンスを求めるユーザーのために、必須ではないウェブフォントを除外した方がよいのは当然のことです。Save-Data を使用すると、それほど手間がかかりません。

たとえば、Google FontsFira 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 ヘッダーは実質的なニュアンスはありません。有効か無効かは問いません。理由にかかわらず、その設定に基づいてアプリが適切なエクスペリエンスを提供するという負担をアプリが負います。

たとえば、ユーザーによっては、接続状況が不安定であってもアプリのコンテンツや機能が失われることが疑われる場合、データ節約モードを許可しないことがあります。逆に、接続状況が良好であっても、ページを可能な限り小さくしてシンプルに保つユーザーもいます。アプリでは、明示的なユーザー操作によって明確な指示がない限り、ユーザーは完全で無制限のエクスペリエンスをユーザーが望んでいると想定することをおすすめします。

サイト所有者およびウェブ デベロッパーは、データおよびコストに制約のあるユーザーのユーザー エクスペリエンスを向上させるために、コンテンツを管理する責任を負います。

Save-Data の詳細と実用的な例については、ユーザーをサポートするSave Dataをご覧ください。