37

我正在创建一个包含大量大尺寸图像的页面,所以我自然想确保页面加载没有太多麻烦。我在这里阅读了这篇文章http://24ways.org/2010/speed-up-your-site-with-delayed-content

延迟的方法如下(从页面拉,不要介意URL)

<div>
    <h4>
        <a href="http://allinthehead.com/" data-gravatar-hash="13734b0cb20708f79e730809c29c3c48">
            Drew McLellan
        </a>
    </h4>
</div>

然后稍后一段 js 负责图像加载

$(window).load(function() {
    $('a[data-gravatar-hash]').prepend(function(index){
        var hash = $(this).attr('data-gravatar-hash')
        return '<img width="100" height="100" alt="" src="http://www.gravatar.com/avatar.php?size=100&amp;gravatar_id=' + hash + '">'
    });
});

我不打算对每张图片都这样做,但绝对是对一些我不需要它在页面加载时显示的图片。

这是最好的方法还是有更好的方法通过延迟图像来实现更快的页面加载?

谢谢

4

5 回答 5

64

有点晚了,但如果它有利于其他人,Patrick Sexton 有一篇关于这个主题的精彩文章 https://varvy.com/pagespeed/defer-images.html

他基本上是在建议同样的事情,仅通过使用微小的 base 64 编码图像,他可以将他的图像标签直接放在 HTML 中,这具有能够单独控制诸如高度、宽度、alt 等属性的好处。与在脚本中创建整个图像标签相比,以这种方式维护 HTML 会容易得多。

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="image1.jpg" alt="image 1">
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="image2.jpg" alt="image 2">

然后您的脚本对于所有图像都很简单且通用

<script>
function init() {
  var imgDefer = document.getElementsByTagName('img');
  for (var i = 0; i < imgDefer.length; i++) {
    if (imgDefer[i].getAttribute('data-src')) {
      imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
    }
  }
}

window.onload = init;
</script>
于 2015-05-26T13:33:29.110 回答
5

这似乎是延迟图像的非常干净的方式。唯一的潜在问题是图像是否携带重要信息,因为“数据属性是 HTML5 中的新功能”。

另一种选择可能是将图像放在正文的末尾并使用 CSS 来定位它们。我个人会坚持使用javascript。

于 2012-09-12T21:29:14.760 回答
2

这是一个展示的版本.querySelectorAll

function swapSrcAttributes(source) {
  return function(element) {
    element.setAttribute('src', element.getAttribute(source));
  }
}

function forEach(collection, partial) {
  for (var i = 0; i < collection.length; i++) {
     partial(collection[i]);
  }
}

function initDeferImages() {
  // for images
  var deferImages = document.querySelectorAll('img[data-src]');

  // or you could be less specific and remove the `img`
  deferImages = document.querySelectorAll('[data-src]');

  forEach(deferImages, swapSrcAttributes('data-src'));
}

window.onload = function() {
  initDeferImages();
}

这是.querySelector.querySelectorAll通过https://caniuse.com/#feat=queryselector的兼容性表

于 2017-11-18T07:19:05.853 回答
1

html

<img
    width="1024"
    src="https://placehold.it/64x48.jpg"
    data-src-defer="https://images.unsplash.com/photo-1570280406792-bf58b7c59247?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1486&q=80"
    alt="image 1"
/>
            
<img
    width="1024"
    src="https://placehold.it/64x48.jpg"
    data-src-defer="https://images.unsplash.com/photo-1557053964-d42e8e29cb27?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1500&q=80"
    alt="image 2"
/>

JS

function deferImgs() {
    Array
    .from(document.querySelectorAll("img[data-src-defer]"))
    .forEach((element) => {
        element.setAttribute("src", element.dataset.srcDefer);
        });
}
    
window.addEventListener("load", deferImgs());

==================================================== ===============

我正在尝试通过此编辑来满足 Farrukh 的要求。

我尽力做到最好,但不幸的是英语只是我说的第三语言。而且我不是语言天才。:D

这个 js 代码片段说明了一些大图片的延迟加载。这不是一个实际的实现。图像之间的尺寸差异是故意巨大的。这是因为测试必须是说明性的。您可以通过浏览器开发工具页面监控其运行情况。F12 > 网络选项卡 > 速度设置下拉列表 测试的理想网络速度在 1 - 3MB/s 之间(网络速度有些慢)。您可能需要多次运行测试,因此您可以看到,在这种情况下,加载图像的顺序不受控制,而是取决于传输。因为它不受监管,所以无法预测哪个图像会先到达。

我们首先将一个小图像加载到一个大占位符中。(图片:64x48.jpg > 占位符宽度=“1024”)。

querySelectorAll() 方法返回一个静态节点列表。乍一看,这个节点列表看起来像一个数组,但事实并非如此。

这是一个类似数组的对象:

document.querySelectorAll("img[data-src-defer]")

Array.from() 方法可以从这个对象创建一个新的数组实例。现在可以在这个数组上执行 forEach 方法。forEach() 方法为数组的每个元素执行一次提供的函数。

在这种情况下,数组的每个元素都被传递给这个函数一次:

(element) => {
        element.setAttribute("src", element.dataset.srcDefer);
        }

此函数将图像标签的 src="" 属性的值设置为同一图像标签的数据集的值。

src="https://placehold.it/64x48.jpg";

data-src-defer="https://images.unsplash.com/photo-1570280406792-bf58b7c59247?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1486&q=80";

src = data-src-defer;

So finally:

src="https://images.unsplash.com/photo-1570280406792-bf58b7c59247?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1486&q=80";
于 2021-02-20T20:09:41.183 回答
0

您可以像下面的示例一样简单地做到这一点:

所有图像都具有data-src放置文件路径的属性。并src带有一个假的透明 1x1px png 图像的属性。您还可以添加loading属性设置为lazy,它告诉现代浏览器避免立即加载超出视口(可见站点区域)的图像

<img data-src="path/to/image.jpg" loading="lazy"
     src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" />

添加此脚本以使所有图像在src您的网站加载后都获得该属性(您需要jQuery才能使其工作)

$(function(){
    $("img[data-src]").attr("src", function(){ return $(this).data("src"); });
});
于 2021-05-27T08:28:45.953 回答