在HTML页面上加载脚本时,需要注意不要损害页面的加载性能。取决于将脚本添加到HTML页面的位置和方式,将影响加载时间
在HTML页面上加载脚本时,需要注意不要损害页面的加载性能。
传统上,脚本是通过以下方式包含在页面中的:
<script src="script.js"></script>
只要HTML解析器找到这一行,就会请求获取脚本,并执行脚本。
一旦完成此过程,就可以继续进行解析,然后可以分析HTML的其余部分。
您可以想象,此操作可能会对页面的加载时间产生巨大影响。
如果脚本的加载时间比预期的要长一点,例如,如果网络有点慢,或者您使用的是移动设备,并且连接有点草率,则访问者可能会看到空白页,直到脚本被加载为止。加载并执行。
位置很重要
初学HTML时,系统会告诉您脚本标签实时存在于<head>
标签:
<html>
<head>
<title>Title</title>
<script src="script.js"></script>
</head>
<body>
...
</body>
</html>
正如我之前告诉您的那样,当解析器找到这一行时,它将去获取脚本并执行它。然后,完成此任务后,它将继续解析正文。
这很糟糕,因为引入了很多延迟。解决此问题的一种非常常见的方法是将script
标签位于页面底部,紧接在结束之前</body>
标签。
这样做时,在所有页面都已被解析和加载之后,脚本便被加载并执行,这是一个巨大的进步在head
选择。
如果需要支持不支持HTML的两个相对较新的功能的旧版浏览器,这是最好的选择。async
和defer
。
异步和延迟
异步和延迟都是布尔属性。它们的用法类似:
<script async src="script.js"></script>
<script defer src="script.js"></script>
如果您同时指定,async
在现代浏览器上优先,而支持该功能的旧版浏览器defer
但不是async
将回退到defer
。
有关支持表,请访问caniuse.com以获取异步信息https://caniuse.com/#feat=script-async并推迟https://caniuse.com/#feat=script-defer
仅当在head
页面的一部分,如果您将脚本放在body
就像我们在上面看到的页脚。
性能比较
头部无延迟或异步
这是网页在不延迟或异步的情况下加载脚本的方式,head
页面的一部分:
暂停解析,直到提取并执行脚本。完成此操作后,将继续解析。
体内没有延迟或异步
这是网页加载脚本时没有延迟或异步的方式,该脚本位于body
标签,就在它关闭之前:
解析没有任何暂停即可完成,完成后,将提取并执行脚本。解析是在脚本下载完成之前完成的,因此该页面以用户的方式显示在上一个示例之前。
与异步,在头上
这是网页加载脚本的方式async
,放在head
标签:
该脚本是异步获取的,准备就绪后,HTML解析将暂停以执行该脚本,然后将其恢复。
延后,在头上
这是网页加载脚本的方式defer
,放在head
标签:
该脚本是异步获取的,只有在HTML解析完成后才执行。
解析完成就像我们将脚本放在末尾一样body
标记,但总体而言,脚本执行早于完成,因为脚本是与HTML解析同时下载的。
所以这是速度方面的制胜法宝🏆
阻止解析
async
阻止页面解析,而defer
才不是。
阻止渲染
两者都不async
也不defer
确保在阻止渲染时采取任何措施。这取决于您和您的脚本(例如,确保脚本在onLoad
) 事件。
dom互动
标记脚本defer
在之后执行domInteractive
事件,发生在HTML加载,解析并DOM建成。
此时的CSS和图像仍然需要解析和加载。
完成此操作后,浏览器将发出domComplete
事件,然后onLoad
。
domInteractive
之所以重要,是因为它的时间被认为是感知加载速度的量度。查看MDN更多。
保持秩序
另一个案例defer
:标记的脚本async
当它们可用时,将以随意的顺序执行。标记脚本defer
(在解析完成之后)按照标记中定义的顺序执行。
告诉我最好的方法
使用脚本时,加快页面加载速度的最佳方法是将其放入head
,然后添加一个defer
归因于您script
标签:
<script defer src="script.js"></script>
这是触发更快的情况domInteractive
事件。
考虑到的优点defer
,似乎是一个更好的选择async
在各种情况下。
除非可以延迟页面的第一次渲染,否则请确保在解析页面时,所需的JavaScript已经执行。
免费下载我的JavaScript初学者手册
更多浏览器教程:
- HTML5提供了一些有用的技巧
- 我如何使基于CMS的网站脱机工作
- 渐进式Web应用程序完整指南
- 提取API
- 推送API指南
- 频道消息传递API
- 服务人员教程
- 缓存API指南
- 通知API指南
- 深入IndexedDB
- Selectors API:querySelector和querySelectorAll
- 通过延迟和异步有效地加载JavaScript
- 文档对象模型(DOM)
- Web存储API:本地存储和会话存储
- 了解HTTP Cookies的工作原理
- 历史API
- WebP图像格式
- XMLHttpRequest(XHR)
- 深入的SVG教程
- 什么是数据网址
- 学习网络平台的路线图
- CORS,跨域资源共享
- 网络工作者
- requestAnimationFrame()指南
- 什么是Doctype
- 使用DevTools控制台和控制台API
- 语音合成API
- 如何在纯JavaScript中等待DOM ready事件
- 如何将类添加到DOM元素
- 如何遍历来自querySelectorAll的DOM元素
- 如何从DOM元素中删除类
- 如何检查DOM元素是否具有类
- 如何更改DOM节点值
- 如何将click事件添加到从querySelectorAll返回的DOM元素列表中
- WebRTC,实时Web API
- 如何在JavaScript中获取元素的滚动位置
- 如何替换DOM元素
- 如何只接受输入文件字段中的图像
- 为什么要使用浏览器的预览版?
- Blob对象
- 文件对象
- FileReader对象
- FileList对象
- ArrayBuffer
- ArrayBufferView
- URL对象
- 类型数组
- DataView对象
- BroadcastChannel API
- Streams API
- FormData对象
- 导航器对象
- 如何使用地理位置API
- 如何使用getUserMedia()
- 如何使用拖放API
- 如何在网页上滚动
- 在JavaScript中处理表单
- 键盘事件
- 鼠标事件
- 触摸事件
- 如何从DOM元素中删除所有子级
- 如何使用原始Javascript创建HTML属性
- 如何检查是否使用JavaScript选中了复选框?
- 如何使用JavaScript复制到剪贴板
- 如何使用JavaScript禁用按钮
- 如何在浏览器中使页面可编辑
- 如何使用URLSearchParams在JavaScript中获取查询字符串值
- 如何一次删除页面上的所有CSS
- 如何使用insertAdjacentHTML
- Safari,退出前警告
- 如何使用JavaScript将图像添加到DOM
- 如何重设表格
- 如何使用Google字体