likes
comments
collection
share

聊聊关于 Link 标签的预加载机制

作者站长头像
站长
· 阅读数 37

link 标签的作用

前端页面加载资源的方式有很多种,预处理类 link 标签允许我们控制浏览器,提前针对一些资源去做这些操作,以提高性能;我们可以在页面 <head> 元素内部使用 <link> 标签书写一些声明式的资源获取请求。

<head>
    <meta charset="utf-8">
    <title>Link</title>
    
    <link rel="preload" href="style.css" as="style">
    <link rel="preload" href="main.js" as="script">
</head>

预加载 preload

有些资源是在页面加载完成后即刻需要的,你可能希望在页面加载的生命周期的早期阶段就开始获取这些资源,在浏览器的主渲染机制介入前就进行预加载,这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。preload 使用 as 指定预加载的内容的类型,将使得浏览器能够:

  • 更精确地优化资源加载优先级
  • 匹配未来的加载需求,在适当的情况下,重复利用同一资源
  • 为资源应用正确的内容安全策略
  • 为资源设置正确的 Accept 请求头

as 属性可以取以下的值:audio、font、image、script、style、worker、video

以下是一些关于 preload 的特点:

  1. 加载的资源是在浏览器渲染机制之前进行处理的,并且不会阻塞 onload 事件
  2. 可以支持加载多种类型的资源,并且可以加载跨域资源
  3. js 脚本的加载和执行过程是分离的,会预加载相应的脚本代码,待到需要时自行调用

跨域获取 crossorigin

如果你想要预加载跨域资源,只需在 <link> 元素中设置好 crossorigin 属性即可,注意:如果你需要获取的是字体文件,那么即使是非跨域的情况下,也需要应用这一属性

<head>
    <meta charset="utf-8">
    <link rel="preload" href="fonts/cicle_fina-webfont.ttf" as="font" type="font/ttf" crossorigin="anonymous">
    <link rel="preload" href="fonts/cicle_fina-webfont.svg" as="font" type="image/svg+xml" crossorigin="anonymous">
</head>

包含媒体 media

<link> 元素有一个 media 属性,它可以接受媒体类型或有效的媒体查询作为属性值,能够实现响应式的预加载,下面是一个简单的例子,我们可以通过媒体查询,来根据屏幕的大小预加载不同的图片。

<head>
    <meta charset="utf-8">
    <title>DEMO</title>
    
    <link rel="preload" href="image-1.png" as="image" media="(max-width: 1000px)">
    <link rel="preload" href="image-2.png" as="image" media="(min-width: 500px)">
</head>
<body>
    <div>
        <h1>HELLO WORLD</h1>
    </div>
    <script>
        const mediaQueryList = window.matchMedia("(max-width: 1000px)");
        const element = document.querySelector('div');
        
        if(mediaQueryList.matches) {
            element.style.backgroundImage = 'url(image-1.png)';
        } else {
            element.style.backgroundImage = 'url(image-2.png)';
        }
    </script>
</body>

脚本化与预加载

我们完全能够以脚本化的方式来执行预加载操作,比如下面的例子,浏览器将预加载这个 JavaScript 文件,但并不实际执行它,当你需要预加载一个脚本,但需要推迟到需要的时候才令其执行时,这种方式会特别有用。

let preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);

prefetch

prefetch 是一种利用浏览器的空闲时间加载页面将来可能用到的资源的一种机制;通常可以用于加载非首页的其他页面所需要的资源,以便加快后续页面的首屏速度;其加载的资源可以获取非当前页面所需要的资源,并且将其放入缓存至少5分钟(无论资源是否可以缓存);并且,当页面跳转时,未完成的 prefetch 请求不会被中断。

简单来说:preload 主要用于预加载当前页面需要的资源;而 prefetch 主要用于加载将来页面可能需要的资源;