图片如何优先加载

1,956 阅读3分钟

背景:

业务:这个模块的背景图片怎么出现的比商品图片慢呢?这种效果不美观.
我:喔,我这面怎么看不出呢...
我:打开开发者工具,选择slow 3g(约等于2g环境),在多次模拟中,终于看到这种情况了。好的,咱马上改😭

背景图片

通过打开开发者工具,发现背景图片的优先级是low,商品图片的优先级是high,所以是,商品图片先加载再是背景图片。

查了下原因发现是:由于背景图是通过css中的background-image实现,大部分主流浏览器都会调低该标签图片加载优先级,等所有主页面加载完后才会加载该图片。

有了上述的论证,我试了两种方法,证明都是ok的:

将背景图片改为图片

<div className="seckill-container" >
    <img src={toWebp(seckillBg)} alt="" className="seckill-bg" />
</div>

最后俩张图片就是我们的背景图片,可以看到它是一开始就加载了,不像之前,先挂起等所以商品图片加载完成。 截屏2022-02-16 下午5.30.04.png

使用CSS并使其成为任何0大小元素的背景。

这将强制浏览器在到达JS脚本之前加载图像。当然,CSS需要在JS之前加载并尽快加载。
 ```JS
    html {
      background-image:
        url("img/bg1.jpg"),
        url("img/bg2.jpg"),
        url("img/bg3.jpg"),
        url("img/bg4.jpg"),
        url("img/bg5.jpg");
      background-size:0 0;
    }
 ```
可以看到头两张图片先于其他图片加载,并且其优先级也变成了high。
![这是改过之后的效果.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9f97e5c519dc4a5eaa14cfdebed56e3e~tplv-k3u1fbpfcp-watermark.image?)

最后从效果出发,选择了第二种方式。

图片

上面既然了解了背景图片的优先加载方式,下面,我们也来看看图片资源的优先加载方式。

预加载

下载必要的资源,特别是对于浏览器早期不易发现的资源。

<link rel="preload" as="font" crossorigin href="https:" />
<style>
   @font-face {
     font-family: JDZhengHT-Regular;
     src: url('https://xxx.ttf');
   }
</style>
 const img = new Image();
 img.src = 'https://';
 img.importance = 'high';
 img.onload = () => {
 }

importance属性

可以使用一个 importance 属性来更细力度的控制资源加载的优先级,包括 link、img、script 和 iframe 这些标签。能够达到提升 LCP 图像的优先级。

importance属性可以指定三个值:

  • high:你认为该资源具有高优先级,并希望浏览器对其进行优先级排序。
  • low:你认为该资源的优先级较低,并希望浏览器降低其优先级。
  • auto:采用浏览器的默认优先级。
<img src="/images/in_viewport_but_not_important.svg" importance="high">

除了上面说的图片优先加载,它也能做些其他事情:

  • 降低首屏图片的优先级 使用 importance 属性降低可能不重要的首屏图片的优先级,比如轮播图中后面的图片:
<ul class="carousel">   
    <img src="img/carousel-1.jpg" importance="high">   
    <img src="img/carousel-2.jpg" importance="low">   
    <img src="img/carousel-3.jpg" importance="low">   
    <img src="img/carousel-4.jpg" importance="low"> 
</ul>
  • 降低预加载资源的优先级

想要阻止预加载资源和其他关键资源的竞争,可以降低其优先级:

<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" href="/js/script.js" as="script" importance="low">
<link rel="preload" as="style" href="theme.css" importance="low" onload="this.rel=stylesheet">
  • 脚本的优先级

如果页面上有一些必要的交互脚本,但不需要阻塞其他资源,你可以把它们标记为具有高优先级,同时异步加载它们:

<script src="async_but_important.js" async importance="high"></script>

如果脚本依赖于特定的 DOM 节点,则它们不能被标记为异步加载。但是如果它们不是首屏渲染必备的,你可以降低它们的优先级:

<script src="blocking_but_unimportant.js" importance="low"></script>