广告脚本加async仍阻塞渲染?因async仅适用于无dom操作、不依赖其他脚本的自包含sdk(如统计代码),而广告初始化常需读写dom或调用未加载的api,导致报错;正确方案是预加载资源、移至body底部延时执行、用intersectionobserver按需加载iframe并显式刷新。

广告脚本加 async 属性后仍阻塞渲染?先确认是否真适合 async
不是所有广告脚本都适合加 async。它只对「完全自包含、不读写 DOM、不依赖其他脚本」的脚本安全——比如百度联盟的 cm.js 或 Google Analytics 的统计代码。但如果你的广告初始化逻辑里有 document.getElementById、querySelector,或依赖某个容器元素已存在,加了 async 就大概率报 null 错误。
常见错误现象:BAIDU_CLB_fillSlotAsync is not defined 或容器 div#aside_1 找不到。这是因为脚本执行时 DOM 还没解析完,或广告 SDK 尚未加载就调用了填充函数。
- ✅ 安全用
async:埋点、上报、无 DOM 操作的 SDK(如hotjar.js) - ❌ 禁止用
async:含document.write、动态创建 iframe、调用googletag.display()或BAIDU_CLB_fillSlotAsync的初始化脚本 - ⚠️ 注意:
async对内联脚本无效,只对带src的外部脚本起作用
广告 iframe 必须用 data-src + IntersectionObserver 控制加载时机
loading="lazy" 对广告基本无效:它只对 HTML 中静态书写的 <iframe></iframe> 生效,而广告 SDK 返回的 iframe 是 JS 动态插入的,浏览器根本不会识别其 loading 属性。更糟的是,写死 src 可能导致页面一打开就发请求,浪费带宽甚至触发风控。
正确做法是占位 + 监听进入视口再注入真实地址:
- 广告容器写成:
<div class="ad-slot" data-ad-unit="/123/home_top"></div>,不设iframe,也不写src - 用
IntersectionObserver监听,threshold: 0.2(20% 可见即触发),避免快滑错过 - 触发后手动创建
iframe,设置sandbox="allow-scripts allow-popups"隔离执行环境 - 加载完成必须显式调用广告 SDK 的刷新方法,例如:
googletag.pubads().refresh([slot])或BAIDU_CLB_fillSlotAsync("aside_1")
预加载 cm.js 和 cm.css 能缩短实际加载延迟
浏览器默认不会主动预取广告资源,等脚本标签解析到才发起网络请求,中间有明显等待 gap。在 顶部加 <link rel="preload"> 可提前启动连接、DNS 查询和 TLS 握手。
实操只需两行:
<link rel="preload" href="https://cpro.baidustatic.com/cpro/ui/cm.js" as="script"><link rel="preload" href="https://cpro.baidustatic.com/cpro/ui/cm.css" as="style">
注意:as 值必须准确(script / style),否则浏览器可能忽略;路径必须与实际加载的脚本完全一致,包括协议和版本号。
若使用 Webpack/Vite 构建,也可通过 import('./ad-sdk.js') 动态导入,配合 prefetch hint 实现更精细控制。
把广告脚本移到 前并延迟 300ms 执行最稳妥
即使不用 async,把广告脚本从 移到 前,也能避开关键渲染路径。但要注意:不能紧贴着
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











