feat: PostHog 加载策略优化计划
目标
改进 PostHog 延迟加载策略,平衡首屏性能和数据完整性:
1. 使用 requestIdleCallback 替代固定 2 秒延迟
2. 保留关键事件(first_visit)的同步追踪,确保数据不丢失
This commit is contained in:
38
src/App.js
38
src/App.js
@@ -100,10 +100,9 @@ function AppContent() {
|
|||||||
const pageEnterTimeRef = useRef(Date.now());
|
const pageEnterTimeRef = useRef(Date.now());
|
||||||
const currentPathRef = useRef(location.pathname);
|
const currentPathRef = useRef(location.pathname);
|
||||||
|
|
||||||
// 🎯 ⚡ PostHog 延迟加载 + Redux 初始化(首屏不加载 ~180KB)
|
// 🎯 ⚡ PostHog 空闲时加载 + Redux 初始化(首屏不加载 ~180KB)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// ⚡ 延迟 2 秒加载 PostHog 模块,确保首屏渲染不被阻塞
|
const initPostHogRedux = async () => {
|
||||||
const timer = setTimeout(async () => {
|
|
||||||
try {
|
try {
|
||||||
const modules = await loadPostHogModules();
|
const modules = await loadPostHogModules();
|
||||||
if (!modules) return;
|
if (!modules) return;
|
||||||
@@ -115,13 +114,21 @@ function AppContent() {
|
|||||||
|
|
||||||
// 初始化 PostHog
|
// 初始化 PostHog
|
||||||
dispatch(posthogSliceModule.initializePostHog());
|
dispatch(posthogSliceModule.initializePostHog());
|
||||||
logger.info('App', 'PostHog 模块延迟加载完成,Redux 初始化已触发');
|
logger.info('App', 'PostHog 模块空闲时加载完成,Redux 初始化已触发');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('App', 'PostHog 延迟加载失败', error);
|
logger.error('App', 'PostHog 加载失败', error);
|
||||||
}
|
}
|
||||||
}, 2000);
|
};
|
||||||
|
|
||||||
|
// ⚡ 使用 requestIdleCallback 在浏览器空闲时加载,最长等待 3 秒
|
||||||
|
if ('requestIdleCallback' in window) {
|
||||||
|
const idleId = requestIdleCallback(initPostHogRedux, { timeout: 3000 });
|
||||||
|
return () => cancelIdleCallback(idleId);
|
||||||
|
} else {
|
||||||
|
// 降级:Safari 等不支持 requestIdleCallback 的浏览器使用 setTimeout
|
||||||
|
const timer = setTimeout(initPostHogRedux, 1000);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
|
}
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
// ⚡ 性能监控:标记 React 初始化完成
|
// ⚡ 性能监控:标记 React 初始化完成
|
||||||
@@ -150,22 +157,31 @@ function AppContent() {
|
|||||||
};
|
};
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
// ✅ 首次访问追踪
|
// ✅ 首次访问追踪(🔴 关键事件:立即加载模块,确保数据不丢失)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hasVisited = localStorage.getItem('has_visited');
|
const hasVisited = localStorage.getItem('has_visited');
|
||||||
|
|
||||||
if (!hasVisited) {
|
if (!hasVisited) {
|
||||||
const urlParams = new URLSearchParams(location.search);
|
const urlParams = new URLSearchParams(location.search);
|
||||||
|
const eventData = {
|
||||||
// ⚡ 使用延迟加载的异步追踪,不阻塞页面渲染
|
|
||||||
trackEventLazy('first_visit', {
|
|
||||||
referrer: document.referrer || 'direct',
|
referrer: document.referrer || 'direct',
|
||||||
utm_source: urlParams.get('utm_source'),
|
utm_source: urlParams.get('utm_source'),
|
||||||
utm_medium: urlParams.get('utm_medium'),
|
utm_medium: urlParams.get('utm_medium'),
|
||||||
utm_campaign: urlParams.get('utm_campaign'),
|
utm_campaign: urlParams.get('utm_campaign'),
|
||||||
landing_page: location.pathname,
|
landing_page: location.pathname,
|
||||||
timestamp: new Date().toISOString()
|
timestamp: new Date().toISOString()
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// 🔴 关键事件:立即加载 PostHog 模块并同步追踪(不使用 trackEventLazy)
|
||||||
|
// 确保首次访问数据不会因用户快速离开而丢失
|
||||||
|
(async () => {
|
||||||
|
const modules = await loadPostHogModules();
|
||||||
|
if (modules) {
|
||||||
|
// 使用同步追踪(trackEvent),而非异步追踪(trackEventAsync)
|
||||||
|
modules.posthogModule.trackEvent('first_visit', eventData);
|
||||||
|
logger.info('App', '首次访问事件已同步追踪', eventData);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
localStorage.setItem('has_visited', 'true');
|
localStorage.setItem('has_visited', 'true');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user