html.js.css渲染顺序

可以发现一个Dom过来,正常情况下, html解析器和css解析器同时进行解析, html解析成一个dom树,解析成dom树的同时,css解析器也会解析成一个css 规则树. 然后dom树和css规则树生成了附件,我把他当做cssom来看待.附件形成之后,就可以生成一个渲染树了.然后渲染树和layout就可以进行绘制了. 因为浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系, 所以可以进行绘制.最后进行呈现.

上面也说了,是正常情况下.但是不正常情况呢? 不正常情况就是阻塞,不能并行下载.

  • css阻塞

css其实也会阻塞,不要只以为js会阻塞.

CSS会阻塞渲染树的构建,但是不会阻塞DOM构建,但是在CSSOM构建完成之前,页面不会开始渲染(一片空白).会等待css规则树如何优化css阻塞

与js不一样,js虽然会阻塞后续DOM构建,但是前面已经就绪的内容会进行渲染。CSS虽然不阻塞DOM构建,但是会阻塞后面js的执行,从而间接阻塞完整DOM的构建

  • js阻塞

JS默认也是会阻塞DOM和渲染树的构建的。

HTML解析器在遇到脚本文件时,默认会停下来去获取脚本(不考虑资源预加载优化),然后执行,期间阻塞DOM构建。

所以加载顺序是自上而下,但是渲染流程却是如图.所以最好将js放在最下面.

js 通过async和defer加载

渲染的关键词

  • 关键资源: 可能阻止网页首次渲染的资源。

  • 关键路径长度 获取所有关键资源所需的往返次数或总时间。

  • 关键字节: 实现网页首次渲染所需的总字节数,它是所有关键资源传送文件大小的总和。

进程线程

为什么js加载执行会阻塞渲染树构建

这就得从浏览器来说起来,现在的浏览器都是多进程的浏览器,以谷歌来说,他就是多进程的,每当你打开一个新的tab页的时候,他就会去开一个进程来处理这个tab页面。在这个tab里,是单进程,但是却是多线程的,主要是有那么一些线程,可以看下。

  • JavaScript引擎线程

  • GUI线程

  • 事件触发线程

  • 定时触发器线程

  • 异步http请求线程

javascript线程

毫无疑问,这东西就是处理js代码的。例如V8引擎,就是解析运行代码。但是为什么是单线程的呢?因为线程存在上下文切换,可能多个线程操作一个dom,这就产生了资源竞争,后续要处理更多,索性用了单线程。

GUI线程

这个是负责渲染页面,每当页面重绘的时候这个线程都会调用。js引擎在执行的时候,GUI线程会停止执行,处于挂起的一个状态。

js阻塞GUI引擎

因为js是可以操作dom,GUI也是操作dom, 如果同时运行会存在问题,可能同时修改dom,导致渲染前后不一致。

定时触发器器线程

处理一些异步的web api的时候,碰到定时的,会去处理这种定时,再放入事件队列等待放入栈里。

事件触发线程

一些事件被触发时就会调用该线程,比如一些ui事件,定时事件,ajax请求等,都会放到队列里准备执行。

异步http请求线程

一些http请求连接开启之后,都会新开一个线程去处理。

Last updated