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 资源。相反,您可以依靠浏览器的缩放能力,通过生成一个小图像并使用 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
事件。
最大内容ful绘制 (LCP) 和 Web 性能考量
最大内容ful绘制 (LCP) 是衡量 Web 性能的关键指标。它衡量最大图像或文本块在页面上呈现所需的时间,应少于 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 控制器加载。
向后兼容性承诺
此 bundle 旨在遵循与 Symfony 框架相同的向后兼容性承诺:http://symfony.ac.cn/doc/current/contributing/code/bc.html