Symfony UX LazyImage
警告
不再建議使用此套件。 請改用現代技術來提升圖片載入效能,這些技術已由所有主要瀏覽器原生支援。
Symfony UX LazyImage 是一個 Symfony 套件,提供實用工具來提升圖片載入效能。它是 Symfony UX 計畫 的一部分。
它提供兩個主要功能
- Stimulus 控制器,用於延遲載入大型圖片,並帶有預留位置
- BlurHash 實作,用於為圖片建立 data-uri 縮圖
安裝
注意
在開始之前,請確保您的應用程式已設定 StimulusBundle。
使用 Composer 和 Symfony Flex 安裝套件
1
$ composer require symfony/ux-lazy-image
如果您使用 WebpackEncore,請安裝您的資源並重新啟動 Encore (如果您使用 AssetMapper,則不需要)
1 2
$ npm install --force
$ npm run watch
用法
Symfony UX LazyImage 的預設用法是使用其 Stimulus 控制器,先載入一個小的預留位置圖片,然後在頁面呈現後,再將其替換為高解析度版本
1 2 3 4 5 6 7 8 9 10
<img
src="{{ asset('image/small.png') }}"
{{ stimulus_controller('symfony/ux-lazy-image/lazy-image', {
src: asset('image/large.png')
}) }}
{# Optional but avoids having a page jump when the image is loaded #}
width="200"
height="150"
>
透過此設定,使用者最初會看到 images/small.png
。然後,一旦頁面載入完成,且使用者的瀏覽器已下載較大的圖片,src
屬性將變更為 image/large.png
。
也支援 srcset
屬性,方法是將 srcset
值傳遞至控制器
1 2 3 4 5 6 7 8 9 10 11 12
<img
src="{{ asset('image/small.png') }}"
srcset="{{ asset('image/small.png') }} 1x, {{ asset('image/small2x.png') }} 2x"
{{ stimulus_controller('symfony/ux-lazy-image/lazy-image', {
src: asset('image/large.png'),
srcset: {
'1x': asset('image/large.png'),
'2x': asset('image/large2x.png')
}
}) }}
/>
注意
stimulus_controller()
函式來自 StimulusBundle。
您可以使用 BlurHash 演算法來建立圖片的輕量、模糊的 data-uri 縮圖,而無需使用檔案系統中存在的已產生縮圖
1 2 3 4 5 6 7 8 9 10
<img
src="{{ data_uri_thumbnail('public/image/large.png', 100, 75) }}"
{{ stimulus_controller('symfony/ux-lazy-image/lazy-image', {
src: asset('image/large.png')
}) }}
{# Using BlurHash, the size is required #}
width="200"
height="150"
/>
data_uri_thumbnail
函式接收 3 個引數
- 要產生 data-uri 縮圖的圖片路徑;
- 要產生的 BlurHash 寬度
- 要產生的 BlurHash 高度
自訂圖片擷取
預設情況下,data_uri_thumbnail
使用 file_get_contents 函式擷取圖片。它適用於本機檔案,但您可能想要自訂它以從遠端伺服器、Flysystem 等擷取圖片。
若要執行此操作,您可以建立可調用的類別,第一個引數是要擷取的檔案名稱
1 2 3 4 5 6 7 8 9
namespace App\BlurHash;
class FetchImageContent
{
public function __invoke(string $filename): string
{
// Your custom implementation here to fetch the image content
}
}
然後您必須在 Symfony 組態中設定服務
1 2 3
# config/packages/lazy_image.yaml
lazy_image:
fetch_image_content: 'App\BlurHash\FetchImageContent'
效能考量
您應該嘗試產生小的 BlurHash 圖片,因為產生圖片可能會消耗大量 CPU 資源。或者,您可以透過產生小圖片並使用 width
和 height
HTML 屬性來放大圖片,藉此依賴瀏覽器的縮放能力。
您也可以設定快取池來儲存產生的 BlurHash,這樣您可以避免多次產生相同的 BlurHash
1 2 3 4 5 6 7 8
# config/packages/lazy_image.yaml
framework:
cache:
pools:
cache.lazy_image: cache.adapter.redis # or any other cache adapter depending on your needs
lazy_image:
cache: cache.lazy_image # the cache pool to use
擴充預設行為
Symfony UX LazyImage 允許您使用自訂 Stimulus 控制器來擴充其預設行為
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// mylazyimage_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
this.element.addEventListener('lazy-image:connect', this._onConnect);
this.element.addEventListener('lazy-image:ready', this._onReady);
}
disconnect() {
// You should always remove listeners when the controller is disconnected to avoid side-effects
this.element.removeEventListener('lazy-image:connect', this._onConnect);
this.element.removeEventListener('lazy-image:ready', this._onReady);
}
_onConnect(event) {
// The lazy-image behavior just started
}
_onReady(event) {
// The HD version has just been loaded
}
}
然後在您的範本中,將您的控制器新增至 HTML 屬性
1 2 3 4 5 6 7 8 9 10
<img
src="{{ data_uri_thumbnail('public/image/large.png', 100, 75) }}"
{{ stimulus_controller('mylazyimage')|stimulus_controller('symfony/ux-lazy-image/lazy-image', {
src: asset('image/large.png')
}) }}
{# Using BlurHash, the size is required #}
width="200"
height="150"
/>
注意:請注意在 LazyImage 控制器之前新增您的控制器,使其在之前執行,並能正確監聽
lazy-image:connect
事件。
最大內容繪製 (LCP) 和網頁效能考量
最大內容繪製 (LCP) 是網頁效能的關鍵指標。它測量頁面上呈現最大圖片或文字區塊所需的時間,應小於 2.5 秒。它是 Core Web Vitals 的一部分,並由 Google 用於評估網站的使用者體驗,影響搜尋排名。
最初,針對您的 LCP 圖片使用 Symfony UX LazyImage 可能是一個好主意,
但實際上,它會降低 LCP 分數,因為
- 漸進式載入 (透過 blurhash) 不會納入 LCP 計算;
- 即使您預先載入 LazyImage Stimulus 控制器,也會在 LCP 計算中增加少量延遲;
- 如果您未預先載入圖片,瀏覽器將等待 Stimulus 控制器載入圖片,這會為 LCP 計算增加另一個延遲。
一個解決方案是不針對 LCP 圖片使用 Stimulus 控制器,而是改用 src
和 style
屬性,並同時預先載入圖片
1 2 3 4 5 6 7 8 9
<img
src="{{ preload(asset('image/large.png'), { as: 'image', fetchpriority: 'high' }) }}"
style="background-image: url('{{ data_uri_thumbnail('public/image/large.png', 20, 15) }}')"
fetchpriority="high"
{# Using BlurHash, the size is required #}
width="200"
height="150"
/>
這樣一來,瀏覽器將儘快顯示 BlurHash 圖片,並同時載入高解析度圖片,而無需等待 Stimulus 控制器載入。
向後相容性承諾
此套件旨在遵循與 Symfony 框架相同的向後相容性承諾:https://symfony.dev.org.tw/doc/current/contributing/code/bc.html