使用 Save-Data 提供快速輕巧的應用程式

Dave Gash
Dave Gash
Ilya Grigorik
Ilya Grigorik

Chrome、Opera 和 Yandex 瀏覽器提供 Save-Data 用戶端提示要求標頭,可讓開發人員為在瀏覽器中選擇加入數據節省模式的使用者,提供更輕量、更快速的應用程式。

輕量網頁的需求

Weblight 統計資料

大家都同意,更快速、更輕量的網頁能提供更令人滿意的使用者體驗,讓使用者更容易理解及記住內容,並提高轉換率和收益。Google 研究顯示,「…最佳化網頁的載入速度比原始網頁快四倍,使用的位元組數也減少 80%。由於載入速度提升,這些網頁的流量也提高了 50%。」

雖然 2G 連線數量終於開始下降,但 2G 在 2015 年仍是主要的網路技術。3G 和 4G 網路的普及率和可用性正在快速成長,但相關的擁有成本和網路限制仍是數億名使用者的重要考量因素。

這些都是網頁最佳化的有力論據。

您也可以採用其他方法提升網站速度,不一定要由開發人員直接參與,例如使用 Proxy 瀏覽器和轉碼服務。雖然這類服務相當受歡迎,但也有許多缺點,例如圖片和文字壓縮方式過於簡單 (有時甚至無法接受)、無法處理安全 (HTTPS) 網頁、只能最佳化透過搜尋結果造訪的網頁等。這些服務之所以廣受歡迎,本身就代表網頁程式開發人員並未妥善因應使用者對快速、輕量應用程式和網頁的高度需求。但要達成這個目標,過程複雜且有時相當困難。

Save-Data 要求標頭

其中一個相當簡單的技術是使用 Save-Data 要求標頭,讓瀏覽器提供協助。網頁可透過這個標頭,為受限於成本和效能的使用者,提供量身打造的最佳體驗。

支援的瀏覽器 (如下所示) 可讓使用者啟用 *數據節省模式,授權瀏覽器套用一組最佳化設定,減少轉譯網頁所需的數據量。如果瀏覽器公開或宣傳這項功能,可能會要求解析度較低的圖片、延遲載入部分資源,或透過套用其他內容專屬最佳化設定 (例如圖片和文字資源壓縮) 的服務轉送要求。

瀏覽器支援

  • Chrome 49 以上版本會在使用者於行動裝置上啟用「數據節省模式」選項,或在電腦版瀏覽器上啟用「數據節省模式」擴充功能時,宣傳 Save-Data。
  • 當使用者在電腦上啟用「Opera Turbo」模式,或在 Android 瀏覽器上啟用「節省數據用量」選項時,Opera 35+ 會宣傳 Save-Data。
  • 在電腦或行動瀏覽器上啟用加速模式時,Yandex 16.2 以上版本會宣傳 Save-Data。

偵測 Save-Data 設定

如要判斷何時向使用者提供「精簡」體驗,應用程式可以檢查 Save-Data 用戶端提示要求標頭。這項要求標頭表示用戶端因傳輸費用高、連線速度慢或其他原因,偏好減少數據用量。

使用者在瀏覽器中啟用數據節省模式時,瀏覽器會將 Save-Data 要求標頭附加至所有傳出要求 (包括 HTTP 和 HTTPS)。截至本文撰寫時,瀏覽器只會在標頭 (Save-Data: on) 中宣傳一個 *on- 權杖,但日後可能會擴充,以表示其他使用者偏好設定。

此外,您也可以在 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 Internet 瀏覽器中 實作。接著,您只需要檢查 navigator.connection.saveData 是否等於 true,並在該條件下實作任何資料儲存作業。

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

雖然您可以透過 navigator.connection.saveData 屬性在 JavaScript 中偵測 Save-Data 狀態,但有時最好在伺服器端偵測。在某些情況下,JavaScript 可能無法執行。此外,伺服器端偵測是唯一能在標記傳送至用戶端「之前」修改標記的方法,這涉及 Save-Data 的一些最有利的用途。

在伺服器端程式碼中偵測 Save-Data 標頭的特定語法,取決於使用的語言,但基本概念在任何應用程式後端都相同。舉例來說,在 PHP 中,要求標頭會儲存在 $_SERVER 超全域陣列中,索引開頭為 HTTP_。這表示您可以檢查 $_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 狀態,並可在網頁上的任何位置使用。瞭解這項機制後,我們來看看幾個例子,瞭解如何使用這項機制限制傳送給使用者的資料量。

在高解析度螢幕上顯示低解析度圖片

網頁圖片的常見用途包括以兩張圖片為一組提供圖片:一張圖片用於「標準」螢幕 (1x),另一張圖片則用於高解析度螢幕 (例如 Retina 螢幕),大小是前者的兩倍 (2x)。這類高解析度螢幕不一定僅限於高階裝置,而且越來越常見。如果偏好較輕量的應用程式體驗,建議將解析度較低 (1x) 的圖片傳送至這些螢幕,而非較大的 (2x) 變化版本。如要在 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) 達到相同效果。這裡提供一些範例,說明如何透過相對簡單的設定達成這個目標。

您也可以將這個概念延伸到 CSS background-image 屬性,只要在 <html> 元素中加入類別即可:

<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 採取行動,不傳送其他非重要資源,例如特定字體。

省略不必要的網頁字型

雖然網頁字型通常不會像圖片一樣,占據網頁總酬載的大部分,但仍相當受歡迎。而且消耗的資料量也不容小覷。此外,瀏覽器擷取及算繪字型的方式比您想像的更複雜,例如 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,Fira Sans 就不會載入,因為樣式 DOM 不會叫用該字型。系統會改用 Arial。雖然不如 Fira Sans 漂亮,但對於想節省數據用量的使用者來說,這可能是更好的選擇。

摘要

Save-Data 標頭沒有太多細微差異,只有開啟或關閉兩種狀態,且應用程式必須根據其設定提供適當的體驗,無論原因為何。

舉例來說,如果使用者懷疑應用程式內容或功能會遺失,即使連線狀況不佳,也可能不允許數據節省模式。相反地,有些使用者可能會自然而然地啟用這項功能,盡可能讓網頁保持精簡,即使連線狀況良好也一樣。除非使用者明確表示不希望,否則應用程式最好假設使用者想要完整且不受限制的體驗。

身為網站擁有者和網頁程式開發人員,我們有責任管理內容,為數據用量和費用受限的使用者提升體驗。

如要進一步瞭解 Save-Data 和實用範例,請參閱「協助使用者Save Data」。