美文网首页
一文读懂 css js 阻塞问题

一文读懂 css js 阻塞问题

作者: lanberts | 来源:发表于2021-09-10 17:58 被阅读0次

    前言

    先抛出几个问题:

    • css 加载会不会阻塞 js 的加载?(不会)
    • css 加载会不会阻塞 js 的执行?(会)
    • css 加载会不会阻塞 DOM 的解析?(不会)
    • css 加载会不会阻塞 DOM 的渲染?(会)
    • js 加载会不会阻塞 DOM 的解析?(会)
    • js 加载会不会阻塞 DOM 的渲染?(会)
    • js 执行会不会阻塞 DOM 的解析?(会)
    • js 执行会不会阻塞 DOM 的渲染?(会)

    可以看出 js 是全阻塞的,这也是为什么 js 要放尾部的原因。
    至于 css 放头部则是为了避免页面一开始样式,而后出现样式导致页面闪动情况,这样用户体验就比较差了。

    浏览器的主要进程和职责


    关于 css,js 的阻塞问题,都跟浏览器的渲染进程有关。而渲染进程又是多线程的。理清各个线程的职责及相互之间的合作关系,就能窥探其原理。

    • JS 引擎线程(单线程):负责解析 Javascript 脚本,运行代码
    • GUI 渲染线程:负责渲染浏览器界面,解析 HTML,CSS,构建 DOM Tree,Style Tree 和 Render Tree,布局和绘制等

    注意:GUI 渲染线程与 JS 引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起,所以当 JS 加载和执行时,会阻塞住 DOM 的解析和渲染,导致白屏时间很长

    浏览器渲染流程

    1.解析 HTML 生成 DOM Tree
    2.解析 CSS 生成 Style Tree
    3.将 DOM Tree 与 Style Tree 合并在一起生成 Render Tree
    4.遍历 Render Tree 开始布局,计算每个节点的位置大小信息(Layout)
    5.绘制 Render Tree,绘制页面的像素信息(Painting),显示到屏幕上(Display)

    DOM Tree 和 Style Tree 是并行构建的,所以 CSS 加载不会阻塞 DOM 的解析

    由于 Render Tree 是依赖于 DOM Tree 和 Style Tree 的,因此,css 加载会阻塞 Dom 的渲染

    GUI 渲染线程与 JS 引擎线程是互斥的,加载解析 css 时,JS 引擎会被挂起,所以 css 会阻塞 js 的执行

    回流和重绘

    回流必将引起重绘,重绘不一定会引起回流

    回流(Reflow):当 Render Tree 中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流
    重绘(Repaint):当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility 等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘

    回流比重绘的代价要更高

    资源加载优先级

    想要提升页面的加载速度,除了关注 css,js 阻塞的问题外,了解资源加载的优先级同样重要。
    我们知道资源加载本身不存在互相阻塞的问题,但浏览器依然会按照资源默认的优先级确定加载顺序:
    1.html 、 css 、 font 这三种类型的资源优先级最高
    2.然后 script 、 xhr 请求
    3.接着是图片、语音、视频

    然而,有些资源我们知道很重要,想优先加载;有些资源无关紧要,想延后加载,那么如何手动控制浏览器加载优先级呢?
    主要有4种指令:

    • preload 预加载(提升优先级):通知浏览器接下来马上就会用到的资源,并尽快开始加载资源
    • prefetch 预获取(最低优先级):通知浏览器这是稍后可能需要用到的东西,可以延迟加载(在带宽空闲(idle)时再加载)
    • asnyc 异步获取(降低优先级):资源可以异步加载,加载完即可执行(乱序执行)
    • defer 异步获取(降低优先级):资源可以异步加载,但需要按照资源加载顺序执行(按序执行)

    相关文章

      网友评论

          本文标题:一文读懂 css js 阻塞问题

          本文链接:https://www.haomeiwen.com/subject/kstuihtx.html