javascript - 如何处理大页面上的图像延迟加载?

标签 javascript html lazy-loading

我们当前用于延迟加载图像的方法是:

服务器端模板将所有图像元素呈现为:

<img
    src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
    data-src="http://static.com/img.jpg"
    style="display: none;"
/>

DOMContentLoaded事件被触发,然后 JavaScript 检测到 <img />视口(viewport)中的元素并替换 src属性值的值为 data-src .

问题:

在加载整个 DOM 之前,首页上的图像不会出现。由于这是一个非常大的页面(2MB HTML),因此大约需要 3-5 秒才能看到 DOMContentLoaded事件被触发。

我正在寻找一个 JavaScript 解决方案,它使我能够在前 100 个图像可在 DOM 中进行操作时立即加载它们。

最佳答案

What I am looking for is a JavaScript solution that would enable me to load the first 100 images as soon as they become available for manipulation in the DOM.

我实现的解决方案基本上是这样的。

我需要一个抽象延迟加载脚本来重新索引页面上的现有图像。我将首先在文档中的其他内容之前同步加载此脚本。从 JavaScript 可以运行的那一刻起,脚本就会开始一个间隔,尝试在 DOM 中查找所有图像元素并检查它们是否在视口(viewport)中。如果元素被认为在视口(viewport)中,它会尝试修改图像元素(data-srcsrc)。此间隔将持续到触发 DOMContentLoaded 为止。

就代码而言,它看起来像这样:

const LazyImageLoader = require('./LazyImageLoader');
const domReady = require('domready');

/**
 * The reason for using setTimeout instead of setInterval
 * is to not re-run revalidate more often than the body
 * of the function can be evaluated.
 */
const createIntervalIterator = (callback, interval) => {
  let currentTimeout;

  const control = {};

  const iterator = () => {
    const startTime = new Date().getTime();

    callback();

    const evaluationTime = new Date().getTime() - startTime;

    const delayNextIteration = interval - evaluationTime;

    currentTimeout = setTimeout(iterator, delayNextIteration);
  };

  iterator();

  return () => {
    clearTimeout(currentTimeout);
  };
};

const iterationIntervalTime = 100;

const lazyImageLoader = new LazyImageLoader({
  offset: 100,
  selector: 'img[data-src]',
});

/**
 * Revalidation ensures that all images are in LazyImageLoader index.
 */
const revalidate = () => {
    lazyImageLoader.revalidate();
};

const cancelInterval = createIntervalIterator(() => {
  revalidate();
}, iterationIntervalTime);

domReady(() => {
  if (cancelInterval) {
    cancelInterval();
  }

  // Revalidate after domReady in case any images have been added
  // to the DOM after the last `revalidate` invocation.
  revalidate();
});

关于javascript - 如何处理大页面上的图像延迟加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38484325/

相关文章:

android - 延迟加载像 googlenewstand 应用

javascript - php codeigniter - 使用 ajax 取回默认值

javascript - 多个导入类如何调用彼此的方法?

javascript - 复制div内容并将其放置在其他地方

html - 如何从文本区域的文本输入中删除下划线?

android - 许多 AsyncTask 生成时出现 AsyncTask 性能问题。

javascript - "onClick"构建项目后不工作

html - 如何以 Angular 动态设置 sibling 的最大宽度

html - 如何仅使用 Html 和 CSS 在滚动条上创建固定/粘性标题?

c# - SetFetchMode Lazy 不会覆盖 ClassMap 设置