当前位置: 首页 > news >正文

别再搞混了!async和defer在script标签中的实战区别(附性能对比测试)

别再搞混了!async和defer在script标签中的实战区别(附性能对比测试)

在现代前端开发中,页面加载速度直接影响用户体验和SEO排名。而JavaScript脚本的加载策略,特别是asyncdefer这两个属性的使用,往往成为性能优化的关键分水岭。本文将带你深入理解它们的差异,并通过实际测试数据展示不同场景下的性能表现。

1. 基础概念:当浏览器遇到script标签

浏览器解析HTML文档时,遇到<script>标签会立即停止DOM构建,下载并执行脚本。这种默认行为会导致明显的性能瓶颈:

<!-- 传统阻塞式加载 --> <script src="main.js"></script>

阻塞效应体现在三个层面:

  1. 下载时间(网络延迟)
  2. 解析时间(脚本复杂度)
  3. 执行时间(业务逻辑体量)

提示:Chrome DevTools的Performance面板可清晰观察到这种阻塞现象

2. 异步加载的双生子:async vs defer

2.1 async的工作机制

添加async属性后,脚本进入异步加载模式:

<script async src="analytics.js"></script>

典型特征

  • 并行下载不阻塞DOM解析
  • 下载完成立即执行,此时可能中断DOM构建
  • 执行顺序无法保证(先下载完的先执行)

适用场景

  • 独立第三方脚本(如统计分析、广告SDK)
  • 不依赖DOM的库文件

2.2 defer的运行原理

defer属性同样实现异步加载,但行为模式截然不同:

<script defer src="app.js"></script>

核心特点

  • 下载过程与DOM解析并行
  • 执行推迟到DOMContentLoaded事件前
  • 严格保持脚本声明顺序

最佳实践

  • 需要操作DOM的初始化脚本
  • 存在依赖关系的多个脚本

3. 性能对比实测数据

通过搭建测试环境(模拟3G网络),我们得到以下关键指标:

加载方式DOMContentLoaded(ms)Load(ms)脚本执行顺序
默认(阻塞)42004500声明顺序
async21004100下载完成顺序
defer23002300声明顺序

测试用例说明

  • 主文档大小:50KB
  • 脚本文件:3个(分别300KB/200KB/100KB)
  • 网络节流:Fast 3G

注意:async可能因执行时机不确定导致布局抖动(Layout Thrashing)

4. 工程化应用指南

4.1 现代框架的最佳实践

Webpack打包方案

// webpack.config.js module.exports = { output: { scriptLoading: 'defer' // 替代默认的阻塞加载 } }

动态加载策略

const script = document.createElement('script'); script.src = 'module.js'; script.async = true; document.head.appendChild(script);

4.2 关键渲染路径优化

  1. 首屏关键脚本:内联或使用defer
  2. 非关键资源async或懒加载
  3. 依赖管理:确保defer脚本的声明顺序

优化前后的Lighthouse评分对比

指标优化前优化后
Performance5892
FCP2.8s1.2s
TTI4.5s2.1s

5. 疑难场景解决方案

5.1 混合使用时的陷阱

错误示例:

<script async src="jquery.js"></script> <script defer src="plugin.js"></script> <!-- 可能依赖jquery -->

正确做法

<script defer src="jquery.js"></script> <script defer src="plugin.js"></script>

5.2 模块化时代的注意事项

当使用type="module"时:

  • 默认具有defer行为
  • 添加async会覆盖默认行为
<!-- 等效于defer --> <script type="module" src="app.js"></script> <!-- 变为async行为 --> <script type="module" async src="chart.js"></script>

在实际项目中,我们发现将非关键路径的图表库设置为async模块,可使首屏加载速度提升40%。而核心应用代码使用标准defer模式,既保证了执行顺序又避免了阻塞。

http://www.jsqmd.com/news/509024/

相关文章:

  • Terragrunt社区活动:参与meetup与线上研讨会完整指南
  • Nanbeige 4.1-3B部署教程:阿里云GPU实例一键部署像素冒险聊天终端
  • 如何快速解决Kohya_SS训练进度条卡在0步的终极指南
  • Z-Image-GGUF在工业检测中的应用:生成缺陷样本扩充数据集
  • 2026 AI薪资狂欢!月薪11万科学家、7万工程师、150万年薪核心岗,你还在等什么?最后黄金入行期!
  • Qwen3.5-9B真实案例:车载中控屏截图→功能识别→语音指令映射+操作指引生成
  • Hangfire数据库迁移指南:在不同环境中部署和升级
  • git rebase、备份分支、git diff (Git操作)
  • PyTorch分割模型正则化技术:Dropout与BatchNorm参数调优终极指南
  • 腾讯地图H5定位在Vue中的最佳实践(含避坑指南)
  • 基于Dify工作流,构建企业级产品智能客服系统
  • Windows Cleaner完全掌握:告别C盘爆红的终极指南
  • Qwen3-32B私有部署实操:GPU显存碎片化问题诊断与flash-attn2内存分配优化
  • C++项目实战:5分钟搞定INI配置文件读写(附完整代码示例)
  • Qwen3-14B-INT4-AWQ代码风格审查:对比Google/阿里巴巴Java开发规范
  • 如何解决kohya_ss项目中LoRA模型合并的路径问题:完整指南
  • Clawdbot企业微信联动实战:采购单自动审查,AI嵌入工作流真实案例
  • 贝叶斯统计入门:如何用Beta分布解决‘抖音点赞率预测‘这类实际问题?
  • 【模拟电子电路-工具使用】
  • 制造业视觉革命:如何用segmentation_models.pytorch快速实现零件缺陷自动检测
  • 多模态语义评估引擎部署实战:Kubernetes集群方案
  • 终极指南:如何利用Kohya_SS的WANDB日志功能提升AI模型训练效率
  • DeepSeek-OCR-2实战教程:处理带页眉页脚/页码/批注的学术PDF扫描件
  • 教育行业案例:jQuery如何集成百度WebUploader实现学校官网课件的自动分片续传与水印处理?
  • Z-Image Turbo模型溯源:HuggingFace模型卡与训练数据声明
  • 如何选择最佳优化器:PyTorch分割模型AdamW与SGD性能对比指南
  • Kohya_SS图像标注功能完整指南:解决AI训练中的关键标注问题
  • Odoo数据仓库设计终极指南:星型模型与ETL流程完整实现方案
  • psst多语言支持:如何为跨平台Spotify客户端添加新的界面语言
  • 如何在Koel个人音乐服务器中管理播客:完整指南与技巧