likes
comments
collection
share

面试官:给我说说script默认加载、defer、async加载方式的异同点

作者站长头像
站长
· 阅读数 25

前言

根据 什么?你还不知道浏览器渲染流程?这篇文章可以知道,页面从浏览器解析到<body/>的起始标签开始渲染,如果我们将<script/>都放在了<head/>中,那么浏览器将会在页面渲染前将所有的JS下载、解析和解释完毕后才开始渲染页面,这么做就有一个问题是用户不能接受的:页面白屏。所以我们通常会将<script/>放在<body>后面,这样可以使得在页面渲染完毕后执行JS,减少用户等待白屏的时间。

<script/>是用于加载JS脚本的标签,通常用于引入JS文件。在项目庞大到一定程度时,我们通常会使用多个<script/>标签来引入多个JS文件,包括第三方库cdn和内部JS,以防止JS内容过大阻塞页面加载进程,导致页面白屏。为了解决这个问题,我们可以对需要引入的JS文件进行优先级排序,将需要优先加载的JS文件放在前面(<script>默认是顺序加载)。看到这里,你心里肯定会想:就这???别急,接下来我们来看看高阶用法。

defer

HTML4 为 <script> 定义了defer属性,defer --- 推迟,延迟。和名字一样,在<script>中使用这个属性会先下载JS文件等到页面渲染后再执行下载的JS脚本内容。也就说:先下载,渲染后在执行。 eg:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script defer src="xxxx1.js"></script>
    <script defer src="xxxx2.js"></script>
    <title>Document</title>
  </head>
  <body>
  	<!-- 页面内容... -->
    <div id="app"></div>
  </body>
</html>

尽管这个案例中的 <script>放在了<head>中,但是浏览器在解析的时候只会将其下载到本地,跳过执行继续向下解析,等到页面渲染完成后再开始按顺序执行这里的<script>文件,另外需要说明的是尽管defer加载方式是推迟加载,但是执行的时候其顺序和出现顺序相同(这一点和默认的一样~)。需要注意的是:在MDN文档中提到,加载的script不能是module模块,否则将不起作用。 面试官:给我说说script默认加载、defer、async加载方式的异同点

async

HTML5 为<script>定义了async属性,该属性和async类似,但略有不同。它和defer都只适用于加载外部JS,都会让浏览器立即下载。不同点在于async不能保证按照出现的次序进行执行且是下载完就执行。 eg:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script async src="xxxx1.js"></script>
    <script async src="xxxx2.js"></script>
    <title>Document</title>
  </head>
  <body>
  	<!-- 页面内容... -->
    <div id="app"></div>
  </body>
</html>

另外,使用在使用async的时候可以使用module来引入外部模块。

总结

属性名加载JS限制加载JS方式加载顺序执行时期白屏产生时期使用moduel时是否会失效
默认同步同出现顺序下载完执行下载和执行时
defer限外部异步同出现顺序渲染后执行不产生白屏
async限外部异步无法保证下载完执行执行时产生

更清晰的图示: 图源 面试官:给我说说script默认加载、defer、async加载方式的异同点

转载自:https://juejin.cn/post/7393973660908437558
评论
请登录