prerender预加载页面时为什么会触发两次DOMContentLoaded事件?

Mc.雨晨 阅读 15

我在导航页给某个链接加了prerender预加载,结果发现目标页面的DOMContentLoaded事件触发了两次。明明代码看起来没问题,这是什么情况?

示例代码是这样的:


<link rel="prerender" href="/about.html" rel="external nofollow"  rel="external nofollow" >
<a href="/about.html" rel="external nofollow"  rel="external nofollow" >跳转到关于页</a>

目标页面about.html里用console.log测试过,当先点击导航再跳转时,控制台会显示两次”DOMContentLoaded”日志。如果直接访问about页面则正常只触发一次。查过MDN文档没找到相关说明,是不是预加载时会先完整加载页面导致重复触发?

尝试过把prerender换成prefetch,问题消失,但需要保持prerender的完整渲染特性,应该怎么解决重复触发的问题?

我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
UP主~圆圆
这问题我之前踩过坑,不是你的代码写得不对,而是 prerender 的机制导致的。prerender 会真的把整个页面在后台完整跑一遍,包括 DOM 解析、资源加载、脚本执行,所以 about.html 被预加载时就会触发一次 DOMContentLoaded。等你真正点击跳转过去的时候,浏览器发现这个页面已经 prerender 过了,就直接激活它,这时候页面又走了一遍生命周期,于是事件再触发一次。

换成 prefetch 就不会,因为 prefetch 只是下载 HTML 内容,不执行渲染流程,所以没这个问题。

标准写法是加个判断,确保 DOMContentLoaded 的逻辑只执行一次。可以用一个全局标记:

if (!window.domContentLoadedFired) {
window.domContentLoadedFired = true;
document.addEventListener('DOMContentLoaded', function() {
console.log('DOMContentLoaded');
// 你的初始化逻辑
});
}


这样即使页面被 prerender 加载一次、再被激活一次,核心逻辑也只会运行一回。

另外,如果你用了框架(比如 React 或 Vue),它们内部一般已经处理了这类重复执行的问题,但纯原生 JS 就得自己防重。建议所有依赖 DOM 的初始化都包一层 guard 条件。
点赞 4
2026-02-10 17:00