稀土掘金技术社区 2024年11月17日
不是吧,沟通的async、defer都搞不清楚你就敢写熟练HTML啊??
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文详细介绍了HTML中script标签的async和defer属性,以及它们与默认script标签的区别和用法。通过文字讲解、官方图片和示例代码,阐述了三种用法下浏览器解析HTML和执行JavaScript脚本的顺序。重点说明了async和defer属性可以避免脚本加载阻塞HTML解析,从而提升页面加载速度,并对三种用法在实际应用中的场景进行了分析。文章旨在帮助前端开发者理解script标签的特性,提升页面性能,避免白屏问题,并提升前端基础功水平。

🤔默认script标签:浏览器解析HTML遇到默认script标签时,会暂停解析,加载并执行JavaScript脚本,之后再继续解析HTML。这种方式容易造成页面加载缓慢,出现白屏现象。

🚀async属性:浏览器遇到async属性的script标签时,会异步加载脚本,不会阻塞HTML解析。脚本加载完成后立即执行,但执行过程中会阻塞HTML解析。适用于与其他资源加载无关的独立脚本。

⏱️defer属性:浏览器遇到defer属性的script标签时,会异步加载脚本,不会阻塞HTML解析。脚本加载完成后,等到HTML解析完成后再执行。适用于多个脚本之间存在依赖关系的情况,可以确保脚本按顺序执行。

🔄三种用法混用:实际场景中,可以将三种用法结合使用,例如将与页面渲染无关的脚本使用async,将存在依赖关系的脚本使用defer。

⚠️注意:async和defer属性的优先级,async的优先级高于defer。

原创 天天鸭 2024-11-17 09:01 重庆

点击关注公众号,“技术干货”及时达!

点击关注公众号,“技术干货” 及时达!

回想起当年面试时面试官问我:你简历上说熟练HTML,那么说说scriptasync、defer的区别吧。当时一下就蒙了,心想工作中好像从来没有用到过啊,那次之后我细细查阅资料才彻底理解它们的作用和区别。

这算是很经典面试题了,这面试题目没有难度,但却可以体现一个前端的基本功水平,因此下面除了文字讲解外还会配合官方的图片和博主自定义的示例,便于更深刻理解。

先汇总一下在 HTML 中的 script会有这三种用法,然后下面一一说明。

    默认按顺序执行用法: <script src='https://...'></script>

    脚本下载完马上执行用法: <script src='https://...' async></script>

    脚本下载完最后执行用法: <script src='https://...' defer></script>

「解释:」 当浏览器正在执行解析 HTML 代码块时,如果遇到默认的 script 标签,就会阻塞从而暂停解析 HTML 的剩余代码,去加载该 javascript 脚本,脚本加载完成之后会立即执行脚本,最后继续解析 HTML 代码。

配合下图理解更直观。

再看看如下示例代码解释

<html lang="zh">  <head>    <script>        console.log("Hello log~");    </script>    <script src="https://.../Chart.min.js"></script>    <script src="https://.../moment.min.js"></script>    <script src="https://.../vue.min.js"></script>  </head>  <body>    您好,我是天天鸭的示例1  </body></html>

执行顺序会如下:

    执行打印:console.log("Hello log~");

    下载并执行Chart外部脚本:Chart.min.js

    下载并执行moment外部脚本:moment.min.js

    下载并执行vue外部脚本:vue.min.js

    显示文本内容:您好,我是天天鸭的示例1

「注意:」 默认script会按顺序执行脚本,如果中间有一个脚本执行时间长, 后续的脚本就会排队,HTML也停止解析等待执行完成,这时会有白屏情况出现。

「解释:」 当浏览器正在执行解析 HTML 代码块时,如果遇到 script 标签并且标识是async,不会阻塞解析 HTML的剩余代码, 而是异步请求去加载该 javascript 脚本,但脚本加载完成之后会立即执行脚本并且此时会阻塞停止解析HTML,最后执行完脚本继续解析 HTML 代码。

配合下图理解更直观。

再看看如下示例代码解释

<html lang="zh">  <head>    <script>        console.log("Hello log~");    </script>    <script async src="https://.../Chart.min.js" ></script>    <script async src="https://.../moment.min.js"></script>    <script async src="https://.../vue.min.js"></script>  </head>  <body>    您好,我是天天鸭的示例2  </body></html>

执行顺序会如下:

    执行打印:console.log("Hello log~");

    异步下载Chart.min.js、moment.min.jsvue.min.js脚本,此时HTML正常解析中

    下载完开始脚本,此时阻塞HTML解析

    最后接着解析剩下HTML

「注意:」async标识的script会在执行脚本时阻塞HTML解析,但下载脚本时不会,所以如果页面HTML结构比较简单那么会在脚本下载过程中就已经执行完成,因此上述例子是屏幕先显示您好,我是天天鸭的示例2,再执行脚本。

如果HTML结构复杂且量大解析时间较长,会在脚本执行时中断,执行完成接着解析。

「解释:」 当浏览器正在执行解析 HTML 代码块时,如果遇到有 script 标签并且标识是defer,不会阻塞解析 HTML 的剩余代码, 而是异步请求去加载该 javascript 脚本,但脚本加载完成之后并不会立即执行脚本,直到最后解析完 HTML 代码,最后再去执行脚本。

配合下图理解更直观。

再看看如下示例代码解释

<html lang="zh">  <head>    <script>        console.log("Hello log~");    </script>    <script defer src="https://.../Chart.min.js" ></script>    <script defer src="https://.../moment.min.js"></script>    <script defer src="https://.../vue.min.js"></script>  </head>  <body>    您好,我是天天鸭的示例3  </body></html>

执行顺序会如下:

    执行打印:console.log("Hello log~");

    异步下载Chart.min.js、moment.min.jsvue.min.js脚本,此时HTML正常解析中

    下载完脚本后不会立即执行,等待HTML全部解析完显示文本内容:您好,我是天天鸭的示例3

    最后执行脚本

「注意:」  如果多个defer脚本,浏览器会并行下载,无论下载速度的快慢都不影响执行的顺序,会按HTML中出现的顺序依次执行。

真实场景可以会几种方法混用,示例如下。

<html lang="zh">  <head>    <script>        console.log("Hello log~");    </script>    <script defer src="https://.../Chart.min.js" ></script>    <script async src="https://.../moment.min.js"></script>    <script defer src="https://.../vue.min.js"></script>  </head>  <body>    您好,我是天天鸭的示例4  </body></html>

执行顺序会如下:

    执行打印:console.log("Hello log~");

    异步下载Chart.min.js、moment.min.jsvue.min.js脚本

    因为HTML比较简单,脚本下载过程中就执行完成了,显示文本内容:您好,我是天天鸭的示例4。

    moment.min.js脚本下载完成后马上执行

    Chart.min.jsvue.min.js会在HTML解析完成后执行

因此,理论上如果脚本独立的与其它资源加载没有关联可以选择async(可能会阻塞), 但脚本之间存在依赖关系需要选择defer

「注意:」 如果同时存在async,defer属性,async优级更高

好啦先写到这时,如果那里写的不好或者不对,欢迎指出。

点击关注公众号,“技术干货” 及时达!

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

HTML JavaScript async defer script
相关文章