资讯专栏INFORMATION COLUMN

HTML执行顺序-一探究竟

darry / 1781人阅读

摘要:而进程是多线程的,它主要包含以下主要线程渲染线程负责渲染浏览器界面,解析,,构建树和树,布局和绘制等。且加载解析执行会阻止解析器往下执行,要强调渲染和下载是不冲突的,渲染是线程在执行,下载是下载线程在执行,浏览器多线程。

了解浏览器线程基础

一个页面的呈现主要是由浏览器渲染进程实现的(render进程),主要作用为页面的渲染,脚本执行,事件处理等。而render进程是多线程的,它主要包含以下主要线程:

1 GUI渲染线程

负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。

当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行

注意,GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于被冻 结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

2 JS引擎线程

也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)

JS引擎线程负责解析Javascript脚本,运行代码。

JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中 无论什么时候都只有一个JS线程在运行JS程序

同样注意,GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。

3 事件触发线程

归属于浏览器而不是JS引擎,用来控制事件循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)

当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中

当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理

注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)

4 定时触发器线程

传说中的setInterval与setTimeout所在线程

浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)

因此通过多带带线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)

5 异步http请求线程

在XMLHttpRequest在连接后是通过浏览器新开一个线程请求

将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。

JS阻塞特性

由上述GUI线程和JS引擎互斥的关系,我们也就能更好的理解为什么JS运行会阻塞页面的渲染,也就是常说的JS阻塞特性

HTML整体执行步骤

0.加载整体html文件

1.至上而下解析html

2.解析html建立dom树,遇到诸如

html顺序测试

Test.js代码:

        for(var i=0;i<10000;i++){
            console.log("delay");
            if(i==9999){
                loadStyle("lime.css");
            }
        }


        function loadStyle(url){
            var link = document.createElement("link");
            link.type = "text/css";
            link.rel = "stylesheet";
            link.href = url;
            var head = document.getElementsByTagName("head")[0];
            head.appendChild(link);
        }

Test2.js代码:

console.log("after blocking script,you will appear");

从图中可以看出:遇到

Refresh with the console open to see the hanging

由https://blog.csdn.net/gbstack...,我们可以得到:

由图中可以看出:

外部脚本与外部样式是并行加载(即在 下载 阶段,

阅读需要支付1元查看
<