跳到內容

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 資源。或者,您可以透過產生小圖片並使用 widthheight 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 分數,因為

一個解決方案是不針對 LCP 圖片使用 Stimulus 控制器,而是改用 srcstyle 屬性,並同時預先載入圖片

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

這項作品,包括程式碼範例,已根據 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本