一文讲清楚script加载和执行顺序,包括script标签、defer、async、动态script等
1. 普通script标签
- 先说原理,一个HTML文档,里面有会有html和script等
- 浏览器一般是按照顺序解析执行的,比如下面的代码
<div>I`m Html</div><script>console.log('I`m script from script tag with no src')</script><div>I`m html ,too</div><scriptsrc='test.js'></script>/** * test.js * console.log('I`m script from script tag with src') */浏览器的解析和执行顺序是这样的
也就是说浏览器是按行解析,按行执行的,如果执行到带有外部链接的script标签,就全部加载,然后执行,执行完以后再继续往下走
这样就会有一个问题
如果某一个出在文档中间的script标签很大,执行耗费了很长的时间,那么标签下面的HTML内容就得不到渲染,就会造成页面的卡顿
聪明的你立刻就提出了解决方案,说把所有的script放在页面的底部,是不是就解决了问题,
然而并不完美,以为这样的话,浏览器必须下载解析完所有的HTML内容,才会处理script,如果script里面有对HTML内容的改变,就会明显的延迟和跳动
那应该怎么办呢
先分析现在的问题是什么,是HTML的解析执行和script解析执行在同一个线程里,发生了资源竞争,也就是说我执行的时候你就得停,你执行的时候我就得停
那怎么解决呢,那就让分开,也就是HTML你执行你的,script标签我执行我的,互不干扰,这不是不是好点了,怎么分开了,我们自然的想到了使用异步加载script
那怎么实现异步呢,问得好,script标签有两个完美的特性defer和async可以实现异步
他两都可以实现让script标签跟HTML分开加载和解析执行
那有啥区别呢
2. defer
- 首先说defer,他可以告诉浏览器,如果你碰到我,不要等待我加载和执行完,你继续往下处理你的HTML,我会在后台自己加载,等你处理完HTML构建出DOM,我再执行
<div>I`m Html</div><scriptdefersrc