UNPKG

perf-observer-kit

Version:

A lightweight, flexible library for monitoring web performance metrics including Core Web Vitals, resource loading performance, long tasks, and navigation timing.

156 lines 5.26 kB
import { NetworkMetricsCollector } from '../../utils/network-metrics'; import { calculateTimeDelta } from '../../utils/time'; import { logger } from '../../utils/logger'; /** * 基础观察者类 * 提供所有Web指标观察者共享的功能 */ export class BaseObserver { constructor(options) { this.observer = null; // 页面可见性和用户交互相关属性 this.isPageVisible = true; this.userHasInteracted = false; this.visibilityChangeHandler = null; this.userInteractionHandler = null; this.pageshowHandler = null; this.onUpdate = options.onUpdate; } /** * 启动观察 */ start() { this.setupVisibilityTracking(); this.setupUserInteractionTracking(); this.setupPageshowListener(); this.observe(); } /** * 停止观察 */ stop() { if (this.observer) { this.observer.disconnect(); this.observer = null; } this.cleanupEventListeners(); } /** * 清理事件监听器 */ cleanupEventListeners() { // 移除页面可见性监听 if (this.visibilityChangeHandler && typeof document !== 'undefined') { document.removeEventListener('visibilitychange', this.visibilityChangeHandler); this.visibilityChangeHandler = null; } // 移除用户交互监听 if (this.userInteractionHandler && typeof document !== 'undefined') { document.removeEventListener('click', this.userInteractionHandler); document.removeEventListener('keydown', this.userInteractionHandler); this.userInteractionHandler = null; } // 移除pageshow监听 if (this.pageshowHandler && typeof window !== 'undefined') { window.removeEventListener('pageshow', this.pageshowHandler); this.pageshowHandler = null; } } /** * 设置页面可见性跟踪 */ setupVisibilityTracking() { if (typeof document === 'undefined') { return; } this.isPageVisible = document.visibilityState === 'visible'; this.visibilityChangeHandler = (event) => { this.isPageVisible = document.visibilityState === 'visible'; logger.debug('页面可见性变化:', this.isPageVisible ? '可见' : '隐藏'); // 通知子类可见性变化 this.onVisibilityChange(this.isPageVisible); }; document.addEventListener('visibilitychange', this.visibilityChangeHandler); } /** * 设置用户交互跟踪 */ setupUserInteractionTracking() { if (typeof document === 'undefined') { return; } this.userInteractionHandler = (event) => { if (this.userHasInteracted) { return; // 已经处理过用户交互了,不重复处理 } this.userHasInteracted = true; logger.debug('用户已交互'); }; // 监听点击和键盘事件 document.addEventListener('click', this.userInteractionHandler); document.addEventListener('keydown', this.userInteractionHandler); } /** * 设置bfcache恢复监听 */ setupPageshowListener() { if (typeof window === 'undefined') { return; } this.pageshowHandler = (event) => { // 只有当页面是从bfcache恢复时才处理 if (event.persisted) { logger.info('页面从bfcache恢复'); // 重置用户交互状态 this.userHasInteracted = false; // 由子类实现具体的bfcache恢复处理 this.onBFCacheRestore(event); } }; window.addEventListener('pageshow', this.pageshowHandler); } /** * 获取网络状态信息 * @returns 网络信息对象 */ getNetworkInformation() { return NetworkMetricsCollector.getNetworkInformation(); } /** * 获取完整的网络上下文 * @param extraContext 额外的上下文信息 * @returns 完整的上下文数据 */ getNetworkContext(extraContext = {}) { // 获取当前页面URL const currentUrl = typeof window !== 'undefined' ? window.location.href : undefined; return NetworkMetricsCollector.getNetworkContext({ ...extraContext, userHasInteracted: this.userHasInteracted, url: currentUrl }); } /** * 计算两个时间点之间的差值,确保结果为非负 * @param end 结束时间点 * @param start 开始时间点 * @returns 非负的时间差值 */ calculateTimeDelta(end, start) { return calculateTimeDelta(end, start); } /** * 页面可见性变化时的回调 - 可由子类重写 * @param isVisible 页面是否可见 */ onVisibilityChange(isVisible) { // 默认实现为空,由子类覆盖 } /** * BFCache恢复处理 - 由子类重写 */ onBFCacheRestore(event) { // 默认实现为空,由子类覆盖 } } //# sourceMappingURL=base-observer.js.map