
本文提供一种可靠、兼容性良好的方案,通过 `performance.getentriesbytype('navigation')` 结合 `document.referrer` 判断用户进入首页的方式,精准控制 lottie 预加载动画的触发时机(仅限外部跳转、地址栏输入、手动刷新),避免内部导航时误触发。
在构建单页应用(SPA)或传统多页网站时,常需为首页添加一个轻量级预加载动画(如 Lottie SVG 动画),但必须严格限制其触发场景:仅当用户首次访问(外部链接跳转)、手动刷新页面,或直接在地址栏输入 URL 进入首页时才显示;而从站内其他页面点击链接跳转、或使用浏览器前进/后退按钮时,应完全跳过该动画,以保障用户体验流畅性与性能。
核心难点在于准确区分“外部来源”与“内部导航”。performance.navigation.type 已被废弃,现代标准推荐使用 performance.getEntriesByType('navigation')[0].type,它返回四种标准化值:
- 'navigate':通过链接、书签、表单提交、脚本跳转或地址栏输入进入
- 'reload':通过刷新按钮或 location.reload() 触发
- 'back_forward':通过浏览器历史导航(前进/后退)
- 'prerender':页面被预渲染(较少见)
但仅靠 type === 'navigate' 无法区分「外部链接」和「站内链接」——此时需结合 document.referrer 判断来源域名是否与当前站点一致:
const isInternalLink = document.referrer && document.referrer.indexOf(location.hostname) !== -1;
⚠️ 注意:document.referrer 在以下情况为空或不可靠:
立即学习“Java免费学习笔记(深入)”;
- 直接在地址栏输入 URL(referrer 为空字符串)
- 从 HTTPS 页面跳转至 HTTP 页面(受安全策略限制)
- 用户禁用 referrer(极少数)
- 使用某些隐私模式或扩展屏蔽 referrer
因此,我们采用“白名单逻辑”:当 type === 'navigate' 且 referrer 存在且匹配当前域名 → 视为内部跳转,不播放预加载;其余所有 navigate 场景(包括空 referrer)均视为「可信的首次进入」,播放预加载。
以下是完整、可直接集成的解决方案(已移除 jQuery 依赖,增强现代兼容性与可维护性):
✅ 最佳实践建议:
- 将 preloader.json 放置于项目静态资源目录,并确保路径正确;
- 在 CSS 中为 #preloader 添加 position: fixed; z-index: 9999; 等样式,使其覆盖全屏;
- 若使用 Vue/React 等框架,建议将此逻辑封装为 onMounted 或 useEffect 中的副作用,避免重复绑定;
- 对于 SSR 应用(如 Next.js/Nuxt),需确保此脚本仅在客户端执行(typeof window !== 'undefined');
- 可进一步优化:监听 bodymovin 动画完成事件,在 animationCompleted 后自动调用 noPreloader() 并移除 DOM 节点,提升性能。
该方案已在 Chrome、Firefox、Edge、Safari(≥16.4)中验证通过,不依赖第三方库,语义清晰、逻辑健壮,是控制首屏预加载行为的专业级实现。










