我们用于延迟加载图片的当前方法是:
服务器端模板将所有图像元素呈现为:
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-src="http://static.com/img.jpg"
style="display: none;"
/>
当DOMContentLoaded
事件被触发时,JavaScript会检测视口中的<img />
个元素,并将src
属性值替换为data-src
的值。
问题:
在加载整个DOM之前,首页上的图像不会出现。由于这是一个非常大的页面(2MB HTML),因此在DOMContentLoaded
事件被触发之前需要大约3-5秒。
我正在寻找的是一个JavaScript解决方案,它可以让我在DOM中进行操作后立即加载前100个图像。
答案 0 :(得分:0)
我正在寻找的是一个能够让我的JavaScript解决方案 一旦可用,就加载前100个图像 DOM中的操作。
我实施的解决方案基本上就是这个。
我需要一个抽象延迟加载脚本来启用对页面上现有图像的重新索引。我将首先在文档中的其他任何内容之前同步加载此脚本。从JavaScript可以运行的那一刻起,脚本在尝试查找DOM中的所有图像元素并检查它们是否在视口中时启动一个间隔。如果视口中包含元素,则会尝试修改图像元素(data-src
到src
)。这段时间一直持续到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();
});