【问题标题】:load image asynchronous异步加载图片
【发布时间】:2013-04-06 15:46:24
【问题描述】:

如果我有如下图片标签:

<img src="myimage.jpg" />

如果我在其中添加“异步”:

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

图片会异步加载吗?

【问题讨论】:

    标签: html image asynchronous


    【解决方案1】:

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

    属性: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">
    

    进一步阅读

    View the pull request for the WHATWG spec

    Fallback JavaScript with notes about perhaps not using fallbacks

    【讨论】:

    • 既然这个被合并了,这个答案应该更新
    【解决方案2】:

    答案可能为时已晚,但最近遇到了同样的问题,控制台中的“灯塔”建议我应该遵循链接中提到的内容: enter link description here

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

      <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 脚本决定何时加载图像,而不是浏览器。

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

    希望对某人有所帮助:)

    【讨论】:

      【解决方案3】:

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

      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)
      })
        
      

      【讨论】:

      • 您建议的vanillaJS 库很受欢迎,但多年来一直有一些偶然的浏览器支持,所以很多人不会依赖它。 5 年前,我会推荐使用 jQuery,而不是讽刺。
      • @jpaugh 我想为上述替代方案添加更新的答案。我已经编辑了回答的措辞以反映:)
      【解决方案4】:

      虽然其他几个答案突出了异步获取图像的方法,但知道&lt;img /&gt; 标记支持作为提示浏览器的属性也可能会有所帮助可能 导致图像被异步解码。 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

      【讨论】:

        【解决方案5】:

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

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

        使用 jQuery(或者也可以使用纯 JavaScript)使用下面的代码(建议 here):

        <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>
        

        【讨论】:

        • 为什么没有评论就被否决了?代码就像一个魅力,并为 OP 提供了如何延迟加载他的内容的解决方案......
        • 窗口加载未准备好 dom。 jQuery(function($) { ... }) 将更快地加载图像。
        • @B2K,不利的一面是 DOM 读取会在稍后启动,并且用户在加载图像时仍然需要等待,这将是使用延迟加载的原因之一......使用&lt;img src="... 也会更快地加载它们......
        • 不应该是 lazysrc 而不是 lazyload 吗??
        • 这将像defer 一样工作,而不是async。两个属性有很大区别。
        【解决方案6】:

        我在 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"));
        });
        

        【讨论】:

          【解决方案7】:

          如果您使用的是 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 以使图像在加载时“弹出”。

          【讨论】:

          • 如果您不赞成您也发表评论,我们将不胜感激,这样我就可以知道您认为答案需要如何改进或修复。
          【解决方案8】:

          虽然@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>
          

          【讨论】:

            【解决方案9】:

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

            <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"/>
            

            【讨论】:

            【解决方案10】:
            <img async src="myimage.jpg" />
            

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

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

            【讨论】:

            【解决方案11】:
            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 中指定 widthheight),然后返回一些点,在JS中,设置图片的URL。

            【讨论】:

            • 在这之后我做了&lt;script async&gt;var mybg = new Image(); mybg.src="/dir/to/image/mybg.png";&lt;/script&gt;之前主要是css/js。它只加载一次图像文件。然后可以通过css或其他方式正常设置图像,如bg。它很少出现加载/部分,但有时会。
            • @iacchus async 属性不适用于内联 script 标签(没有 src)。
            猜你喜欢
            • 1970-01-01
            • 2012-10-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-04-07
            • 1970-01-01
            相关资源
            最近更新 更多