script 标签应该放在html文件的什么位置

问题: 当在html文件中嵌入script标签时,正确的位置应该放在哪里?

分析

这里面主要涉及的是加载顺序、js是单线程。

由于浏览器解析是自上而下加载解析,如果一个很大的js文件放在head里面,由于js是单线程,那么浏览器会一直解析,而无法加载解析后面的dom tree,以至于页面出现空白,如果放在body最下面,这样dom tree会先加载解析,呈现出页面再加载解析js里面的内容,这样用户体验会更好。

如果js放在head里面,引用了某个dom,但是这时你还没加载dom tree,会报错,可以采用 window.onload = function(){}这样来解决,或者给js设置defer 或者 async来让js异步加载,这样就不会报错了。

当浏览器加载一个含有<script>标签的页面时,会发生以下动作:
1 获取HTML文件,拉取HTML页面(比如:index.html)
2 开始解析html文件
3 当解析器遇到一个<script>标签时,准备去获取<script>标签对应的js文件
4 当解析器获取js文件时,同时中断了页面上其他html的解析
5 一段时间后,js文件解析完毕,页面上其他的html标签继续解析

在第四步的时候,页面上的html解析阻断,给用户带来了不好的体验。

为什么会出现中断html解析?

任何script代码都能改变HTML的结构,通过document.write() 这种方式或者其他方式。 这就导致了HTML解析必须等待<script>全部被下载和执行完,HTML才能解析script标签之后余下的部分。
然而,大部分的Javascript开发者在加载文档过程中,不会通过script操作HTML的DOM结构。然而,他们必须等到<script>全部加载结束,才能看到页面。

废弃的解决方式

之前解决这个问题的方式是将<script>标签放在html文件的<body>标签之后执行

但这种加载方式存在的问题就是只有当所有的html元素加载完成后才能开始加载<script>标签的内容,如果这个加载需要花很长时间的话,那在这段时间内,就无法操作页面,要知道两秒之内不能操作页面的话,这个用户体验是非常差的。

现在的解决方案

现在浏览器<script>标签支持 asyncdefer 属性, 应用这些属性当<script>被下载时,浏览器更安全而且可以并行下载(下载script并不阻断HTML解析)。

async

<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>

async标记的 <script> 异步下载并执行。这意味着<script>下载时不阻塞HTML的解析,并且下载结束<script>马上执行。
上述代码 script2 可能比 script1 先下载完并执行完。

defer

<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>

defer标签的script顺序执行,这种方式也不会阻断浏览器解析HTML,同时下载结束时<script> 马上执行
上述代码中 script2 肯定比 script1 后执行完

结论

使用 asyncdefer属性来让你的网页不被block,但是前提要确保你的浏览器支持 这两个属性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值