01. HTML Script 引入方式及特性分析 
1. 内联脚本(Inline Script) 
直接在 HTML 文件中使用 <script> 标签包裹代码:
html
<script>
  console.log("内联脚本执行");
</script>- 特点: - 立即执行,阻塞 HTML 解析
- 无法缓存,代码复用性差
- 适用于小型代码片段或 PWA 的 Service Worker 注册
 
2. 外部脚本(External Script) 
通过 src 属性引入外部文件:
html
<script src="app.js"></script>2.1 普通引入 
- 执行特点:
- 关键影响: - 阻塞 DOM 构建和渲染
- 脚本顺序执行(多个脚本按出现顺序加载执行)
 
2.2 async 属性 
html
<script src="app.js" async></script>- 核心特性: - 异步下载,不阻塞 HTML 解析
- 下载完成后立即执行,可能中断渲染
- 执行顺序不固定(先下载完成先执行)
- 适用场景:独立第三方脚本(如统计代码)
 - 执行流程: 
2.3 defer 属性 
html
<script src="app.js" defer></script>- 核心优势: - 异步下载,不阻塞 HTML 解析
- 延迟到 DOMContentLoaded 事件前顺序执行
- 保证脚本执行顺序(按文档中声明顺序)
- 适用场景:DOM 依赖型脚本
 - 执行时序: 
3. 模块化引入(type="module") 
html
<script type="module" src="app.js"></script>- 特殊行为: - 默认具有 defer特性
- 支持 ES6 模块语法(import/export)
- 可配合 async使用(此时忽略defer特性)
 - 模块加载示例: html- <script type="module"> import { init } from './utils.js'; init(); </script>
- 默认具有 
4. 动态脚本加载 
通过 JavaScript 动态创建脚本:
javascript
const script = document.createElement('script');
script.src = 'app.js';
document.head.appendChild(script);- 特点: - 默认具有 async行为
- 可通过 script.async = false改为同步加载
- 适用于按需加载场景
 
- 默认具有 
关键对比表格 
| 特性 | 普通脚本 | async | defer | type="module" | 
|---|---|---|---|---|
| 执行顺序 | 文档顺序 | 下载顺序 | 文档顺序 | 文档顺序 | 
| 阻塞解析 | 是 | 否 | 否 | 否 | 
| DOMContentLoaded 前完成 | 不一定 | 不一定 | 是 | 是 | 
| 支持 document.write | 是 | 禁止 | 禁止 | 禁止 | 
最佳实践建议 
- 主业务逻辑使用 defer保证 DOM 就绪
- 独立第三方库使用 async(如 analytics.js)
- 关键路径脚本可内联(需控制体积)
- 现代项目优先使用 type="module"+defer
- 动态加载非关键功能(如图表库)
javascript
// 性能优化示例:优先加载关键资源
const criticalScript = document.createElement('script');
criticalScript.src = 'critical.js';
document.head.prepend(criticalScript);
window.addEventListener('load', () => {
  // 延迟加载非关键脚本
  const nonCritical = document.createElement('script');
  nonCritical.src = 'analytics.js';
  nonCritical.async = true;
  document.body.appendChild(nonCritical);
});通过合理使用这些特性,可将页面加载性能优化 20-40%(根据 WebPageTest 实测数据)。需特别注意:async 脚本的执行可能影响 First Contentful Paint,而 defer 能更好地配合浏览器预加载扫描器工作。