Chrome浏览器加载script机制浅谈

最近在工作中遇到了一些script方面的加载顺序问题,下面进行一些介绍

在之前的理解中,浏览器是作为一个解释器,逐行分析代码,构建DOM树,然后进行资源加载的,那么如果在一个script执行过程中document.write一个新的script标记到文档流中,本script执行完毕后,浏览器就会同步执行新的script中的脚本资源。

那如果是通过document.createElement("script")的方式,然后动态加载到document head里面去的呢,这个被称为异步脚本加载机制,会异步地发出一个新的请求,然后在收到返回结果时候进入浏览器执行队列,开始执行,所以说这个的执行机制是不确定的,可能在下面的同步脚本任意一个之前,或者之后。举例:

后端的c1.php c3.php c5.php分别代表延时 1秒 3秒 5秒返回结果,再返回时候会分别打印 1111111   333333333  55555555

<script>
	var t = document.createElement("script");
	t.src="c1.php";
	document.head.appendChild(t);
</script>
<script src="c3.php"></script>

  这个显示的结果是

11111111

3333333

这个是在c1是一个异步的请求,而c3是一个同步的请求,同步的请求和异步的资源加载请求都发出后,1秒后c1.php返回结果,进入浏览器事件队列开始执行,3秒后c3.php返回,进入浏览器事件队列开始执行

那么是不是说一定是这个执行顺序呢,看看下面的情况

<script src="c5.php"></script>
<script>
	var t = document.createElement("script");
	t.src="c1.php";
	document.head.appendChild(t);
</script>
<script src="c3.php"></script>

  这个结果是

5555555

3333333

11111111

为什么是这样的结果呢,其实是因为Chrome有一种预加载机制,就是浏览器会先便利整个html文本,找到其中的资源链接标记,发送http请求,所以一上来发现了c5.php和c3.php的标记,注意此时还没有c1.php的标记。所以3秒后c3.php返回结果,等待执行,因为前面的c5.php还没有执行以及后面的内嵌脚本也没有执行,所以没有轮到执行,5秒后c5.php返回结果进入浏览器事件队列开始执行,打印555555然后执行异步加载c1.php,发送异步请求,然后c3.php的结果进入浏览器事件队列开始执行,打印333333然后第6秒c1.php返回结果打印111111所以,实际上是浏览器执行是按照同步顺序执行,但是请求资源却有优化,是在页面解析第一开始就请求资源的。

 

上一篇:nohup: ignoring input and redirecting stderr to stdout


下一篇:Deep Learning with Python猫狗大战cats-vs-dogs学习笔记(1)