关于<script>的脚本执行机制:静态加载与动态生成

关于<script>的静态加载策略

  1. 无 defer 或 async 的 <script>(默认行为)
    • 加载:同步(阻塞式)下载,暂停 HTML 解析(即阻塞 DOM 构建和渲染)。
    • 执行:脚本下载完成后立即执行,执行期间继续阻塞渲染,执行完毕后才恢复解析。
  2. async 属性
    • 加载:异步下载,不阻塞 HTML 解析(与 DOM 构建并行)。
    • 执行:脚本下载完成后立即执行(无论 DOM 是否解析完成),执行期间可能短暂阻塞渲染。
    • 顺序:多个 async 脚本的执行顺序不可预测(取决于下载完成顺序)。
  3. defer 属性
    • 加载:异步下载,不阻塞 HTML 解析(与 DOM 构建并行)。
    • 执行:脚本会在 DOM 解析完成(DOMContentLoaded 事件触发前) 按文档顺序执行。
    • 顺序:多个 defer 脚本严格遵循在 HTML 中的声明顺序执行。

关于<script>的动态生成与应用场景

除此之外,script还可以动态生成,适用于以下应用场景:

  1. 延迟加载,减少首屏阻塞;

    // 在 DOM 解析完成后加载脚本(类似 defer)
    document.addEventListener('DOMContentLoaded', () => {
      const script = document.createElement('script');
      script.src = 'non-critical.js'; // 非关键脚本
      document.body.appendChild(script);
    });
    
    
  2. 用户触发特定行为(如点击按钮、滚动到某位置)后再加载脚本;

    document.getElementById('loadButton').addEventListener('click', () => {
      const script = document.createElement('script');
      script.src = 'component.js';
      document.head.appendChild(script);
    });
    
    
  3. 脚本 URL 需根据运行时条件(如用户权限、设备类型、用户语言等)动态生成;

    // 检查权限后加载对应脚本
    const userRole = 'admin'; // 实际从cookie/localStorage获取
    const script = document.createElement('script');
    script.src = userRole === 'admin' 
      ? 'https://cdn.example/admin-sdk.js' 
      : 'https://cdn.example/user-sdk.js';
    document.head.appendChild(script);
    
    
  4. 脚本加载失败时,动态回退到备用 CDN等应用场景;

    const script = document.createElement('script');
    script.src = 'https://unstable-cdn.com/library.js';
    script.onerror = () => {
      const fallback = document.createElement('script');
      fallback.src = '/local/library.js';
      document.head.appendChild(fallback);
    };
    document.head.appendChild(script);
    
    
  5. JSONP跨域请求(获取远程数据)。

    动态生成 <script> 标签并设置 src 的方式可以绕过 CORS 限制(而在脚本内通过 fetch/XHR 发起的 HTTP 请求会受CORS限制),但只能用于 JSONP这种特定场景,而不是通用的跨域请求方法。

    function handleData(data) {
      console.log(data); // 服务器返回:handleData({...})
    }
    const script = document.createElement('script');
    script.src = 'https://api.example.com/data?callback=handleData';
    document.head.appendChild(script);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值