当前位置:首页 > 行业动态 > 正文

CSS和JS加载过程中的阻塞问题,你了解多少?

CSS 阻塞 JS 是因为 CSS 文件的加载和解析会阻塞浏览器对后续 JavaScript 代码的执行。

在网页开发中,CSS 和 JavaScript(JS)的加载与执行顺序对页面性能有着重要影响,以下是关于 CSS 阻塞 JS 的详细分析:

一、CSS 阻塞 JS 的原因

1、浏览器解析机制:浏览器在解析 HTML 文档时,会按照从上到下的顺序依次处理各种标签和资源,当遇到<link rel="stylesheet" href="styles.css"> 标签引入外部 CSS 文件时,浏览器需要等待该 CSS 文件完全下载并构建成 CSSOM(CSS Object Model),才能继续向下解析后续内容,而在这个过程中,如果后面紧跟着<script> 标签引入的 JS 脚本,由于 JS 可能会修改 DOM 或 CSSOM 的属性,为了避免出现样式计算错误或不一致的情况,浏览器会暂停 JS 的执行,直到 CSSOM 构建完毕。

2、渲染树的构建:CSS 会被构建成 CSSOM Tree,然后与 DOM Tree 一起形成渲染树(Render Tree),在 CSSOM 没有构建完成之前,渲染树无法完整构建,而 JS 的执行可能会依赖于正确的渲染树来进行 DOM 操作或样式计算等,所以浏览器会阻塞 JS 的执行以确保渲染树的正确性。

二、CSS 阻塞 JS 的影响及解决方法

1、影响:导致页面的加载时间变长,尤其是当 CSS 文件较大或网络延迟较高时,用户需要等待更长时间才能看到页面的交互效果和内容呈现,降低了用户体验,还会阻止页面的首次绘制,使用户看到的页面在一段时间内保持空白或不完整状态。

CSS和JS加载过程中的阻塞问题,你了解多少?  第1张

2、解决方法

优化 CSS 加载:将关键的 CSS 样式放在页面头部通过<link> 标签引入,以便尽早开始加载和解析,对于非关键性的 CSS,可以采用异步加载的方式,使用<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'"> 或者动态创建<link> 元素并在onload 事件中将其插入到<head> 中。

调整脚本位置:尽量避免在 CSS 还未加载完成时就执行依赖于样式的 JS 脚本,可以将 JS 脚本放在页面底部,在</body> 标签之前,这样可以让 HTML 文档先解析和显示,然后在页面加载完成后再执行 JS 脚本。

CSS和JS加载过程中的阻塞问题,你了解多少?  第2张

:对于外部 JS 脚本,可以添加defer 属性,表示脚本会在 HTML 文档解析完成后执行,但不会阻塞页面的渲染;对于不需要立即执行且不依赖 DOM 元素的脚本,也可以使用async 属性,使其异步加载和执行。

三、相关问答FAQs

1、为什么内联样式不会阻塞 JS 的执行?

内联样式是直接写在 HTML 标签的style 属性中的样式,由 HTML 解析器进行解析,不会像外部 CSS 那样需要单独的 CSS 解析器去构建 CSSOM,也不会产生阻塞浏览器渲染和后续 JS 执行的问题。

CSS和JS加载过程中的阻塞问题,你了解多少?  第3张

2、CSS 文件是通过 JavaScript 动态加载的,还会不会阻塞后面的 JS 代码?

如果是通过 JavaScript 动态创建<link> 元素来加载 CSS 文件,并且没有设置media 属性为print 或其他非all 的值,那么仍然会阻塞后面的 JS 代码执行,直到该 CSS 文件加载完成并构建好 CSSOM,但如果设置了media 属性为print 等非默认值,就可以实现类似异步加载的效果,不会阻塞后续 JS 代码的执行。

0