JS前面的CSS加载完之前,JS是不会执行的 。浏览器遇到没有设置defer或async的标签时,会触发页面渲染,而页面渲染必须等CSS加载完毕,所以CSS会阻塞JS 。
我们也可以这样想,如果JS中的内容需要获取DOM的样式,CSS没有加载完成就执行JS语句,势必会获取到错误的信息,因此,需要等到JS脚本前面的CSS加载完成,JS才能执行,这才是合理的 。
总结1
CSS的加载不会阻塞DOM树的解析,但会阻塞DOM树的渲染及后续JS的执行,然后JS的执行会阻塞DOM的解析 。如下公式可知,即使DOM树解析完成,在CSSOM构建完毕前,浏览器依旧不会渲染任何内容 。
DOM树 + CSSOM树 = 渲染树
存在阻塞的CSS资源时,浏览器会延迟JS脚本的执行和渲染树的构建 。CSSOM构建时,JS执行将暂停,直至CSSOM构建完毕 。当浏览器遇到一个没有设置defer或async的标签时,DOM树会停止构建,直至脚本执行完成 。
总结2
JS会阻塞DOM树的解析,但不会阻塞位于JS之前的DOM元素的渲染 。
现代浏览器为了更好的用户体验,渲染引擎将尝试尽快的在屏幕上显示内容 。它不会等到所有DOM解析完毕后才布局渲染树,而是当JS阻塞发生时,会将已经构建好的DOM元素渲染到屏幕上,减少白屏的时间 。这也是为什么我们一般会将标签放到body标签的底部,因为这样不会影响前面的页面的渲染 。
拓展:样式前面有DOM元素,可能导致页面闪烁
页面只有当遇到link标签或style标签时才会构建CSSOM,如果这两个标签前面有DOM元素,若加载CSS发生阻塞,样式前的DOM会被浏览器按照默认样式渲染 。当CSS加载完成时,则会重新计算样式,重新渲染,此时可能会出现闪烁效果 。
为了避免页面闪烁,通常样式放在文档头部,即head中 。
措施1
编写HTML时,推荐将CSS放在文档头部,将JS放在文档尾部,此时CSSOM Tree和DOM Tree同时构建,最后CSS树和DOM树合成渲染树 。
引入外部脚本时,样式资源推荐放在文档头部(加速页面的渲染),脚本推荐放在文档底部,当位于其它位置时,非特殊情况(如脚本会改变文档的内容),推荐设置defer或者async,因为设置defer或async的脚本不会阻塞DOM解析 。
Document/* 内联样式 */
措施2
CSS会阻塞DOM渲染,会阻塞JS 。CSS加载过长,可能导致长时间的白屏,因此合理的优化CSS,提高CSS加载速度,可以大大减少页面渲染所用时间,如下措施可供参考 。
1、启用CDN实现静态资源加载速度的优化2、压缩CSS(可以使用webpack、gulp等)3、合理使用缓存(主要避免缓存带来的影响)4、样式文件合并,或干脆写成内联样式(注意,内联样式不能被缓存)5、使用内联JS和CSS,这样获取到HTML文旦后可以直接开始渲染流程6、对于大的CSS,可以通过媒体查询属性,将其拆分为多个不同用途的CSS文件,特定场景加载特定CSS7、若JS中没有操作DOM的代码,可以将其设置async或defer
CDN翻译为内容分发网络,是一组分布在多个不同地理位置的Web服务器 。服务器离用户越远,延迟越高 。CDN会根据网络状况,替我们挑选最近的一个具有缓存内容的节点提供资源,从而缩短请求时间 。引用外部静态资源时,推荐使用CDN 。
拓展
load事件:页面的HTML、CSS、JS、图片等资源均已加载完之后才会触发 。用于监测页面是否完全加载完毕,包括页面及其依赖资源 。
- 可再生能源有哪五种
- Kubernetes 17 (k8s中部署Prometheus、监控nginx、
- 电脑串口号被占用,如何清除和重置串口号
- 2022年全球市场电视空白频谱总体规模、主要生产商、主要地区、产品和应用细分研究
- i18n 国际化
- 安全工具
- 如何用Python保存语音、图片、视频等信息转发给好友
- Drizzle、MariaDB和Percona Server_超越MySQL:三
- 一、安装适用于Windows的Linux子系统
- 卷积神经网络的FPGA硬件加速——QMJ