如何监控Next.js Router页面加载耗时及router.push触发后的延迟?
追踪Next.js中router.push的导航延迟指标
一、手动埋点+路由事件结合
直接在触发router.push的操作节点记录起始时间,再通过Next.js的路由事件监听导航完成的时间点,计算两者差值即可得到精准延迟:
import { useRouter } from 'next/router'; const handleNavigation = async () => { // 记录用户触发导航操作的时间点 const start = performance.now(); const router = useRouter(); const onComplete = () => { // 计算从触发到导航完成的总耗时 const totalDelay = performance.now() - start; console.log('router.push 总延迟:', totalDelay); // 可在此处将数据上报至监控系统 router.events.off('routeChangeComplete', onComplete); }; router.events.on('routeChangeComplete', onComplete); // 触发路由跳转 await router.push('/target-page'); };
如果router.push前存在异步处理任务(如接口请求、数据预处理),需把起始时间放在任务启动前,才能覆盖从用户操作到页面可用的全流程耗时。
二、利用Performance API做阶段化标记
借助浏览器Performance API创建自定义标记和测量,可拆分延迟的不同阶段,更精准定位瓶颈:
const handleNavigation = async () => { // 标记用户触发操作的起始点 performance.mark('navigation-trigger-start'); // 模拟前置异步任务 await fetchRequiredData(); const router = useRouter(); const onComplete = () => { // 标记导航完成的时间点 performance.mark('navigation-complete'); // 测量两个标记间的总耗时 performance.measure('router-push-total-delay', 'navigation-trigger-start', 'navigation-complete'); // 获取测量结果 const measureResult = performance.getEntriesByName('router-push-total-delay')[0]; console.log('全流程延迟:', measureResult.duration); // 清理标记与测量数据,避免内存占用 performance.clearMarks('navigation-trigger-start'); performance.clearMarks('navigation-complete'); performance.clearMeasures('router-push-total-delay'); router.events.off('routeChangeComplete', onComplete); }; router.events.on('routeChangeComplete', onComplete); await router.push('/target-page'); };
三、监听细粒度路由生命周期事件
Next.js提供了更细分的路由事件,可按需针对性追踪阶段耗时:
routeChangeStart: 路由逻辑正式开始处理的节点beforeHistoryChange: 浏览器历史记录即将更新的节点routeChangeComplete: 目标页面渲染完成、可交互的节点
如果延迟主要来自路由本身的处理流程,可直接计算routeChangeStart到routeChangeComplete的时间差;若延迟来自前置任务,则以用户操作触发点作为起始时间。
注意事项
- 若目标页面使用
getServerSideProps或getInitialProps,客户端导航时这些服务端逻辑的执行时间会自动包含在总延迟中,上述方法可完整覆盖该部分耗时。 - 需监听
routeChangeError事件,记录导航失败场景下的耗时,避免监控数据缺失。
内容的提问来源于stack exchange,提问作者Dan Monego
相关产品推荐
相关产品推荐

