JS中<script>标签放置位置的区别

2,074 阅读2分钟

JS中<script>标签放到页面头部和尾部的区别

浏览器渲染机制

当我们从服务器请求会来的HTML页面资源后,浏览器会开辟一个GUI的渲染线程(浏览器打开页面是开辟一个进程,里面存在很多线程,其中包含用来做页面渲染和执行JS的GUI渲染线程,所以JS以及页面渲染是单线程的)用来自上而下渲染和解析我们的代码!

在渲染的过程中如果遇到<link>/<img>/<video>等标记,浏览器会单独开辟出HTTP加载线程去服务器加载资源文件,GUI线程会继续向下渲染(不会阻碍GUI的渲染)

页面加载的步骤

DOM TREE->CSSOM TREE->RENDER TREE->LAYOUT(布局、回流)->PAINTING(绘制)...修改了元素的结构和样式,会重新进行布局和绘制,引发DOM的回流(重排)和重绘;但是如果遇到的是<script>,则不会开辟新的HTTP加载线程,是当前GUI线程自己去加载资源文件,导致渲染被阻碍(script默认是立即加载渲染的),只有JS执行完,页面才会继续向下渲染!

所以在项目中,我们一般会把JS加载放到页面的尾部

  • 防止其阻碍GUI的渲染,让DOM TREE等尽快完成
  • 放到DOM的前面(如:页面的头部)加载JS的时候,此时我们还没有渲染出DOM,无法基于JS获取到DOM元素

放到头部的情况

在项目中,我们如果把<script>放到头部经常处理的事情:

  • 给script设置defer或者async标识来进行异步修饰(两者都不会阻碍GUI的渲染,都是异步去加载资源文件)
    • async是加载完文件,立即去执行(此时会阻碍GUI的渲染),谁先加载回来就先执行谁,没有顺序之分
    • defer是需要等待GUI渲染完后,统一按照之前编写的script顺序,一次吧JS执行
  • 除了设置这些标识,我们也可以基于事件监听的方式来处理:基于window.onload=function(){}或者window.addEventListener('DOMContentLoaded',function(){})任何一种方式,都可以让DOM结构加载完后,再去执行对应的JS代码,此时我们就可以获取对应的DOM元素了

本文使用 mdnice 排版

![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/5/8/171f4133a096c953~tplv-t2oaga2asx-image.image) ![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/5/8/171f4134f73f5c21~tplv-t2oaga2asx-image.image) ![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/5/8/171f413a0cdb1ab9~tplv-t2oaga2asx-image.image)