页面加载太慢?一文搞懂 JS 和 CSS 阻塞机制!

页面加载太慢?一文搞懂 JS 和 CSS 阻塞机制!
最新回答
葫芦岛

2021-07-20 17:07:39

JS 和 CSS 的加载阻塞行为是浏览器为保障页面渲染正确性和脚本安全性而设计的机制,其核心结论如下:

一、JS 的加载阻塞行为
  • 会阻塞 DOM 树的解析浏览器遇到 <script> 标签时,会暂停 HTML 解析,直到 JS 加载并执行完毕后再继续解析后续内容。

    原因:JS 可能操作或依赖前面的 DOM 元素(如绑定事件、修改内容),若 DOM 未解析完成,脚本会因找不到元素而报错。

    示例:在 <head> 中引入大型 JS 文件(如 bootstrap.bundle.js),此时 document.querySelector('h1') 返回 null,因为 <body> 尚未解析。

  • 不会阻塞 DOM 树的渲染若 DOM 已解析完成,即使 JS 仍在加载,浏览器也会优先渲染已解析的内容。

    示例:在 <body> 中放置 <h1 style="color: red">Hello</h1> 和 JS 文件,页面会先显示红色文字,再加载 JS。

  • 不会阻塞 CSS 的解析浏览器会并行下载和解析 CSS 文件,JS 加载不会影响 CSS 的解析过程。

    示例:引入 bootstrap.min.css 和大型 JS 文件,即使 JS 未加载完,CSS 仍会生效(如黄色文字)。

二、CSS 的加载阻塞行为
  • 不会阻塞 DOM 树的解析CSS 加载期间,浏览器会持续解析 HTML 生成 DOM 树。

    示例:在 <head> 中引入 bootstrap.css 和脚本,脚本能成功获取 <h1> 元素,说明 DOM 解析未被阻塞。

  • 会阻塞 DOM 树的渲染浏览器会等待 CSS 加载并解析完成后,再渲染页面以避免“无样式内容闪烁(FOUC)”。

    现象:若 CSS 文件较大或网络慢,用户会看到白屏,直到 CSS 生效(如蓝色文字显示)。

  • 会阻塞 JS 的运行<link> 后的 JS 脚本会等待 CSS 加载完成后再执行,防止脚本依赖的样式未生效导致错误。

    示例:在 <head> 中放置两个脚本,中间引入 CSS 文件,第二个脚本的执行时间与 CSS 加载时间一致(如 2759ms)。

三、浏览器设计原理与优化建议
  1. JS 阻塞解析的设计目的

    确保脚本操作的是完整 DOM,避免因元素未解析导致的错误。

    优化建议:将非关键 JS 放在 <body> 末尾或使用 async/defer 属性异步加载。

  2. CSS 阻塞渲染的设计目的

    防止 FOUC 和样式错乱,保证用户看到的是最终渲染结果。

    优化建议:压缩 CSS 文件、使用媒体查询按需加载、内联关键 CSS(Critical CSS)。

  3. 并行加载的优化

    浏览器会并行下载 JS 和 CSS 文件,但执行顺序受阻塞机制约束。

    关键点:JS 不阻塞 CSS 解析,但 CSS 阻塞 JS 执行,需合理规划资源顺序。

总结:JS 和 CSS 的阻塞行为是浏览器为平衡渲染正确性、脚本安全性和用户体验的权衡结果。理解这些机制后,开发者可通过调整资源位置、异步加载和样式优化等手段,显著提升页面加载性能。