You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

序列图片滚动加载完成后页面滚动不顺畅的技术求助

问题原因

滚动到最后一帧后仍频繁触发无意义的图片重绘,占用浏览器资源,导致后续滚动响应卡顿。原代码中每次滚动事件都会调用requestAnimationFrame更新图片,即使帧索引没有变化,这种重复操作会干扰浏览器的滚动事件处理逻辑。

解决方案

通过记录上一帧索引,仅在帧索引变化时执行更新,减少不必要的重绘,同时限制滚动分数的最大值,避免超出范围的滚动影响计算:

修改后的完整JS代码:

const html = document.documentElement;
const canvas = document.getElementById("3d");
const context = canvas.getContext("2d");

const frameCount = 27;
const currentFrame = index => (
  `https://www.in-visionen.de/Webdesign/Webdesign${index.toString().padStart(4, '0')}.jpg`
)

const preloadImages = () => {
  for (let i = 1; i < frameCount; i++) {
    const img = new Image();
    img.src = currentFrame(i);
  }
};

const img = new Image()
img.src = currentFrame(1);
canvas.width = 3840;
canvas.height = 2160;
img.onload = function() {
  context.drawImage(img, 0, 0);
}

const updateImage = index => {
  img.src = currentFrame(index);
  context.drawImage(img, 0, 0);
}

// 记录上一次渲染的帧索引
let lastFrameIndex = 1;

window.addEventListener('scroll', () => {
  const scrollTop = html.scrollTop;
  const maxScrollTop = html.scrollHeight - window.innerHeight;
  // 限制滚动分数最大为1,避免超出范围后计算无效值
  const scrollFraction = Math.min(scrollTop / maxScrollTop, 1);
  const frameIndex = Math.min(
    frameCount - 1,
    Math.ceil(scrollFraction * frameCount)
  );
  const targetFrame = frameIndex + 1;

  // 仅当帧索引变化时才执行更新操作
  if (targetFrame !== lastFrameIndex) {
    lastFrameIndex = targetFrame;
    requestAnimationFrame(() => updateImage(targetFrame))
  }
});

preloadImages()

额外优化(可选)

如果希望仅用页面中特定区域的滚动来控制帧切换(比如.design元素的高度范围),可以进一步限定滚动分数的计算范围,避免整个页面滚动影响:

// 获取控制滚动的容器元素
const scrollContainer = document.querySelector('.design');
// 计算该容器对应的有效滚动高度
const frameMaxScrollTop = scrollContainer.offsetHeight - window.innerHeight;

window.addEventListener('scroll', () => {
  const scrollTop = html.scrollTop;
  // 基于容器高度计算滚动分数,超出后固定为1
  const scrollFraction = Math.min(scrollTop / frameMaxScrollTop, 1);
  const frameIndex = Math.min(
    frameCount - 1,
    Math.ceil(scrollFraction * frameCount)
  );
  const targetFrame = frameIndex + 1;

  if (targetFrame !== lastFrameIndex) {
    lastFrameIndex = targetFrame;
    requestAnimationFrame(() => updateImage(targetFrame))
  }
});

内容的提问来源于stack exchange,提问作者Ayhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:02:08