如何在加载时强制解码图像?

12
我正在构建一个支持使用requestAnimationFrame实现视差滚动的网站。有多个区域,每个区域都有一张全尺寸背景图片以及一些中景和前景图片。我已通过requestAnimationFrame成功实现了相对平滑的动画效果,但是仍然偶尔会出现抖动。
通过在Chrome的时间轴模式下观察,我可以看到导致“卡顿”的进程标签为“Image Decode”。此外,一旦动画完成一次,就不会再出现抖动。
似乎大多数浏览器现在都会推迟未显示的图像的解码。是否有一种方法可以在这些图像对用户不可见的情况下进行预解码(而不仅仅是预加载)?

这些抖动可能是因为元素的大小尚未确定吗?你有一个带有示例的链接吗? - Brad
1
当我滚动时,我看到...滚动会在图像解码时停顿一小段时间。这就是你所指的问题,对吗?你尝试过在顶部的div中显示所有图像吗?它们不必可见...如果必要,设置z-index或甚至显示一个1x1的div。 - Brad
我已经尝试显示所有图像,甚至可见,但似乎无论如何都不会影响性能——我仍然在检查器中看到“图像解码”,并且动画中有卡顿。 - modernserf
1
你尝试过 canvas 元素吗? - wukong
@Alnitak 不是我的设计,兄弟。 - modernserf
显示剩余3条评论
3个回答

1

问题可能与图像滚动出/进视图有关。

来自http://creativejs.com/resources/requestanimationframe/

还有一些暗示,浏览器可以根据负载、元素可见性(被滚动出视图)和电池状态来优化requestAnimationFrame的性能。

同样来自W3C draft

ISSUE-4我们是否希望允许将元素传递给requestAnimationFrame,以便在滚动出视图时限制或暂停影响给定元素的动画?

确保您不会为每个onscroll事件启动requestAnimationFrame循环,因为这可能会导致问题。这在这篇单独的文章中有详细描述

Questions about Request Animation Frame


0
我通过删除检查元素是否在屏幕上的代码行来解决了这个问题,因为它很可能与浏览器执行相同的操作,只是效果不佳。

0

您可以将图像预解码为数组

const img = new Image();
img.src = "bigImage.jpg";
img.decode().then(() => {
    images.push(img)
}).catch(() => {
    throw new Error('Could not load/decode big image.');
});

在此示例中,作者 请求解码图像元素。解码涉及加载,然后对图像进行解码。该调用返回一个 Promise,当 Promise 被实现时,可以确保将图像附加到 DOM 而不会在下一帧上造成解码延迟。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接