haizlin / fe-interview

前端面试每日 3+1,以面试题来驱动学习,提倡每日学习与思考,每天进步一点!每天早上5点纯手工发布面试题(死磕自己,愉悦大家),6000+道前端面试题全面覆盖,HTML/CSS/JavaScript/Vue/React/Nodejs/TypeScript/ECMAScritpt/Webpack/Jquery/小程序/软技能……

Home Page:http://www.h-camel.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[html] 第25天 请说说<script>、<script async>和<script defer>的区别

haizhilin2013 opened this issue · comments

第25天 请说说<script><script async><script defer>的区别

  • <script> : 加载的时候是同步的会阻塞后面代码的执行,加载立即执行。
  • <script async>: 异步加载,加载和执行是并行的。
  • <script defer>: 异步加载,需等到所有文档加载完才执行。
<script defer>表示立即下载,但延迟执行(文档完成解析后)<script async>告知浏览器可以在允许的情况下异步执行脚本(这两个属性无法应用于内联系的script)
commented
  1. <script>立即加载并执行相应的脚本。会阻塞后面的文档加载;
  2. <script async>异步加载,脚本执行和后续文档代码加载同时进行;
  3. <script defer>异步加载,脚本的执行需等倒所有文档加载完才执行。

单纯的 <script> 会阻塞 DOM 的渲染,如果放在 <head> 标签中,对页面的显示会有延迟。如果是用过 src 引入外部资源时,浏览器会先停止解析下载外部资源,之后再执行其中的 javaScript(即立即加载并渲染)。

在添加 async 或者 defer 之后,<script> 的下载不会阻塞 DOM 的渲染。两者的区别如下:

  • async 在脚本下载完成后立即执行(此时会阻塞 DOM 的渲染),并且多个 async 脚本存在时,执行的顺序取决于下载完成的顺序。因此对于有前后依赖关系的脚本(比如 jQuery 以及依赖 jQuery 的组件库,就不适合 async
  • defer 在的脚本执行放在 DOM 渲染之后(对于老的浏览器如果不支持 defer 就不行了)。并且多个脚本时,其执行顺序时按照引入顺序执行的。比较符合实际项目众多的需求,但为了兼容老版本浏览器,最佳的实践还是把 <script> 放在 </body> 前。

三者在浏览器渲染时的区别:

参考文章:
スクリプトの非同期読み込み(async, defer の違い)
defer 和 async 的区别

参照图解:https://camo.githubusercontent.com/3cfc9c7f3ff4185cd5c2d9d40c03e942b98c6dfd/68747470733a2f2f692e737461636b2e696d6775722e636f6d2f77664c38322e706e67

1.script在执行的时候会阻塞 DOM 的渲染。
2.页面内内联的script标签,加载时立即执行所以会阻塞下面页面的渲染。
3. async异步加载,加载成功立即执行。
4. defer异步加载,但等到文档加载完成后才执行。
5.async、defer这两个属性无法应用于内联script。

  • 默认
    默认情况下加载script标签内容会阻塞后边代码的执行,加载后立即执行
  • defer
    defer属性表明脚本在执行时不会影响页面的构造,脚本会被延迟到整个页面解析完毕后在运行(延迟执行,异步加载)
  • async
    async属性只适合与外部脚本文件,标记为async的脚本并不保证按照指定他们的先后顺序执行(加载完就执行)

<script>从上到下依次执行加载,需要等待此脚本加载完成时再进行后续加载,会阻塞后续执行
<script async>加载时可以继续往下执行,异步的
<script defer>遇到此标签时,延时到页面加载完成后执行,异步的

细说异步加载和延迟加载

说到<script>标签,那么它是具有两个属性的,async异步加载和defer延迟加载

<script>

script标签放在head中,并且这个script标签只有scr属性引入外部js文件的情况下,HTML文件开始渲染,直到命中script标签,此时解析将停止,并发现一个请求获取该文件并执行。执行结束之前继承渲染HTML标签。

<script async>

async表示的意思是异步加载JavaScript文件。

使用async会在HTML解析期间下载文件,并在下载完成后暂停HTML的解析,执行下载的外部js文件,执行后继续解析HTML

<script defer>

defer表示的意思是在HTML文档解析之后在执行加载完成的JavaScript文件。

它和async的区别是,同样在HTML解析期间下载外部的js文件,但是下载完成后不会立即执行js脚本文件,而是等到HTML解析完成后才执行它。即在DOMContentLoaded之间执行已下载的外部js文件

<script> : 加载的时候是同步的会阻塞后面代码的执行,加载立即执行。 <script async>: 异步加载,加载和执行是并行的。 <script defer>: 异步加载,需等到所有文档加载完才执行。

script是最常见的引入JavaScript文件的方式,当浏览器遇到script标签时,它会停止解析文档,去下载并执行脚本文件,因此JavaScript文件很大或加载速度过慢,就会影响页面的加载速度
script async 标签用于异步加载JavaScript文件,在下载JavaScript文件的同时继续解析HTML网页,但异步加载不能保证按照引入顺序执行
script defer 异步加载,但它能保证按顺序执行代码,同async一样,但如果文件非常大或者加载速度慢,也会造成页面加载较慢

<script><script async><script defer> 是HTML中用于引入JavaScript代码的标签,它们之间有一些区别。

  1. <script> 标签:这是最常见的引入JavaScript代码的方式。当浏览器遇到 <script> 标签时,会立即停止解析HTML,并开始下载并执行JavaScript代码。默认情况下, <script> 标签会阻塞页面的解析和渲染,直到JavaScript代码执行完毕。

  2. <script async> 标签:使用 async 属性的 <script> 标签告诉浏览器在下载JavaScript文件时可以继续解析HTML,而无需等待JavaScript文件下载和执行完成。这意味着页面的解析和渲染不会被阻塞。一旦JavaScript文件下载完成,浏览器会立即执行它。多个 <script async> 标签之间的执行顺序是不确定的,因此如果有依赖关系,需要谨慎使用。

  3. <script defer> 标签:使用 defer 属性的 <script> 标签告诉浏览器在下载JavaScript文件时可以继续解析HTML,但是会推迟JavaScript代码的执行,直到HTML解析完成后再执行。多个 <script defer> 标签之间的执行顺序是按照它们在文档中出现的顺序执行的。这使得可以安全地在HTML中引入多个脚本文件,并确保它们按照正确的顺序执行。

总结:

  • <script> 标签会阻塞页面的解析和渲染,直到JavaScript代码执行完毕。
  • <script async> 标签允许页面的解析和渲染继续进行,不会阻塞,但是执行顺序不确定。
  • <script defer> 标签允许页面的解析和渲染继续进行,不会阻塞,并且保证按照顺序执行。

根据具体的需求和场景,选择适合的标签和属性来引入JavaScript代码,以达到最佳的性能和用户体验。