我有很多图像。当滚动到视图时,如何使它们按需延迟加载?

问题描述 投票:1回答:1

有时我从服务器加载大量HTML,或者作为初始文档的一部分,或者作为AJAX。其他时候,我将HTML动态插入文档中。

问题是此HTML通常包含很多图像。例如,在社交网络上,您可能拥有大量带有照片的用户头像。这导致向服务器发送大量请求。

我知道我可以使用HTTP / 2来管道这些请求,但是仍然不需要从服务器上实际获取所有这些文件,直到它们滚动到视图中为止。我该怎么办?

javascript html performance google-pagespeed
1个回答
1
投票

首先,对于任何图标,如按钮等,您应该为loading and using a font with CSS, or for more flexibility, just SVG。但是,您仍会留下想要在页面上呈现的各种照片和用户生成的内容。

感谢现代Web的新功能,现在我们可以懒加载那些吸盘了!我们将使用Intersection Observer APIObject.defineProperty覆盖图像在运行时可能进入文档的各种方式。

这是将为您完成的代码。您可以将其复制粘贴到Javascript文件中,然后从文档中包含该文件。或者您也可以分析它,学习并告诉我我错过了什么:

(函数(){var Elp = Element.prototype;var观察者=新的IntersectionObserver(函数(条目,观察者){entry.forEach(函数(条目){如果(!entry.target || entry.target.tagName.toUpperCase()!=='IMG'){返回;}var img = entry.target;var rect = entry.intersectionRect;var src = img.getAttribute('data-defer-src');if(src && rect.width> 0 && rect.height> 0){img.setAttribute('src',src);img.removeAttribute('data-defer-src');}});},{root:null,rootMargin:'0px',阈值:0});//观察页面上已有的内容(函数(){var imgs = document.body.getElementsByTagName('img');imgs = Array.from(imgs);imgs.forEach(功能(img){rator.observe(img);});})();//覆盖innerHTMLvar originalSet = Object.getOwnPropertyDescriptor(Elp,'innerHTML')。set;var originalGet = Object.getOwnPropertyDescriptor(Elp,'innerHTML')。get;Object.defineProperty(Elp,'innerHTML',{设置:功能(html){var element = document.createElement('div');originalSet.call(element,html);var imgs = element.getElementsByTagName('img');var found = false;imgs = Array.from(imgs);imgs.forEach(功能(img){var src = img.getAttribute('src');如果(src){img.setAttribute('data-defer-src',src);img.removeAttribute('src');发现=真;}});如果(!找到){originalSet.call(this,html);返回html;}originalSet.call(this,originalGet.call(element));var imgs2 = this.getElementsByTagName('img');imgs2 = Array.from(imgs);imgs2.forEach(function(img){rator.observe(img);});},得到:originalGet});//覆盖任何插入元素的方法['insertBefore','appendChild']。forEach(function(fn){var orig = Elp [fn];Elp [fn] =函数(元素){var imgs = null;如果(!element){返回;}如果(element.tagName && element.tagName.toUpperCase()==='IMG'){imgs = [element];}其他{imgs = element.getElementsByTagName('img');}var found = false;imgs.forEach(功能(img){var src = img.getAttribute('src');如果(src){img.setAttribute('data-defer-src',src);img.removeAttribute('src');rator.observe(img);发现=真;}});返回orig.apply(this,arguments);};});})();

奖励点,如果您可以调整服务器以呈现<img data-defer-src="{{url here}}" alt="{{description here}}" title="{{title here}}">而不是<img src="{{url here}}" alt="{{description here}}" title="{{title here}}">。因为所有浏览器中都有no reliable way可以通过

将图像插入DOM后对其进行拦截。
© www.soinside.com 2019 - 2024. All rights reserved.