自動壓縮和編碼

讓產生高效圖片來源的過程順暢無礙。

本課程的所有語法 (從圖片資料編碼,到驅動回應式圖片運用資訊密集標記等) 都是機器與機器通訊的方法。您已探索了多個可讓用戶端瀏覽器向伺服器傳達需求的方法,以及伺服器以種類做出回應的方式。回應式圖片標記 (尤其是 srcsetsizes) 能夠以相對少量字元描述駭人的資訊。簡言之,簡言之,就是設計更精簡的語法。如果讓開發人員更容易剖析這些語法,這種做法可能會提高瀏覽器的剖析難度。在字串中加入的複雜度越高,剖析器錯誤的可能性就越高,或是瀏覽器間的意外差異。

自動圖片編碼視窗。

不過,儘管讓這些主題感到吃緊,同樣也可以提供解決方案:讓機器更容易「讀取」語法,而這是他們更容易「編寫」的語法。就像身為網路使用者一樣,大致上已經遇到許多自動圖片編碼和壓縮示例:透過社群媒體平台、內容管理系統 (CMS) 到電子郵件用戶端上傳到網路的圖片,幾乎不會大幅通過會調整大小、重新編碼及壓縮的系統。

同樣地,無論是透過外掛程式、外部程式庫、獨立建構程序工具,或負責任地使用用戶端指令碼,回應式圖片標記都可以用來自動執行自動化作業。

自動化圖片效能有兩個主要考量:管理圖片的建立作業 (編碼、壓縮,以及用於填入 srcset 屬性的替代來源),以及產生向使用者顯示的標記。在本單元中,您將瞭解在現代工作流程中管理圖片的幾種常見方法,包括做為開發程序的自動化階段、透過採用您網站採用的架構或內容管理系統,或是幾乎由專屬內容傳遞網路完全摘除。

自動壓縮和編碼

您不太可能會花時間,針對要用於專案的個別圖片,手動決定理想的編碼編碼與壓縮等級,反之亦然。重要的是盡可能縮減圖片傳輸大小,同時微調壓縮設定並重新儲存適用於生產網站的每個圖片素材資源的替代來源,將對您的日常工作造成巨大瓶頸。

如您在讀取各種圖片格式和壓縮類型時有所瞭解,圖片編碼最有效率的系統一律會根據圖片內容決定,而如您在回應式圖片中學到,圖片來源所需的替代大小則取決於這些圖片在網頁版面配置中的位置。在現代的工作流程中,您將全面進行這些決策,而非個別進行,也就是決定圖片的合理預設值,以配合其用途。

選擇攝影圖片目錄的編碼時,AVIF 是品質和傳輸大小最明顯的勝出者,但支援有限,WebP 提供最佳化、現代化的備用項,JPEG 是最可靠的預設值。我們想要為顯示在網頁版面配置中側欄的圖片產生替代大小,與原本要在最高中斷點佔據整個瀏覽器可視區域的圖片,差異很大。壓縮設定需要留意多個結果檔案的模糊和壓縮構件,讓每個圖片都能完整處理每個可能的位元組,藉此提供更靈活且可靠的工作流程。總而言之,您將會遵循和本課程一樣瞭解的決策程序。

就處理本身而言,很多開放原始碼圖像處理程式庫提供了轉換、修改和編輯批次圖片的方法,而且兼顧速度、效率和可靠性。這些處理程式庫可讓您將編碼和壓縮設定一次套用至整個圖片目錄,而不必開啟圖片編輯軟體,而且在需要即時調整這些設定時,可以保留原始圖片來源。它的目標是在各種情境下執行,包括本機開發環境到網路伺服器本身。例如,您可以透過一系列的外掛程式,為 Node.js 適用的壓縮 ImageMin 延伸到特定應用程式,而跨平台的 ImageMagick 和以 Node.js 為基礎的 Sharp 建立功能相當容易取得的功能,

這些影像處理程式庫可讓開發人員打造專用工具,以便在您的標準開發程序中順利將圖片最佳化,確保您的專案將持續參照可投入實際工作環境的圖片來源,並盡可能減少負擔。

本機開發工具和工作流程

Grunt、Gulp 或 Webpack 等工作執行器和套件器可用來最佳化圖片素材資源,並搭配其他常見效能相關工作,例如壓縮 CSS 和 JavaScript。我們來看一個相對簡單的用途:專案的目錄包含十張攝影圖片,並以公開網站的形式使用。

首先,您必須確保這些圖片採用一致且有效率的編碼方式。如先前單元所述,WebP 是相片圖片的高效預設設定,包括品質和檔案大小。由於 WebP 支援,但並非「全面」支援,因此建議您也加入漸進式 JPEG 形式的備用內容。然後,為了使用 srcset 屬性有效率地提供這些資產,您必須為每種編碼產生多種替代大小。

雖然使用圖片編輯軟體時會重複且費時,但 Gulp 等工作執行器的設計能自動執行這類重複問題。許多使用 Sharpgulp-responsive 外掛程式是採用類似模式的其中一種方式:收集來源目錄中的所有檔案,重新編碼,然後根據圖片格式和壓縮中所學的相同標準化「品質」簡寫。產生的檔案會輸出到您定義的路徑,可供您在向使用者顯示的 img 元素 src 屬性中參照,同時保留原始檔案。

const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');

exports.webp = function() {
  return src('./src-img/*')
    .pipe(respimg({
      '*': [{
        quality: 70,
        format: ['webp', 'jpeg'],
        progressive: true
      }]
  }))
  .pipe(dest('./img/'));
}

透過設定這類程序後,如果專案有人不小心將編碼成大型真實色彩 PNG 格式的相片新增至包含原始圖片來源的目錄,這項工作就會產生高效率 WebP 和可靠的漸進式 JPEG 備用項,而且壓縮程度可以輕鬆隨時間調整。當然,這個程序也能確保原始圖片檔會保留在專案的開發環境中,也就是說,這些設定隨時能在只有覆寫自動化輸出內容的情況下調整。

如要輸出多個檔案,除了新增 width 鍵和以像素為單位的值以外,您還會傳遞多個設定物件:

const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');

exports.default = function() {
  return src('./src-img/*')
    .pipe(respimg({
    '*': [{
            width: 1000,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-1000' }
            },
            {
            width: 800,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-800' }
            },
            {
            width: 400,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-400' },
        }]
        })
    )
    .pipe(dest('./img/'));
}

在上述範例中,原始圖片 (monarch.png) 超過 3.3 MB。這項工作產生的最大檔案 (monarch-1000.jpeg) 約為 150 KB。最小的 monarch-400.web 只有 32 KB,

[10:30:54] Starting 'default'...
[10:30:54] gulp-responsive: monarch.png -> monarch-400.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-800.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-400.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-800.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.webp
[10:30:54] gulp-responsive: Created 6 images (matched 1 of 1 image)
[10:30:54] Finished 'default' after 374 ms

當然,建議您仔細檢查可見的壓縮構件結果,或者可能提高壓縮率以節省額外用量。由於這項工作沒有破壞性,因此您可以輕鬆變更這些設定。

總而言之,您可以謹慎手動進行微型最佳化來減少幾 KB 的資料量,這樣您就能取得一個不僅效率高,也「富有彈性」。這項工具可將高效能圖片資產的知識順暢地應用到整個專案,完全不需要任何人力介入。

實際使用回應式圖片標記

填入 srcset 屬性通常是簡單的手動程序,因為這項屬性只會擷取產生來源時已完成的設定資訊。在上述工作中,我們已建立屬性要遵循的檔案名稱和寬度資訊:

srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w"

請注意,srcset 屬性的內容為描述性字詞,而非指示性。只要每個來源的顯示比例一致,srcset 屬性超載應該就不會造成任何危害。srcset 屬性可包含伺服器產生的每個替代剪輯 URI 和寬度,而不會產生任何不必要的要求。而我們提供的轉譯圖片候選來源越多,瀏覽器就越能有效處理要求。

回應式圖片所述,建議您使用 <picture> 元素來順利處理 WebP 或 JPEG 備用模式。在這種情況下,您將使用 type 屬性與 srcset 搭配使用。

<picture>
  <source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
  <img srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>

如您所知,支援 WebP 的瀏覽器會辨識 type 屬性的內容,然後選取 <source> 元素的 srcset 屬性做為候選圖片清單。如果瀏覽器無法辨識 image/webp 為有效的媒體類型,則會忽略這個 <source>,改用內部 <img> 元素的 srcset 屬性。

在瀏覽器支援方面,還有一個考量:不支援任何回應式圖片標記的瀏覽器仍需要備用,否則我們可能會在舊版瀏覽環境中,放送圖片毀損的風險。由於這些瀏覽器會忽略 <picture><source>srcset,我們需要在內部 <img>src 屬性中指定預設來源。

由於圖片向下縮放時可以視覺化的方式縮小圖片,而且系統皆支援 JPEG 編碼,因此建議使用最大的 JPEG 格式。

<picture>
  <source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
  <img src="filename-1000.jpg" srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>

sizes 可能會有點困難。如同您所學sizes 必定為內容相關,如果沒有瞭解圖片要在轉譯的版面配置中佔用的空間,便無法填入屬性。為了盡可能提高要求的效率,當使用者提出要求時,我們必須在標記中加上準確的 sizes 屬性,直到要求用於管理網頁版面配置的樣式為止。完全省略 sizes 不僅會違反 HTML 規格,也會產生與 sizes="100vw" 相等的預設行為,讓瀏覽器知道這張圖片只會受可視區域本身限制,進而選取最大的候選來源。

與任何特別繁重的網站開發工作一樣,我們開發了多種工具,來簡化手寫 sizes 屬性的程序。respImageLint 是絕對重要的程式碼片段,旨在檢查 sizes 屬性的準確性,並提供改善建議。這會以書籤小程式形式執行,也就是您在瀏覽器中執行的工具,指向包含圖片元素的完整轉譯頁面。在瀏覽器完全瞭解網頁版面配置的情況下,同時也能讓圖片以各種可能的可視區域大小,清楚呈現圖片的空間。

回應式圖片報表顯示大小/寬度不符。

檢查 sizes 屬性的工具固然非常實用,但更具有利於產生批發屬性的工具。如您所知,srcsetsizes 語法的用意是讓圖片素材資源的請求最佳化。雖然在實際工作環境中不應用到的內容,但預設的 sizes 預留位置值 100vw 相當合理,可在本機開發環境中處理網頁的版面配置。版面配置樣式設定完成後,執行 respImageLint 會提供量身打造的 sizes 屬性,讓您複製並貼到標記中,細節層次遠大於手動撰寫的樣式:

採用建議的尺寸的回應式圖片報表。

雖然伺服器轉譯標記發起的圖片要求太快,因此 JavaScript 無法產生用戶端 sizes 屬性,但如果這些要求是由用戶端「啟動」,上述原因就不會發生。舉例來說,「Lazysizes」專案可讓您全面延遲圖片要求,直到版面配置建立完成為止,允許 JavaScript 為我們產生 sizes 值,您不但十分方便,也可確保使用者能處理最有效率的要求。不過請注意,這種做法確實需要犧牲伺服器轉譯標記的可靠性和內建於瀏覽器的速度最佳化功能,且只有在網頁轉譯後才發出這些要求,會對 LCP 分數造成巨大的負面影響。

當然,如果您已經仰賴用戶端轉譯架構 (例如 React 或 Vue),就算是債務,而在這種情況下,使用 Lazysize 可讓您幾乎完全捨棄 sizes 屬性。保持不動:隨著延遲載入圖片的 sizes="auto" 取得共識和原生實作,Lazysize 將有效做為新標準化瀏覽器行為的 polyfill。