浏览器的预解析

107 阅读3分钟

浏览器的网络进程接收到html文档后,交给渲染进程的渲染引擎

浏览器的内核由两部分组成

渲染引擎:负责HTML解析、布局、渲染等等相关的工作

js引擎:解析、执行JavaScript代码

以Webkit为例,其中的排版引擎为webCore,JS引擎为JSCore

浏览器的预解析和js引擎的预解析(又被称之为变量提升)需要区分开。

渲染线程解析html构建dom,遇到css则构建cssom

渲染线程与js线程互斥,当js线程工作时,渲染线程会停止,等待js线程工作完成。

有些资料说dom和cssom都是在渲染线程中进行了所以是串行的,只不过因为cssom的构建非常快可忽略不计

而有些资料说dom和cssom是并行构建的,cssom是在浏览器预解析线程中进行,所以能和渲染线程中dom构建并行

笔者更倾向于后者,有确切知道的同学可以评论告知我,万分感谢

现代浏览器在渲染线程解析html时,都会开启一个预解析线程,去解析外部资源,遇到外链的link去下载css,

外部脚本,图片,字体等,并把它们缓存到浏览器。

当主解析器处理到该资源时,如果有缓存则可以直接取用。

如果还没有下载好则看该资源是不是scirpt且没有defer和async标识,就会等待script下载完成,并且直接执行,由于js线程和渲染线程互斥,这个过程渲染线程停止,等待js线程执行完。

如果该资源不是script而是css,img资源等,则主解析器不会被阻塞。

这就是浏览器利用预解析线程的一个优化策略。

也就是说,html的解析可能会被脚本加载、执行所阻塞,但是外部资源的加载是在预解析线程上通知给网络进程的不会被阻塞。

我们编写这样一段代码

可以看到在script中的循环未完成的时候,html的解析还不知道后面有script加载,img的加载,和外链css

但在f12网络面板看到,未执行完js的时候,资源已经开始加载了,这就是预解析

这一点可以通过 chrome 调试工具中的 Network - Waterfall 进行验证,但是需要注意 chrome 的并发连接数(同一域名)上限为 6 个。

了解以上信息之后,我们可以对该页面进行相应优化,例如对CSS文件进行压缩处理、使用 CDN,将资源分布在多个域名下、合并 CSS 文件,减少 HTTP 请求数量等,来提高 CSS 的加载速度,减少 HTML 文档解析和渲染的阻塞时间。

浏览器的并发请求数目限制是针对同一域名的。因此可以使用 CDN 加速技术来提高用户访问网站的响应速度,这样使用了 CDN 的资源加载不会占用当前域名下的并发连接数,从而减少阻塞的时间。

参考:

segmentfault.com/a/119000001…

afantasy.ninja/2018/01/13/…

web.dev/articles/ho…

juejin.cn/post/700301…

www.nowcoder.com/discuss/513…