366

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

4

18 回答 18

207

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

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

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

您也可以通过查看浏览器开发人员工具的“网络”选项卡来检查它。

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

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

于 2012-08-28T11:50:34.927 回答
137

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

于 2013-03-11T19:01:46.887 回答
61

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

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

所以在进一步挖掘之后我发现了这个,它解释了每个浏览器如何处理加载基于 css display: none; 的 img 资产。

摘自博客文章:

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

Chrome-所有 8 个屏幕截图-* 已加载图像

Firefox-仅加载了 1 个屏幕截图-* 当前正在显示的图像

于 2014-04-09T18:28:02.880 回答
38

HTML5<picture>标签将帮助您根据屏幕宽度解析正确的图像源

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

即使有媒体查询解决方法,它也只有在图像被设置为 CSS 中的背景时才有用。

虽然我认为这个问题只有一个 JS 解决方案(延迟加载图片填充等),但似乎有一个很好的纯 HTML 解决方案,它是开箱即用的 HTML5。

那就是<picture>标签。

MDN是这样描述它的:

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

以下是如何使用它:

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

背后的逻辑

img仅当没有任何媒体规则适用时,浏览器才会加载标签的来源。当<picture>浏览器不支持该元素时,它将再次回退到显示img标签。

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

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

在有人过于退出之前,这是当前浏览器支持的<picture>

桌面浏览器

桌面浏览器支持

移动浏览器

移动浏览器支持

有关浏览器支持的更多信息,您可以在Can I use上找到。

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

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

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

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

你仍然可以使用一些 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像素图像(如果您多次使用它可以缓存)。但是请注意,如果<picture>浏览器不支持该标签,即使在桌面屏幕上,也不会显示实际图像(因此您肯定需要一个 polyfill 备份)。

于 2017-03-15T00:52:10.280 回答
13

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

于 2019-04-24T19:43:06.960 回答
10

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

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

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

如果显示设置为无,Opera 是唯一不会加载图像的浏览器。Opera 现在已经转移到 webkit 并且将渲染所有图像,即使它们的显示设置为无。

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

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

于 2012-08-28T11:54:33.793 回答
8

怪癖模式:图像和显示:无

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

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

于 2014-10-29T20:16:13.593 回答
8

如果 div 设置为“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>

于 2018-02-01T17:13:44.950 回答
6

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

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

<img src="https://cdn.test/img.jpg" loading="lazy">

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

MDN img 元素规范

于 2021-01-24T18:16:32.947 回答
5

如果您在 CSS 中将图像设置为 div 的背景图像,则当该 div 设置为“显示:无”时,图像将不会加载。

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

您可以为纯 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%)中为您的 <img> 块(以及背景图像)设置适当的高度:宽度比率。

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!

于 2016-01-06T20:46:40.240 回答
5

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

利用<img src="" srcset="">

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

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

于 2016-04-13T10:21:47.313 回答
3

为了防止获取资源,请使用<template>Web Components 的元素

于 2015-09-06T19:19:53.040 回答
2

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

于 2017-11-21T11:40:58.190 回答
2

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

但我想出了一个很好的解决方案。首先制作一个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

于 2017-05-24T09:06:35.827 回答
2

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

这是一个小片段:

.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 来显示和隐藏显示/可见性/不透明度,但图像仍在加载,这是我们想出的最安全的代码。

于 2016-11-29T11:06:02.583 回答
0

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

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

于 2015-11-27T10:05:38.907 回答
0

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

使用我写的这个 polyfill 来读取<noscript>IE8 中标签的内容

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

于 2016-03-11T15:39:34.190 回答
-3

将 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%;
    }
}

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

于 2017-01-31T03:35:18.377 回答