最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • preload、prefetch、preconnect 和 dns-prefetch 知多少

    正文概述 掘金(大海我来了)   2021-01-08   1005

    在上篇文章 探究网页资源究竟是如何阻塞浏览器加载的 中介绍到 JS 会阻塞 DOM 的加载,样式会阻塞页面的渲染,外链样式里的自定义字体还会对文字造成闪动给用户带来不好的体验,诸如此类问题还有挺多,那到底该如何解决它们呢?

    今天我们就来学习通过在 link 标签里加上特定的属性,比如 preloadprefetch 等来解决此类问题,那么你对这些属性又了解多少呢?把它们用在了你们的项目优化中了嘛?

    preload

    preload 提升了资源加载的优先级,使得它提前开始加载(预加载),在需要用的时候能够更快的使用上。另外 onload 事件必须等页面所有资源都加载完成才触发,而当给某个资源加上 preload 后,该资源将不会阻塞 onload

    preload 怎么用

    当某个页面加载了 2 个脚本 jquery.min.jsmain.js

    <script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
    <script src="./main.js"></script>
    

    此时该页面的资源加载 Waterfall 长这样:

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    当在 <head> 里通过 <link> 标签给 main.js 配置 preload 预加载后:

    <link rel="preload" as="script" href="./main.js">
    

    此时的 main.js 加载顺序出现在了 jquery.min.js 的前面,这就是 preload 提升资源加载优先级的效果。

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    preload、prefetch、preconnect 和 dns-prefetch 知多少 preload、prefetch、preconnect 和 dns-prefetch 知多少

    通过 <link rel="preload"> 只是预加载了资源,但是资源加载完成后并不会执行,所以需要在想要执行的地方通过 <script> 来引入它:

    <script src="./main.js"></script>
    

    但是也有一个例外,因为 CSS 的加载也是通过 <link> 标签引入的,所以我们可以巧妙的利用这点,当 onload 事件触发的时候修改 rel 属性的值,使得它由原来的预加载样式变成引入样式:

    <link rel="preload" as="style" onload="this.rel='stylesheet'" href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css"/>
    

    如果通过 preload 加载了资源,但是又没有使用它,则浏览器会报一个警告:

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    preload 除了能够预加载脚本之外,还可以通过 as 指定别的资源类型,比如:

    • style 样式表;
    • font:字体文件;
    • image:图片文件;
    • audio:音频文件;
    • video:视频文件;
    • document:文档。

    preload 应用案例

    preload 主要用于提升当前页面某些阻塞资源的下载优先级,使得页面能够尽快渲染显示出来。

    案例一:预加载定义在 CSS 中资源的下载,比如自定义字体

    当页面中使用了自定义字体的时候,就必须在 CSS 中引入该字体,而由于字体必须要等到浏览器下载完且解析该 CSS 文件的时候才开始下载,所以对应页面上该字体处可能会出现闪动的现象,为了避免这种现象的出现,就可以使用 preload 来提前加载字体,type 可以用来指定具体的字体类型,加载字体必须指定 crossorigin 属性,否则会导致字体被加载两次

    <link rel="preload" as="font" crossorigin type="font/woff2" href="myfont.woff2">
    

    以上这种写法和指定 crossorigin="anonymous" 是等同的效果。

    案例二:预加载 CSS 文件

    在首屏加载优化中一直存在一种技术,叫做抽取关键 CSS,意思就是把页面中在视口中出现的样式抽出一个独立的 CSS 文件出来 critical.css,然后剩余的样式在放到另外一个文件上 non-critical.css

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    由于 CSS 会阻塞页面的渲染,当同时去加载这 2 部分样式的时候,只要 non-critical.css 还没加载完成,那么页面就显示不了,而实际上只需要显示出视口下的界面即可,所以期待的结果是:当加载完成 critical.css 的时候马上显示出视口下的界面,不让 non-critical.css 阻塞渲染,则需要给 non-critical.css 加上预加载:

    <link rel="preload" as="style" href="https://bubuzou.com/non-critical.css">
    <link rel="stylesheet" href="https://bubuzou.com/critical.css">
    <link rel="stylesheet" href="https://bubuzou.com/non-critical.css">
    

    案例三:创建动态的预加载资源

    当需要预先加载的时候调用 downloadScript,而希望执行的时候则调用 runScript 函数。

    function downloadScript(src) {
        var el = document.createElement("link")
        el.as = "script"
        el.rel = "preload"
        el.href = src
        document.body.appendChild(el)
    }
        
    function runScript(src) {
        var el = document.createElement("script")
        el.src = src
    }
    

    案例四:结合媒体查询预加载响应式图片

    preload 甚至还可以结合媒体查询加载对应尺寸下的资源,对于以下代码当可视区域尺寸小于 600px 的时候会提前加载这张图片。

    <link rel="preload" as="image" href="someimage.jpg" media="(max-width: 600px)">
    

    案例五:结合 Webpack 预加载 JS 模块

    Webpack4.6.0 版本开始支持在魔术注释中配置预加载模块:

    import(_/* webpackPreload: true */_ "CriticalChunk")
    

    如果是版本比较老的,则可以使用 preload-webpack-plugin 进行处理。

    prefetch

    preload 用于提前加载用于当前页面的资源,而 prefetch 则是用于加载未来(比如下一个页面)会用到的资源,并且告诉浏览器在空闲的时候去下载,它会将下载资源的优先级降到最低。

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    比如在首页配置如下代码:

    <link rel="prefetch" as="script" href="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js">
    

    我们会在页面中看到该脚本的下载优先级已经被降低为 Lowest

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    当资源被下载完成后,会被存到浏览器缓存中,当从首页跳转到页面 A 的时候,假如页面 A 中引入了该脚本,那么浏览器会直接从 prefetch cache 中读取该资源,从而实现资源加载优化。

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    preconnect

    当浏览器向服务器请求一个资源的时候,需要建立连接,而建立一个安全的连接需要经历以下 3 个步骤:

    • 查询域名并将其解析成 IP 地址(DNS Lookup);
    • 建立和服务器的连接(Initial connection);
    • 加密连接以确保安全(SSL);

    以上 3 个步骤浏览器都需要和服务器进行通信,而这一来一往的请求和响应势必会耗费不少时间。

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    而就基于这点上,可以使用 preconnect 或者 dns-prefetch 进行优化,而它两又是什么呢?怎么使用呢?

    preconnect 是什么,怎么用

    当我们的站点需要对别的域下的资源进行请求的时候,就需要和那个域建立连接,然后才能开始下载资源,如果我都已经知道了是和哪个域进行通信,那不就可以先建立连接,然后等需要进行资源请求的时候就可以直接进行下载了。

    假设当前站点是 https://a.com,这个站点的主页需要请求 https://b.com/b.js 这个资源。对比正常请求和配置了 preconnect 时候的请求,它们在请求时间轴上看到的表现是不一样的:

    preload、prefetch、preconnect 和 dns-prefetch 知多少

    通过如下配置可以提前建立和 https://b.com 这个域的连接:

    <link rel="preconnect" href="https://b.com">
    

    通过 preconnect 提早建立和第三方源的连接,可以将资源的加载时间缩短 100ms ~ 500ms,这个时间虽然看起来微不足道,但是它是实实在在的优化了页面的性能,提升了用户的体验。

    preconnect 应用场景

    场景一:

    当知道资源是来源于哪个源下,但是对于加载哪个资源不是很明确的时候,比如对于如下这些资源:

    preload、prefetch、preconnect 和 dns-prefetch 知多少 preload、prefetch、preconnect 和 dns-prefetch 知多少

    它们要嘛是动态的,要嘛是根据不同环境携带不同参数,所以它们很适合用 preconnect 进行加载。

    场景二:

    如果页面上有流媒体,但是没那么快播放,又希望当按下播放按钮的时候可以越快开始越好,此时就可以使用 preconnect 预建立连接,节省一段时间。

    如果用 preconnect 预建立连接的资源是一个字体文件,那么也是需要加上 crossorigin 属性。

    dns-prefetch

    通常我们记住一个网站都是通过它的域名,但是对于服务器来说,它是通过 IP 来记住它们的。浏览器使用 DNS 来将站点转成 IP 地址,这个是建立连接的第一步,而这一步骤通常需要花费的时间大概是 20ms ~ 120ms。因此,可以通过 dns-prefetch 来节省这一步骤的时间。

    居然能通过 preconnect 来减少整个建立连接的时间,那为什么还需要 dns-prefetch 来减少建立连接中第一步 DNS 查找解析的时间呢?

    假如页面引入了许多第三方域下的资源,而如果它们都通过 preconnect 来预建立连接,其实这样的优化效果反而不好,甚至可能变差,所以这个时候就有另外一个方案,那就是对于最关键的连接使用 preconnect,而其他的则可以用 dns-prefetch

    可以按照如下方式配置 dns-prefetch

    <link rel="dns-prefetch" href="https://cdn.bootcss.com">
    

    另外由于 preconnect 的浏览器兼容稍微比 dns-prefetch 低,看下图:

    preload、prefetch、preconnect 和 dns-prefetch 知多少 preload、prefetch、preconnect 和 dns-prefetch 知多少

    因此 dns-prefetch 可以作为不支持预连接的浏览器的后备选择,同时配置它们两即可:

    <link rel="preconnect" href="https://cdn.bootcss.com">
    <link rel="dns-prefetch" href="https://cdn.bootcss.com">
    

    参考文章

    • 前端性能优化之关键路径渲染优化
    • web.dev/link-prefet…
    • www.w3.org/TR/resource…
    • 译文Preload,Prefetch 和它们在 Chrome 之中的优先级
    • preload-prefetch-preconnect
    • web.dev/extract-cri…

    起源地下载网 » preload、prefetch、preconnect 和 dns-prefetch 知多少

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元