45

如果我有如下图像标签:

<img src="myimage.jpg" />

如果我向它添加“异步”:

<img async src="myimage.jpg" />

图像会异步加载吗?

4

11 回答 11

47

异步加载(延迟加载)内容的方法是不设置“src”属性,然后在启动 DOM 就绪后执行加载图像的脚本。

 <img data-lazysrc='http://www.amazingjokes.com/images/20140902-amazingjokes-title.png'/>

并使用 jQuery(或者也可以使用纯 JavaScript)使用下面的代码(这里建议的那样):

<script>  
function ReLoadImages(){
    $('img[data-lazysrc]').each( function(){
        //* set the img src from data-src
        $( this ).attr( 'src', $( this ).attr( 'data-lazysrc' ) );
        }
    );
}

document.addEventListener('readystatechange', event => {
    if (event.target.readyState === "interactive") {  //or at "complete" if you want it to execute in the most last state of window.
        ReLoadImages();
    }
});
</script>
于 2016-05-24T11:15:47.457 回答
32
var img = new Image(),
    url = "myimg.jpg",
    container = document.getElementById("holder-div");

img.onload = function () { container.appendChild(img); };
img.src = url;

一旦您在脚本中请求它,这将开始加载图像,并且每当图像完成加载时,它都会抓取并将图像添加到其中。

还有很多其他方法可以做到这一点......
这只是异步加载单个图像的一个非常简单的示例。

但道理是这样的:
要使异步加载正常工作,要么在 JavaScript 中加载它并使用 onload,要么在页面上包含图像标签,不带src属性(在 HTML 中指定widthand height),然后返回某个时间点,在JS,并设置图像URL。

于 2013-04-14T14:56:46.873 回答
16

执行此操作的现代方法是使用loading图像和 iframe 的属性。

属性:loading=lazy

这将延迟内容的加载,直到元素到达与视口的计算距离(这只是意味着,用户很可能会将其滚动到视图中)。

<img src="defer.png" loading="lazy" alt="An Awesome Image" width="500" height="400">

将属性设置为lazy调用新行为。

自 v76 以来,这已经在 Chromium 中,但可能不会在非 Chromium 浏览器中使用,直到它通过通常的规范恶作剧。

如果您要使用脚本延迟加载,则值得使用lazy属性编写图像并填充行为而不是使用类名等。这样,您可以允许本机版本接管为它变得可用。

强制预加载

自动延迟加载可能会成为轻量级浏览的一项功能,在这种情况下,您可能希望执行相反的操作并强制加载图像。您可以使用loading具有值的相同属性eager来要求浏览器抓取图像,即使它可能选择不抓取。

<img src="defer.png" loading="eager" alt="An Awesome Image" width="500" height="400">

进一步阅读

查看 WHATWG 规范的拉取请求

后备 JavaScript 以及可能不使用后备的注释

于 2019-09-16T13:19:47.320 回答
10

异步加载图像的另一种方法是 Promise在 javascript 中使用,它的目的是异步执行操作。

function asyncImageLoader(url){
    return new Promise( (resolve, reject) => {
        var image = new Image()
        image.src = url
        image.onload = () => resolve(image)
        image.onerror = () => reject(new Error('could not load image'))
    })
}    

// then use it like this

var image = asyncImageLoader(url)


image.then( res => {
    console.log(res)
})
  
于 2018-10-25T06:21:03.267 回答
8
<img async src="myimage.jpg" />

图片标签不支持任何异步属性。

http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element

于 2013-04-14T13:57:05.170 回答
4

虽然其他几个答案突出了异步获取图像的方法,但知道<img />标签支持一个属性可能会有所帮助,该属性可以作为浏览器的提示,可能导致图像被异步解码。Internet Explorer 似乎不支持它。

<img src="myimage.jpg" decoding="async"/>

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-decoding

https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding

https://github.com/whatwg/html/issues/1920

于 2019-08-16T22:07:15.320 回答
3

如果您使用的是 jQuery,我做了一些简单但有效的操作,如下所示:

HTML

<div data-lazy-load-image="/Images/image-name.png" data-image-classname="pop-in"></div>

JavaScript

$(function () {
    $("[data-lazy-load-image]").each(function (index, element) {
        var img = new Image();
        img.src = $(element).data("lazy-load-image");
        if (typeof $(element).data("image-classname" !== "undefined"))
            img.className = $(element).data("image-classname");
        $(element).append(img);
    });
});

CSS

@-webkit-keyframes pop-in {
    0% { opacity: 0; -webkit-transform: scale(0.5); }
    100% { opacity: 1; -webkit-transform: scale(1); }
}
@-moz-keyframes pop-in {
    0% { opacity: 0; -moz-transform: scale(0.5); }
    100% { opacity: 1; -moz-transform: scale(1); }
}
@keyframes pop-in {
    0% { opacity: 0; transform: scale(0.5); }
    100% { opacity: 1; transform: scale(1); }
}

您可以扩展它以包含每个图像的其他可选属性,但您明白了。

这将等到 DOM 准备好,然后动态(异步)将图像加载到您使用该data-lazy-load-image属性标记的元素中。我包含了 CSS 以使图像在加载时“弹出”。

于 2016-01-29T17:41:17.250 回答
2

虽然@Norguard 的示例对于一两个图像来说非常简单易行,但我发现 echo.js 对于延迟加载非常方便,https://github.com/toddmotto/echo

它可以延迟加载带有 data-* 属性的图像,并且还提供了一些简洁的其他功能。

<img data-echo="img/photo.jpg">
<script src="dist/echo.js"></script>
<script>
    echo.init();
</script>
于 2016-01-02T23:47:55.880 回答
1

我在 jQuery 中使用了以下方法。

首先,不要在图像标签中使用“src”属性,而是将您的源放入不同的属性中,如下所示:

<img async-src="/mydirectory/myimage.jpg" />

然后,在 jQuery 文档就绪函数中,我使用以下代码将元素的 async-src 复制到元素的实际 src:

$("img[async-src]").each(function(index) {
    $(this).attr("src", $(this).attr("async-src"));
});

笔记:

jQuery 的 .each 函数可以按照它们在 HTML/DOM 中编码的顺序处理标签,但是图像大小和网络问题可能意味着图像实际上并没有按顺序加载。换句话说,您的第三个 async-src 图像可能会在第一个完成加载之前出现在屏幕上。

如果您的页面布局依赖于该图像文件的像素尺寸——例如,您没有通过标签属性、CSS 或父元素定义图像的尺寸——那么您可能必须在原始文件指向上使用“src”属性转换为所需尺寸的空白或透明 GIF。

最后,如果你想在异步加载图像之后处理一些代码——例如,处理渐变效果或更改与元素相关的 CSS 标签——像这样展开 jQuery:

$("img[async-src]").each(function(index) {
    $(this).load(function() {
        // code to run after loading
    });
    $(this).attr("src", $(this).attr("async-src"));
});
于 2019-04-26T19:06:46.020 回答
1

答案可能为时已晚,但最近面临同样的问题,控制台中的“灯塔”建议我应该遵循链接中提到的内容:在此处 输入链接描述

基本上,我按照建议做了以下操作,效果非常好:

  <script src="lazysizes.min.js" async></script>
  <!-- Images End -->
</body>

您可以从https://raw.githubusercontent.com/aFarkas/lazysizes/gh-pages/lazysizes.min.js下载lazysizes.min.js

并在本地采购。

然后,将类lazyload 添加到应该延迟加载的图像中。此外,将 src 属性更改为 data-src。

例如:

<img data-src="images/flower3.png" class="lazyload" alt="">

您可能想知道为什么需要将 src 属性更改为 data-src。如果不更改此属性,则所有图像将立即加载,而不是延迟加载。data-src 不是浏览器识别的属性,所以当它遇到具有该属性的图像标签时,它不会加载图像。在这种情况下,这是一件好事,因为它允许lazysizes 脚本决定何时加载图像,而不是浏览器。

访问参考以获得更好的理解。

希望它会对某人有所帮助:)

于 2020-11-14T13:22:12.630 回答
0

您可以阅读有关延迟加载属性的更多信息:

<img src="myimage.jpg" alt="some description" lazyload/> - with default values

或者您可以优先考虑:

<img src="myimage.jpg" alt="some description" lazyload="1"/>
<img src="myimage.jpg" alt="some description" lazyload="2"/>
于 2015-08-14T14:11:52.910 回答