3 个回答

如果你说的阻塞是阻塞解析html和阻塞渲染,那script无论是不是外链都会阻塞。如果说的是第一种情况,performance里会出现这个:
clipboard.png
第一种情况的加载过程中,先绘制了第一段文字,再绘制第二段文字,第二种情况不会。
个人感觉出现这种情况是因为代码直接写在script时,解析到script后parse HTML和渲染都被阻塞(图里前面很长一段黄色的长条),script的内容被解析完后,会先把script前面的内容渲染出来,再去解析script后面的内容,css树解析完了,DOM树也经历了重绘重排,所以浏览器直接判定差不多可以开始首次绘制了,图里First Paint的时候,script后面的内容还没经历重绘重排,所以FP时没被绘制上去,也是因为没绘制完,所以FP后面还有个FMP(first meaningful paint),script后面的内容经历重绘重排后才会被渲染到页面上:
clipboard.png
第二种情况:
阻塞解析渲染的script文件处理完后,直接开始解析script后面的内容,而不是先将前面的部分重绘重排,因此触发FP时,绘制的是页面所有内容
clipboard.png
第二种情况首次绘制直接把所有内容绘制出来了,所以performance里找不到第一种情况里,前一段文字显示了,后面还没显示的帧。
但是实际上无论是不是外链,都阻塞了DOM解析和渲染(前面都有很长一段黄色长条)。
具体为什么第一种情况会先把script前面的部分重绘重排,第二种不会,个人感觉应该是因为第二种ui线程其实只需要解析很短的一段代码,因为script内容在外链里,下载交给网络请求线程,下载完直接让js线程解析,下载和解析时ui线程处于挂起状态,解析完之后ui线程被唤醒,继续完成之前的工作(解析html)。
但是第一种情况,script里耗时的内容在html里,解析的时候还是需要ui线程参与,ui线程判定是个很耗时的过程,所以js内容执行完直接就先把前面解析的重绘重排,再去解析后面的。
第一种情况,script黄条在parse HTML蓝条下面:
clipboard.png
第二种情况,parse HTML蓝条和script黄条并列:
clipboard.png

这个是个人观点,查了半天资料都没找到相关内容。。。

————————————————————————————————————————————————————————————————————————————

对比了一下第二种情况中,有时先出现hello,再出现world,有时hello和world一起出现,感觉有点眉目了。
hello和world一起出现的情况时,在ui线程对script前面的代码进行重绘重排之前,就接收到了外链的script代码:
clipboard.png
先出现hello再出现world时,接收外链代码晚于重绘重排:
clipboard.png

应该是和浏览器接收到内容的时间有关,超过一段时间没接收到外链的内容,就先进行重绘重排了,如果在这个时间内先接收到外链内容,就先开始解析外链JS代码

这个涉及到浏览器渲染原理的一些知识了。

当构建DOM树时,若遇到<script>标签,则会立刻停止DOM树的构建,而选择将<script>内的脚本运行完后再构建DOM

所以一般的<script>标签放在body后面。

如果碰到外联的<script>标签。DOM的构建仍然被暂停以等待JavaScript脚本运行完,而且还需要将从服务器获得外联脚本的时间计算在内。

注释:假如此元素内部的代码没有位于某个函数中,那么这些代码会在页面被加载时被立即执行。-摘自W3C script 标签说明。
准确的说是阻止了dom树的结构生成,html元素还是在的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏