广告不显示主因是脚本阻塞、iframe sandbox缺失、lazy加载误用及DOM重复插入;须加async、显式sandbox、禁用loading="lazy"、用IntersectionObserver按需创建iframe并幂等插入。

广告脚本没加 async,HTML 解析直接卡死
浏览器遇到没带 async 或 defer 的 <script src="ad.js"></script>,会立刻暂停 HTML 解析,等脚本下载、执行完才继续——首屏 DOM 树根本建不起来,广告位自然空白。
常见现象:页面文字/图片全不出现、DOMContentLoaded 延迟 2s+、LCP 指标崩坏。
- 所有第三方广告 SDK 脚本(如
gpt.js、qg.js)必须显式加async - 严禁放在
里;移到开头,紧贴首屏容器之后 - 删掉内联初始化代码(比如
googletag.cmd.push(...)),统一用googletag.enableServices()在脚本加载完成后调用
广告 iframe 没设 sandbox,被浏览器静默拦截
sandbox="" 或空值的 sandbox 属性,等于让浏览器直接拒绝解析 iframe 内容。Network 面板显示 net::ERR_BLOCKED_BY_RESPONSE,控制台无报错、无日志、无请求——广告位彻底空白,且查不到原因。
- 广告
必须显式写sandbox="allow-scripts allow-popups",不能只写sandbox - 绝对禁止
allow-same-origin和allow-top-navigation,前者破坏隔离,后者可能被用于跳转劫持 - 如果广告返回的是内联 JS(如
onclick、javascript:void(0)),仅allow-scripts不够,需确认 SDK 是否支持无内联行为模式;否则改用动态fetch+innerHTML注入
广告容器用了 loading="lazy",反而触发重复加载
原生 loading="lazy" 只对静态 HTML 中直接书写的 生效。广告 SDK 多数动态创建 iframe,或返回跨域 src,该属性会被忽略。更糟的是:浏览器可能提前预加载 src,JS 再调一次 refresh(),造成两次曝光计费。
- 广告容器一律不用
- 改用占位
- 用
IntersectionObserver监听进入视口(threshold: 0.2),触发后手动创建 iframe 并设src - 容器必须预设宽高(如
style="width:300px;height:250px;"),否则加载时 layout shift 会触发 CLS 报警
广告 JS 加载后反复插入 DOM,节点重复出现
资源重试本身不导致重复,真正原因是插入逻辑被多次执行。比如你在 DOMContentLoaded 和 window.onload 里都调了同一函数,或第三方 SDK 内部也用了 innerHTML +=,而你又手动调了一次。
- 查 Network 面板的
Initiator列,定位触发 DOM 插入的 JS 行(不是请求行) - 避免
innerHTML += ':每次执行都会销毁原有节点、清空事件监听器 - 改用
document.createElement('iframe') + appendChild(),或加data-injected="true"标记做幂等判断 - 若页面同时存在原生 JS 插入和 Vue/React 接管区域,检查框架是否覆盖了容器(如
new Vue({ el: '#ad-container' })),会导致 diff 算法误判并复制节点
广告不显示的多数情况,不是“没配好”,而是“多配了”——比如加了 loading="lazy" 还自己手写 IntersectionObserver,或者既信了 SDK 的自动初始化,又在页面里手动 render() 一遍。这类叠加动作在本地开发时可能侥幸通过,一上生产环境就因加载时机微差而失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











