提供快速、輕量化的應用程式,讓您節省數據用量

Dave Gash
Dave Gash
Ilya Grigorik
Ilya Grigorik

Chrome、Opera 和 Yandex 瀏覽器提供的 Save-Data 用戶端提示要求標頭,可讓開發人員為在瀏覽器中選擇啟用資料儲存模式的使用者提供更快速、更快速的應用程式。

對輕量網頁的需求

Weblight 統計資料

大家都同意,載入快速的網頁能帶來更良好的使用者體驗、提升內容的理解度和留存率,以及提高轉換率和收益。Google 研究顯示:「...最佳化的網頁載入速度比原始網頁快四倍,所用的位元組容量更少 80%。由於載入速度提升,這些網頁的流量也提高了 50%。」

此外,雖然 2G 連線數量最終會減少,但 2015 年,2G 仍然是主要的網路技術。雖然 3G 和 4G 網路的滲透率和可用性正在快速成長,但相關的擁有權成本和網路限制仍是數億名使用者的重要因素。

這些是網頁最佳化的重要論點。

有些替代方法可在開發人員沒有直接參與的情況下提升網站速度,例如 Proxy 瀏覽器和轉碼服務。雖然這類服務廣受歡迎,但有一些缺點 (簡單 (有時是不可接受的) 圖片和文字壓縮、無法處理安全 (HTTPS) 網頁、只針對透過搜尋結果造訪的網頁進行最佳化等)。這些服務之所以相當受歡迎,本身也指出網頁程式開發人員未妥善解決應用程式與網頁的高使用率需求。但實現這個目標既複雜又困難

Save-Data 要求標頭

有一個相當簡單明瞭的技巧,就是使用 Save-Data 要求標頭讓瀏覽器提供協助。透過識別此標頭,網頁就能自訂並提供最佳化使用者體驗,滿足費用和效能受限的使用者。

支援的瀏覽器 (如下) 可允許使用者啟用「*資料節省模式」,讓瀏覽器套用一組最佳化設定,以減少轉譯網頁所需的資料量。這項功能公開或公告時,瀏覽器可能會要求解析度較低的圖片、延遲載入某些資源,或透過套用其他內容專屬最佳化功能 (例如圖片和文字資源壓縮) 的服務來轉送要求。

瀏覽器支援

正在偵測 Save-Data 設定

為了判斷何時向使用者提供「輕量」體驗,應用程式可以檢查 Save-Data 用戶端提示要求標頭。這個要求標頭會指出用戶端因傳輸費用過高、連線速度緩慢或其他原因而降低數據用量的偏好。

當使用者在瀏覽器中啟用資料儲存模式時,瀏覽器會在所有傳出要求 (包含 HTTP 和 HTTPS) 中附加 Save-Data 要求標頭。截至本文撰寫時,瀏覽器在標頭 (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。這個 API 只能在 Chrome、Chrome for Android 和 Samsung 網際網路瀏覽器中實作。這樣一來,您只需要檢查 navigator.connection.saveData 是否等於 true,即可在該條件中實作任何資料儲存作業。

Chrome 開發人員工具中的 Save-Data 標頭,以及數據節省模式擴充功能顯示在圖片中。
在 Chrome 電腦版中啟用數據節省模式擴充功能。

如果應用程式使用服務 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)。舉例來說,您可能希望透過 2G 連線為任何使用者提供輕量級服務 (即使未啟用 Save-Data)。相反地,即便使用者是「快速」的 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 狀態,且可在網頁上任何位置使用。透過此機制的說明,讓我們用幾個範例來限制我們傳送給使用者的資料量。

針對高解析度螢幕提供低解析度圖片

網路圖片的常見用途是在以下的組合中提供圖片:一張用於「標準」螢幕 (1x) 圖片,另一張圖片在高解析度螢幕 (例如Retina 顯示器)。這類高解析度螢幕不一定適用於高階裝置,而且越來越常見。如果我們建議使用較輕量的應用程式體驗,建議您傳送解析度較低的 (1 倍) 圖片到這些螢幕,而非大於 (2 倍) 的變化版本。如要在有 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 操作,略過其他非關鍵資源,例如特定字體。

省略非必要的網路字型

雖然網頁字型通常不像圖片一樣佔據整個網頁的總酬載,但仍然相當受歡迎。也不會耗用少量資料。此外,瀏覽器擷取及轉譯字型的方式比您想像的複雜,具備 FOITFOUT 和瀏覽器經驗法等概念,使得轉譯作業進行細微作業。

這可能的原因在於,您可能會想避免使用者閱讀不必要的網路字型,以便提供較優質的使用者體驗。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 元素是否叫用樣式表單中的任何資源。如果開啟 Save-Data 後有人發生,Fira Sans 就一律不會載入,因為樣式化 DOM 一律不會叫用。系統會改為使用 one。雖然這沒有像 Fira Sans 那麼像 Fira Sans 那樣,但使用者可能更適合想擴展數據計畫的使用者。

摘要

Save-Data 標頭沒有明顯的細微差異;這種標頭可開啟或關閉,不論原因為何,應用程式都無須負擔根據其設定提供適當體驗的負擔。

舉例來說,部分使用者疑似會遺失應用程式內容或功能,即使連線品質不佳,也可能不允許使用資料儲存模式。相反地,某些使用者可能會為了盡可能精簡精簡網頁,即使在連線狀態良好的情況下也能保持精簡。建議您讓應用程式假設使用者需要完整且無限制的使用體驗,直到您透過明確的使用者動作明確指示為止。

身為網站擁有者和網頁程式開發人員,我們接著應負責管理內容,為資料和成本受限的使用者改善使用者體驗。

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