1

原文链接:https://csswizardry.com/2018/...

背景资料

为了更好地控制产品主页缩略图的显示,(作者)团队选择了css的background-image而不是<img>标签;除了语义上的担忧,在样式的角度看,用css可以更好的控制图片在容器中的大小和位置;这种方式唯一值得商榷的是,当图片定义在css而不是html中时,图片的请求会在浏览器创建渲染树之后开始,也就是说直到css文件被下载、解析,并且浏览器得知cssDOM构造的这个class的div在当前页面上是可见,背景图片才会被下载。

下面瀑布流图片展示了:浏览器是在CSSOM加载完成后才开始发送图片请求,你可以清楚的看到css需求在任何图片开始之前完成。这可以得出一个结论:在CSSOM建立之前,浏览器不知道需要哪些图片。
背景图片无法下载,直到cssom完成

这对于用户希望能尽快看到并且有着重要内容的缩略图来说已经太晚了。

通过将图片放置到<img/>标签上能解决这个问题,浏览器能尽快发现这些img标签,语义上讲也更为合适。因为他们已经暴露在浏览器的预加载扫描器上,并且在cssom构建完成之前(或者是并行)去发出图片请求。
展示了img元素独立于cssom构建的下载规则

列举一下我们目前所知道的规则:

1.浏览器需要在构建好cssom之后再去下载background-image
2.浏览器不会延迟下载img标签上的图片(css不影响img标签图片的请求)

我开始在思考浏览器是怎么去处理可见或者不可见(display:none)的img图片,不可见的时候理想情况下应该是不要去下载这个图片,以节省请求;但问题是浏览器只有在cssom完成构建后才能知道图片是不是不可见,所以当图片不可见时浏览器是不是会放慢了img默认的下载行为呢?

background-imgae

先从研究浏览器对于background-image处理开始,因为这是我的产品初始案例。我觉得background-image的行为是最容易预测的,因为cssom总是在下载图片前构建好。

预测浏览器行为:

1.cssom构建完成前浏览器不能触发下载background-image图片
2.浏览器不会下载不可见(display:none)的background-image图片

实际浏览器行为:

  • chrome(v67.0.3396.79)
    1.和预测一样,cssom构建完成前浏览器不能触发下载background-image图片

clipboard.png

  2.出乎意料的是,浏览器还是会不可见(display:none)的background-image图片

clipboard.png

  • Safari (v11.1 (13605.1.33.1.4))
    1.和预测一样,cssom构建完成前浏览器不能触发下载background-image图片

clipboard.png

2.和预测一样,浏览器不会下载不可见(display:none)的background-image图片

clipboard.png

  • Firefox (v60.0.1)
    1.和预测一样,cssom构建完成前浏览器不能触发下载background-image图片

clipboard.png

2.和预测一样,浏览器不会下载不可见(display:none)的background-image图片

clipboard.png

  • Opera (v53.0.2907.68)
    1.和预测一样,cssom构建完成前浏览器不能触发下载background-image图片

clipboard.png

2.出乎意料的是,浏览器还是会不可见(display:none)的background-image图片

clipboard.png

  • Edge (v17.17134)
    1.和预测一样,cssom构建完成前浏览器不能触发下载background-image图片

clipboard.png

2.出乎意料的是,浏览器还是会不可见(display:none)的background-image图片  

clipboard.png

总结

YES 或者NO 代表实际结果,√和×代表时候符合预期(作者认为是浏览器这样做是表现更好的)和不符合预期
clipboard.png

  • firefox 和 safari在图片不可见的情况下不会去下载background-image的行为似乎是更可取的。
  • chrome,opera和edge会下载不可以见的backgroud-image感觉是浪费资源的,但我怀疑这是一个提前加载的优化,保证在使图片可见的潜在事件发生之前就做好准备。但我觉得如果真的是这样的话,这种优化行为应该交由开发者去处理。

<img/>

接下来看看浏览器是怎么处理<img/>
预测浏览器行为:

1.浏览器下载图片应该独立于cssom的构建。如果在cssom的构建中阻塞<img/>的请求效率是很低的,并且会导致延迟下载内容。
2.那么相应的浏览器就会下载不可见的img(display:none)。因为如果浏览器在cssom构建前开始下载img,它是没有办法知道这张图片是不是需要展示在页面上。

实际浏览器行为:

- Chrome 
    1.和预测一样,浏览器下载图片应该独立于cssom的构建     

clipboard.png

    2.和预测一样,浏览器会先下载后再把图片隐藏

clipboard.png

  - safri
      1.和预测一样,safari没有阻塞img请求        

clipboard.png

      2.和预测一样,浏览器会先下载后再把图片隐藏

clipboard.png

    - firefox
        1.出人意料的是,火狐会等到cssom构建完成才去请求img,这是令人惊讶的低效率。     

clipboard.png

        2.出人意料的是,尽管火狐是等到cssom构建完才去请求img,也就是说它可以知道img不可见,还是会去下载img。我觉得非常奇怪,这两个方面都是非常低效率的。           

clipboard.png

       - opera
         1.和预测一样,opera没有阻塞img请求
         

clipboard.png

         2.和预测一样,浏览器会先下载后再把图片隐藏
         

clipboard.png

        -edge
        1.和预测一样,opera没有阻塞img请求
        

clipboard.png

        2.和预测一样,浏览器会先下载后再把图片隐藏
      

clipboard.png

总结

YES 或者NO 代表实际结果,√和×代表时候符合预期(作者认为是浏览器这样做是表现更好的)和不符合预期
clipboard.png

firefox阻塞了cssom构建中的img请求,这是似乎是一个低效率的行为;在css文件下载,解析,应用之前没有一张图片会被加载。这意味着你的样式是阻塞的话,也会阻塞你的img加载,如果img是种重要的内容这影响将会是尤其严重。
firefox的表现非常奇怪,无论img是否可见,都要等到cssom构建完才会触发请求。这是一种双重低效行为。

关键要点:

1.chrome、opera和edge下无论background-image是否可见都会下载,谨防不可见的图片下载可能会造成额外的资源浪费。
2.firefox在构建cssom完成前阻塞img下载,意味着延迟下载;
3.并且firefox在知道img不可见的情况下仍然会请求img;谨防不可见的图片下载可能会造成额外的资源浪费。

这些会影响哪些情况

  1. 如果你的产品是严重依赖图像的内容(例如:在线出版社,摄影作品等等),firefox会阻塞img直到css文件加载完。这种情况应该预加载一些关键的图像内容。
  2. 如果你第一次加载的时候并没有把所有图片显示出来(并没有用到所有的图片),你要意思到一些浏览器还是会继请求下载的。你可能想要找到更好的隐藏内容方案,例如直接移除DOM而不是display:none


Obeing
665 声望108 粉丝

努力地成为一只小牛