【问题标题】:Does "display:none" prevent an image from loading?“显示:无”是否会阻止图像加载?
【发布时间】:2012-08-22 22:02:42
【问题描述】:

每个响应式网站开发教程都建议使用display:none CSS 属性来隐藏移动浏览器加载的内容,从而加快网站加载速度。这是真的吗? display:none 不加载图像还是仍然在移动浏览器上加载内容?有什么方法可以防止在移动浏览器上加载不必要的内容?

【问题讨论】:

标签: css responsive-design


【解决方案1】:

浏览器变得越来越智能。今天你的浏览器(取决于版本)可能会跳过加载图像,如果它可以确定它没有用。

图像具有display:none 样式,但脚本可以读取其大小。 如果父级隐藏,Chrome v68.0 不会加载图像。

您可以在那里查看:http://jsfiddle.net/tnk3j08s/

您也可以通过查看浏览器开发者工具的“网络”标签来检查它。

请注意,如果浏览器位于小型 CPU 计算机上,则不必渲染图像(和布局页面)将使整个渲染操作更快,但我怀疑这在今天是否真的有意义。

如果您想阻止加载图像,您可以不将 IMG 元素添加到文档中(或将 IMG src 属性设置为 "data:""about:blank")。

【讨论】:

  • 空图像 src 很危险。它向服务器发送一个额外的请求。好好读一下这个话题nczonline.net/blog/2009/11/30/…
  • @SrinivasYedhuri 是的,你是对的。我编辑了一个更好的解决方案。
  • 这个答案只是部分正确。我刚刚在谷歌浏览器(v35)上测试了这个,我可以确认没有下载显示设置为无的图像。这可能是为了让开发人员更轻松地进行响应式设计。
  • 这个答案不再正确。有关各种浏览器(包括最新版本的 FF)如何以不同方式处理这种情况的更新结果,请参见下文
  • 即使在今天(2017 年 10 月),最常见的浏览器 Chrome 也会下载所有“img”元素源,即使它们是隐藏的。它不会下载隐藏的背景图片。
【解决方案2】:

是的,它会渲染得更快一点,只是因为它不必渲染图像并且在屏幕上排序的元素少了一个。

如果您不想加载它,请将 DIV 留空,以便稍后将包含 <img> 标记的 html 加载到其中。

尝试使用我之前提到的 firebug 或 wireshark,您会发现即使存在 display:none,文件也会被传输。

Opera 是唯一一个在 display 设置为 none 时不会加载图像的浏览器。 Opera 现在已迁移到 webkit 并且将呈现所有图像,即使它们的 display 设置为 none。

这是一个可以证明这一点的测试页面:

http://www.quirksmode.org/css/displayimg.html

【讨论】:

    【解决方案3】:

    如果您在 CSS 中将图像设置为 div 的背景图像,则当该 div 设置为“display: none”时,图像将不会加载。当 CSS 被禁用时,它仍然不会加载,因为 CSS 被禁用了。

    【讨论】:

    • 在我看来,这实际上是一个非常有用的响应式设计技巧。
    • 这适用于 FF、Chrome、Safari、Opera、Maxthon。我没试过任何IE。
    • 从正面突破! <div hidden style="display:none;width:0;height:0;visibility:hidden;background:url('test.jpg')"></div>。结果:无法加载 Firefox 29 和 Opera 12。 IE 11 和 Chrome 34 加载。
    • @CoolCmd 对于响应式设计,这仍然是一个可行的选择,因为您可以在 CSS 媒体查询中将 background-image 设置为 none,以应对您不希望加载图像的情况。对于这个不使用 JS 的用例,还没有找到更好的替代方案。
    • 我测试了一个具有最小宽度媒体查询的图像滑块(使用背景图像)。低于该宽度,父 div 的 CSS display: none;。窗口低于该宽度的网络测试:Chrome 35、IE11 和 Edge 未加载图像
    【解决方案4】:

    答案并不像简单的是或否那么简单。查看我最近进行的一项测试的结果:

    • 在 Chrome 中:所有 8 张截图-* 图像已加载 (img 1)
    • 在 Firefox 中:仅加载了 1 张截图-* 当前正在显示的图像 (img 2)

    所以在进一步挖掘之后我找到了this,它解释了每个浏览器如何处理加载基于css显示的img资源:无;

    摘自博文:

    • Chrome 和 Safari (WebKit):
      WebKit 每次都会下载文件,除非通过不匹配应用背景 媒体查询。
    • Firefox:
      如果样式被隐藏,Firefox 将不会下载使用背景图像调用的图像,但它们仍会下载资源 来自 img 标签。
    • Opera:
      与 Firefox 一样,Opera 不会加载无用的背景图像。
    • Internet Explorer:
      IE,像 WebKit 一样会下载背景图像,即使它们有 display: none; IE6 出现了一些奇怪的东西:带有背景图像和显示的元素:不会下载内联设置...但它们将是 如果这些样式未内联应用。

    【讨论】:

    • 只要这些结果不是标准的一部分,它们就毫无意义。 Chrome 改变了渲染引擎,Opera 也改变了,IE 将被其他东西取代。你不能指望像这样的边缘功能的实现会随着时间的推移保持稳定。该解决方案将是一种提示浏览器何时应该延迟加载资产的方法。
    • @MarkKaplun 我并不是说这些测试结果应该准确地向您展示每个浏览器始终会发生的事情。我只是想证明答案“不像是或否那么简单”。每个浏览器目前正在以不同的方式实现这一点,并且可能会继续这种方式一段时间
    • @DMTintner 完全正确。就在今天,我可以确认 iOS Safari 加载的 div 的背景图像是“显示:无”。最好的方法是不要假设任何东西,如果您不想加载图像,请不要在 html 标记中引用它
    【解决方案5】:

    Quirks Mode: images and display: none

    当图像具有display: none 或位于具有 display:none,浏览器可能会选择不下载图像,直到display 设置为另一个值。

    当您将display 切换为block 时,只有 Opera 会下载图像。 所有其他浏览器都会立即下载。

    【讨论】:

      【解决方案6】:

      为防止获取资源,请使用<template> element of Web Components

      【讨论】:

      • 您能否更详细地解释一下这是如何工作的?
      【解决方案7】:

      我们说的是无法在移动设备上加载的图片,对吧?那么如果你只是做了一个@media (min-width: 400px){background-image:thing.jpg}

      那不是只在某个屏幕宽度以上寻找图像吗?

      【讨论】:

        【解决方案8】:

        If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.

        只是扩展布伦特的解决方案。

        您可以对纯 CSS 解决方案执行以下操作,它还可以使 img 框在响应式设计设置中实际上表现得像一个 img 框(这就是透明 png 的用途),如果您的设计使用响应式,这尤其有用- 动态调整图像大小。

        <img style="display: none; height: auto; width:100%; background-image: 
        url('img/1078x501_1.jpg'); background-size: cover;" class="center-block 
        visible-lg-block" src="img/400x186_trans.png" alt="pic 1 mofo">
        

        只有在触发与 visible-lg-block 相关的媒体查询并将 display:none 更改为 display:block 时才会加载图像。透明 png 用于允许浏览器在流畅的设计(高度:自动;宽度:100%)中为您的 块(以及背景图像)设置适当的高度:宽度比率。

        1078/501 = ~2.15  (large screen)
        400/186  = ~2.15  (small screen)
        

        因此,对于 3 个不同的视口,您最终会得到以下内容:

        <img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
        <img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
        <img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">
        

        在初始加载期间仅加载默认媒体视口大小的图像,然后根据您的视口动态加载图像。

        而且没有 javascript!

        【讨论】:

          【解决方案9】:

          另一种可能性是使用&lt;noscript&gt; 标签并将图像放在&lt;noscript&gt; 标签内。然后根据需要使用 javascript 删除 noscript 标签。通过这种方式,您可以使用渐进增强按需加载图像。

          使用我写的这个polyfill来读取IE8中&lt;noscript&gt;标签的内容

          https://github.com/jameswestgate/noscript-textcontent

          【讨论】:

            【解决方案10】:

            如果是这样,有没有办法不在移动设备上加载不必要的内容 浏览器?

            使用&lt;img src="" srcset=""&gt;

            http://www.webdesignerdepot.com/2015/08/the-state-of-responsive-images/

            https://caniuse.com/#feat=srcset

            【讨论】:

            【解决方案11】:

            使用@media query CSS,基本上我们只是发布了一个项目,在该项目中,我们在旁边的桌面上有一个巨大的树图像,但没有显示在桌面/移动屏幕上。所以防止图像加载很容易

            这是一个小sn-p:

            .tree {
                background: none top left no-repeat; 
            }
            
            @media only screen and (min-width: 1200px) {
                .tree {
                    background: url(enormous-tree.png) top left no-repeat;
                }
            }
            

            您可以使用相同的 CSS 来显示和隐藏显示/可见性/不透明度,但图像仍在加载,这是我们想出的最安全的代码。

            【讨论】:

              【解决方案12】:

              对图像使用 display:none 的技巧是为它们分配一个 id。这是因为不需要很多代码就可以让它工作。这是一个使用媒体查询和 3 个样式表的示例。一种用于手机,一种用于平板电脑,一种用于台式机。我有 3 张图片,手机、平板电脑和台式机的图片。手机屏幕上只会显示手机的图像,平板电脑只会显示平板电脑的图像,桌面会显示桌面计算机的图像。 这是一个使其工作的代码示例:

              源代码:

              <div id="content">
              <img id="phone" src="images/phone.png" />
              <img id="tablet" src="images/tablet.png" />
              <img id="desktop" src="images/desktop.png" />
              </div>
              

              不需要媒体查询的手机 CSS。它的 img#phone 使它工作:

              img#phone {
                  display: block;
                  margin: 6em auto 0 auto;
                  width: 70%;
                  }
              
              img#tablet {display: none;}
              img#desktop {display: none;}
              

              平板电脑CSS:

              @media only screen and (min-width: 641px) {
              img#phone {display: none;}
              
              img#tablet {
                  display: block;
                  margin: 6em auto 0 auto;
                  width: 70%;
                  }
              }
              

              还有桌面css:

              @media only screen and (min-width: 1141px) {
              img#tablet {display: none;}
              
              img#desktop {
                  display: block;
                  margin: 6em auto 0 auto;
                  width: 80%;
                  }
              }
              

              祝你好运,让我知道它是如何为你工作的。

              【讨论】:

              • 问题不在于如何在图像上设置display: none。它是:“display:none”是否会阻止图像加载?
              • 这不是一个有效的解决方案,因为许多浏览器仍然会加载图像源,即使用户无法通过 CSS 看到它们。无论如何,这仍然不是一个好的策略。有很多更好的方法可以为不同的设备提供不同的图像,这也是对元素 ID 的完全不必要的滥用。
              【解决方案13】:

              HTML5 &lt;picture&gt; 标签将帮助您根据屏幕宽度解析正确的图像源

              显然浏览器的行为在过去 5 年没有太大变化,许多人仍然会下载隐藏的图像,即使它们上设置了 display: none 属性。

              即使有 media queries 解决方法,它也只能在图像在 CSS 中设置为背景时才有用。

              虽然我认为只有一个 JS 解决方案(lazy loadpicturefill 等),但似乎有一个很好的纯 HTML 解决方案,它是开箱即用的 HTML5。

              这就是&lt;picture&gt; 标签。

              MDN 是这样描述它的:

              HTML &lt;picture&gt; 元素 是一个容器,用于为其中包含的特定&lt;img&gt; 指定多个&lt;source&gt; 元素。浏览器会根据页面的当前布局(图像出现的框的约束)和显示的设备(例如普通或hiDPI设备)选择最合适的来源。

              下面是如何使用它:

              <picture>
               <source srcset="mdn-logo-wide.png" media="(min-width: 600px)">
               <img src="mdn-logo-narrow.png" alt="MDN">
              </picture>
              

              背后的逻辑

              浏览器会加载img标签的来源,只有在没有任何媒体规则适用的情况下。当浏览器不支持&lt;picture&gt; 元素时,它会再次回退到显示img 标签。

              通常您会将最小的图像作为&lt;img&gt; 的来源,因此不会为较大的屏幕加载重图像。反之亦然,如果应用了媒体规则,则不会下载&lt;img&gt; 的来源,而是会下载对应&lt;source&gt; 标签的url 内容。

              这里唯一的陷阱是,如果浏览器不支持该元素,它只会加载小图像。 另一方面,在 2017 年,我们应该以移动优先的方式进行思考和编码。

              在有人过于退出之前,这是对&lt;picture&gt;当前浏览器支持:

              桌面浏览器

              移动浏览器

              有关浏览器支持的更多信息,请访问 Can I use

              好在html5please 的句子是将它与后备一起使用。我个人打算听取他们的建议。

              您可以在W3C's specification 中找到有关该标签的更多信息。那里有一个免责声明,我觉得很重要:

              picture 元素与外观相似的videoaudio 元素有些不同。虽然它们都包含source 元素,但当元素嵌套在picture 元素中时,源元素的src 属性没有意义,并且资源选择算法不同。同样,picture 元素本身不显示任何内容;它只是为其包含的 img 元素提供一个上下文,使其能够从多个 URL 中进行选择。

              所以它的意思是,它只是通过为图像提供一些上下文来帮助您提高加载图像时的性能。

              您仍然可以使用一些 CSS 魔法来隐藏小型设备上的图像:

              <style>
                picture { display: none; }
              
                @media (min-width: 600px) {
                  picture {
                    display: block;
                  }
                }
              </style>
              
              <picture>
               <source srcset="the-real-image-source" media="(min-width: 600px)">
               <img src="a-1x1-pixel-image-that-will-be-hidden-in-the-css" alt="MDN">
              </picture>
              

              因此,浏览器将不显示实际图像,并且只会下载1x1 像素图像(如果您多次使用它可以缓存)。但是请注意,如果浏览器不支持&lt;picture&gt; 标签,即使在桌面屏幕上,实际图像也不会显示(所以你肯定需要一个 polyfill 备份) .

              【讨论】:

              【解决方案14】:

              大家好,我正在为同样的问题苦苦挣扎,如何不在移动设备上加载图片。

              但我想出了一个很好的解决方案。首先制作一个img标签,然后在src属性中加载一个空白svg。现在您可以将图像的 URL 设置为带有内容的内联样式:url('link to your image');。现在将您的 img 标签包装在您选择的包装器中。

              <div class="test">
                <img src="data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/‌​svg%22/%3E" style="content:url('https://blog.prepscholar.com/hubfs/body_testinprogress.gif?t=1495225010554')">
              </div>
              
                @media only screen and (max-width: 800px) {
                    .test{
                     display: none;
                    }
                  }
              

              将包装器设置为在您不想加载图像的断点上不显示。现在忽略 img 标记的内联 css,因为包装在具有 display none 的包装器中的元素的样式将被忽略,因此不会加载图像,直到到达包装器具有显示块的断点。

              你去吧,不用在移动断点上加载 img 的非常简单的方法 :)

              查看此代码笔,以获取工作示例:http://codepen.io/fennefoss/pen/jmXjvo

              【讨论】:

              • 我喜欢网络如何不断发展,以前没见过这个技巧,使用content-property 来改变显示的图像,就是这样。你能提供一些关于兼容性的统计数据吗?
              • Edge :/ 太糟糕了,至少它可以在最新版本的 Firefox、Chome 和 Safari 中运行。
              【解决方案15】:

              不。如果您考虑节省手机用户带宽,图像将照常加载并且仍将使用用户的带宽。您可以做的是使用媒体查询并过滤您希望图像成为的设备已加载。您的图片必须设置为 div 等的背景图片,而不是标签,因为无论屏幕大小和媒体查询设置如何,图片标签都会加载图片。

              【讨论】:

                【解决方案16】:

                如果 div 设置为 do 'display:none',则 div 元素的背景图像将加载

                无论如何,如果同一个 div 有一个父级并且该父级设置为 'display:none',则子元素的背景图像将不会加载。 :)

                使用引导程序的示例:

                <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
                
                
                <div class="col-xs-12 visible-lg">
                	<div style="background-image: url('http://via.placeholder.com/300x300'); background-repeat:no-repeat; height: 300px;">lg</div>
                </div>
                <div class="col-xs-12 visible-md">
                	<div style="background-image: url('http://via.placeholder.com/200x200'); background-repeat:no-repeat; height: 200px;">md</div>
                </div>
                <div class="col-xs-12 visible-sm">
                	<div style="background-image: url('http://via.placeholder.com/100x100'); background-repeat:no-repeat; height: 100px">sm</div>
                </div>
                <div class="col-xs-12 visible-xs">
                	<div style="background-image: url('http://via.placeholder.com/50x50'); background-repeat:no-repeat; height: 50px">xs</div>
                </div>

                【讨论】:

                  【解决方案17】:

                  ** 2019 年答案 **

                  在正常情况下display:none 不会阻止图片被下载

                  /*will be downloaded*/
                  
                  #element1 {
                      display: none;
                      background-image: url('https://picsum.photos/id/237/100');
                  }
                  

                  但是如果一个祖先元素有display:none,那么后代的图片就不会被下载

                  
                  /* Markup */
                  
                  <div id="father">
                      <div id="son"></div>
                  </div>
                  
                  
                  /* Styles */
                  
                  #father {
                      display: none;
                  }
                  
                  /* #son will not be downloaded because the #father div has display:none; */
                  
                  #son {
                      background-image: url('https://picsum.photos/id/234/500');
                  }
                  

                  其他阻止图片下载的情况:

                  1- 目标元素不存在

                  /* never will be downloaded because the target element doesn't exist */
                  
                  #element-dont-exist {
                      background-image: url('https://picsum.photos/id/240/400');
                  }
                  

                  2- 两个相同的类加载不同的图像

                  /* The first image of #element2 will never be downloaded because the other #element2 class */
                  
                  #element2 {
                      background-image: url('https://picsum.photos/id/238/200');
                  }
                  
                  /* The second image of #element2 will be downloaded */
                  
                  #element2 {
                      background-image: url('https://picsum.photos/id/239/300');
                  }
                  

                  您可以在这里观看:https://codepen.io/juanmamenendez15/pen/dLQPmX

                  【讨论】:

                  • 这仅在图像是孩子的背景时才有效。如果你有一个子 &lt;img&gt; 元素,它仍然会加载我所看到的源代码(Chrome v90)。
                  【解决方案18】:

                  即使后者被display: none 属性直接或间接隐藏,浏览器似乎仍会下载图像。

                  我发现防止这种情况发生的唯一标准方法是使用img 标签的loading 属性:

                  &lt;img src="https://cdn.test/img.jpg" loading="lazy"&gt;

                  所有最新的浏览器都支持它,除了 Safari 和 Firefox Android。

                  MDN img element specification.

                  【讨论】:

                  • 谢谢,这是我在 FF 86 上的用例的唯一方法。
                  猜你喜欢
                  • 2019-05-19
                  • 2010-12-12
                  • 2023-03-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-08-08
                  • 1970-01-01
                  相关资源
                  最近更新 更多