前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库script type module defer 严格模式
HTML语义与文档

type="module" 脚本默认会阻塞 HTML 解析吗?

外部模块脚本及其依赖可与 HTML 解析并行获取,默认等文档解析完成后执行,行为类似普通脚本加 defer。模块默认是严格模式,顶层声明不会自动挂到全局对象。给模块脚本再加 defer 没有效果;加 async 则会改成依赖可用后尽快执行,不再按默认的解析后顺序等待。

前端进阶之旅 · 一题精讲更新于 2026.09.29
HTML#语义与文档
先看核心答案读代码示例
理解线索

模块默认等解析完成再执行

  1. 模块脚本按模块图获取依赖,入口通常等解析完成再运行
  2. defer额外写在模块脚本上无新效果,传统脚本则不同
  3. async依赖就绪后尽快运行,可能改变普通延后执行顺序

模块脚本默认已有延后执行行为,defer 对它无额外作用。

核心回答

先记住这个答案

外部模块脚本默认会并行获取,等 HTML 解析完成后再按模块依赖关系执行,因此无需再加 defer。它也天然运行在严格模式,顶层变量不会自动变成 window 的属性。若加 async,模块及依赖准备好后就尽快执行,不能再依赖普通延后脚本的原有先后顺序。

  • 模块依赖可并行获取
  • 模块默认延后执行
  • defer 对模块无额外作用
  • async 会改变执行时机

head 中的模块入口何时执行

页面 <head> 中加载应用入口。普通 <script src> 可能阻塞解析,改成 <script type="module" src="/app.js"> 后不必为了默认延后执行再写一遍 defer。若脚本需要操作正文 DOM,默认模块执行时文档结构已经解析完;但如果模块又动态等待异步依赖或执行了其他异步任务,不能把“解析完成”理解成所有业务逻辑已经就绪。

模块与经典脚本放进 headHTML
<head>
  <script type="module" src="/app.js"></script>
  <script defer src="/legacy.js"></script>
</head>
<body><main id="app"></main></body>
<!-- 模块默认延后执行;defer 对模块无额外作用 -->

浏览器为模块构建依赖图,获取入口与依赖并在适当时机执行;静态 import 的依赖先于导入它的模块求值。 示例把模块入口与传统 defer 脚本都放在 <head>,两者都不会像普通同步脚本那样阻断 HTML 解析。但模块还能导入依赖,依赖获取和求值可能延后入口运行;若传统脚本期待模块先设置某个全局变量,单凭标签位置并不稳。应让依赖通过模块导入、显式初始化函数或事件传递,不要依靠偶然的网络完成顺序。

模块默认等解析完成再执行

普通经典脚本不加 defer 或 async 时会在遇到时阻塞解析;经典脚本加 defer 与模块默认行为更接近。模块脚本跨源加载还受 CORS 规则影响,不能简单把旧脚本的 URL 原样替换。async 模块可能打乱与其他脚本的相对执行时序。

普通脚本没有 defer 时会在解析到标签处执行;模块入口则默认等文档解析后执行,因此放在 <head> 通常不需再加同义属性。但“解析完成后”不等于依赖已按源码顺序同步执行:模块图要先获取和求值。若页面初始化依赖多个入口的顺序,应显式通过 import 表达依赖关系,不要靠标签摆放位置碰运气。

如果模块入口依赖另一个模块的初始化,直接在入口里 import 它能让依赖关系进入模块图;把两个互不关联的 <script type="module"> 放在某种顺序里,不应成为表达业务依赖的唯一手段。加 async 更会改变执行时机,适合完全独立的埋点等模块,而页面主入口通常需要明确依赖和 DOM 准备条件。

回答前,多想一步

容易答错的地方

给模块加 defer 才以为不会阻塞解析
模块脚本默认已有延后执行行为,defer 对它无额外作用。
认为模块顶层变量会成为全局属性
模块拥有自己的作用域,顶层声明不会自动挂到 window。
试着用自己的话回答

面试官还会怎么问?

模块加 async 后会怎样?

入口和依赖准备好后尽快执行,不再保证默认的解析后顺序。

模块为什么要检查服务器 MIME?

模块脚本使用更严格的资源加载规则,错误的 JavaScript MIME 类型可能导致加载失败。

模块内部默认是严格模式吗?

是,模块代码自动采用严格模式,不需要写 use strict。

从一道题,走向一组知识

把知识连起来

语义与文档

表单计算结果为什么用 output,而不直接用 span?

模块脚本可更新表单 output,但加载时序要保证所需 DOM 已解析。

语义与文档

picture、source、srcset 和 sizes 各管哪一步?

响应式图片选源由浏览器图片算法决定,不会等待模块脚本手动切图。

参考资料

  • HTML:语义与文档参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. head 中的模块入口何时执行
  3. 模块默认等解析完成再执行
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑