跳到内容

Symfony UX LazyImage

编辑此页

警告

不推荐使用此包。 请使用所有主流浏览器原生支持的现代技术来提高图像加载性能

Symfony UX LazyImage 是一个 Symfony 扩展包,提供实用工具来提高图像加载性能。它是 Symfony UX 倡议 的一部分。

它提供了两个主要功能

  • 一个 Stimulus 控制器,用于延迟加载重型图像,并带有占位符
  • 一个 BlurHash 实现,用于为图像创建 data-uri 缩略图

安装

注意

在开始之前,请确保您的应用中配置了 StimulusBundle

使用 Composer 和 Symfony Flex 安装 bundle

1
$ composer require symfony/ux-lazy-image

如果您正在使用 WebpackEncore,请安装您的 assets 并重启 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 事件。

最大内容ful绘制 (LCP) 和 Web 性能考量

最大内容ful绘制 (LCP) 是衡量 Web 性能的关键指标。它衡量最大图像或文本块在页面上呈现所需的时间,应少于 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 控制器加载。

向后兼容性承诺

此 bundle 旨在遵循与 Symfony 框架相同的向后兼容性承诺:http://symfony.ac.cn/doc/current/contributing/code/bc.html

这项工作,包括代码示例,已获得 Creative Commons BY-SA 3.0 许可协议的许可。
目录
    版本