<link>和<script>和dom解析渲染之间的关系,及资源标识符的作用

·  阅读 874
<link>和<script>和dom解析渲染之间的关系,及资源标识符的作用

<link>和<script>和dom解析渲染之间的关系,及资源标识符的作用

script标签的位置不当的话,会阻塞html的解析,进而影响首屏速度

关键词解释

解析,渲染,触发页面paint。下载,执行

  1. 解析:html文件的解析(从上到下)
  2. 渲染:页面的渲染(能看见东西)
  3. 触发页面paint:触发页面渲染
  4. 下载(download):资源下载(缓存到浏览器)
  5. 执行:资源执行(run),等同于解析

link标签 和 script标签 和 dom解析 之间的关系

以下结论不带资源标识符(比如link的preload,script的async等),就纯标签

测试例子部分可以参考 juejin.cn/post/684490…

<link>带src 的 <script> (外链)inline内联的 <script>
DOM的解析(生成dom树)不会阻塞会阻塞(但会有预解析,只解析外链[让资源并行下载] ,不会修改dom树) 并且需要等到css执行完,生成cssom tree后,才执行(可以先下载),
*危害:让dom树和cssom树不能并行解析,变成串行解析了
同左
生成渲染树并渲染会阻塞(没有样式的页面几乎无法看,而且还要浪费重排和重绘的性能,所以索性,等到css规则树生成完毕,才渲染)会阻塞同左
触发页面paint(立刻生成渲染树并渲染 )不会解析之前会触发(渲染此<script>标签之前的元素)
- 也有前提条件:1. 不在<head>内,在body内。2. 此前的link标签需加载并执行完毕
不会触发paint(因为不用下载,只需执行,多数情况下时间比较短)
script 下载不会阻塞
script 执行(解析)会阻塞(src和inline都会阻塞)
link 下载不会阻塞(因为link标签都是外链)同左
link 执行(解析)会阻塞(会阻塞script标签下面的link标签,因为是从上到下执行)同左

如果script标签带上资源提示符

提示符是: async 和 defer

例如:<script src="1.js" defer></script>

目的:让script标签不阻塞 dom的解析 (一样会阻塞渲染)

scriptscript asyncscript defer
script的下载(是否阻塞dom解析(生成dom树))会阻塞(但会有预解析,只解析外链[让资源并行下载] ,不会修改dom树)不阻塞,并行不阻塞,并行
script的解析执行(是否阻塞dom解析(生成dom树))会阻塞会阻塞不阻塞,等到其他元素解析完成(dom树生成)后执行, DOMContentLoaded之前

scriptSymbol.jpeg

如果link标签带上资源提示符

例如:<link rel="preconnect" href="https://code.jquery.com" as="script">

  1. preconnect ( 对比 dns-prefetch )

    提前 DNS查询,TLS协商,tcp握手

    1. 对当前域名的资源无效(因为已经有缓存了
    2. 一般对cdn或其他域的资源 有效

    场景:页脚有个cdn资源<script>,则可以在页眉可以放一个preconnect资源提示

    <head>
      <meta charset="utf-8">
      <title>preconnect example</title>
      
      <link rel="preconnect" href="https://code.jquery.com/jquery-3.6.0.min.js" as="script">
    </head>
    
    <body>
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    </body>
    复制代码

    对比:dns-prefetch, dns-prefetch只有DNS查询,多了2次RTT(Round-trip delay 往返延迟)

    <link rel="dns-prefetch" href="https://fonts.googleapis.com/">

  2. preload(用法几乎同上)

    作用:提前加载资源:提前 DNS查询,TLS协商,tcp握手,和资源下载

    支持的格式多:image,style,script,font,audio,video 等

    场景:希望把 资源 放页脚(不阻塞dom解析),然后又想让资源提前下载,就可以用 preload + as="[type]"

    建议不要滥用:因为他的优先级会提很高,只在会影响白屏时间的重点资源上使用(预加载)(不要所有的资源都加preload,优先级没那么高的资源,就不要跟优先级高的抢了)

    <head>
      <meta charset="utf-8">
    
      <link rel="preload" href="style.css" as="style">
      <link rel="preload" href="main.js" as="script">
    
      <link rel="stylesheet" href="style.css">
    </head>
    
    <body>
      <h1>bouncing balls</h1>
      <canvas></canvas>
    
      <script src="main.js"></script>
    </body>
    
    -----------------
    
    <head>
      <meta charset="utf-8">
      <title>Video preload example</title>
      <link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4">
    </head>
    <body>
      <video controls>
        <source src="sintel-short.mp4" type="video/mp4">
        <source src="sintel-short.webm" type="video/webm">
        <p>Your browser doesn't support HTML5 video. Here is a <a href="sintel-short.mp4">link to the video</a> instead.</p>
      </video>
    </body>
    复制代码
  3. prefetch(用法几乎同上)

    作用:提前下载未来某个资源 (当前页面资源加载完了后,才会去预取)

    • 预取“将来”的资源(比如下一个页面,用户也有概率不到下一个页面),优先级比preload低(因为是下一个页面,preload是作用于当前页面)

      • 可以预下载资源到浏览器缓存,等到真正执行的时候,就直接拿缓存

    场景:下一个页面有个cdn资源<script>,则可以在当前页加 个link标签 prefetch资源提示符

    <link rel="prefetch" href="https://code.jquery.com/jquery-3.6.0.min.js" as="script"></link>

    注意:

    • 在 Chrome 中,如果用户导航离开一个页面,而对其他页面的预取请求仍在进行中,这些请求将不会被终止。

    • 此外,无论资源的可缓存性如何,prefetch 请求在未指定的网络堆栈缓存中至少保存 5 分钟。


码字不易,点赞鼓励!


性能优化合集快速入口:

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改