AwsLinker/lib/performance-config.ts
2025-09-16 17:19:58 +08:00

360 lines
12 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 性能优化配置
export const performanceConfig = {
// 缓存配置
cache: {
// API 缓存时间 (秒)
apiCacheDuration: 3600, // 1小时
// ISR 重新验证时间 (秒)
isrRevalidate: 3600, // 1小时
// 静态资源缓存时间
staticAssetsCacheDuration: 86400, // 24小时
},
// 预加载配置
prefetch: {
// 关键页面列表
criticalPages: ['/products', '/news', '/contact', '/support', '/about'],
// 预加载延迟 (毫秒)
prefetchDelay: 100,
// 关键图片列表
criticalImages: [
'/images/hero-bg.jpg',
'/images/cloud-services.jpg',
'/images/aws-logo.png',
'/images/server-room.jpg',
],
},
// 图片优化配置
images: {
// 图片质量
quality: 85,
// 响应式图片断点
breakpoints: [640, 768, 1024, 1280, 1536],
// 图片格式优先级
formats: ['webp', 'avif', 'jpg', 'png'],
// 懒加载距离
lazyLoadRootMargin: '50px',
},
// 代码分割配置
codeSplitting: {
// 重要组件预加载
importantComponents: [
'Header',
'Footer',
'NewsArticleServerComponent',
'ProductsServerComponent',
],
// 延迟加载的组件
lazyComponents: [
'ContactForm',
'NewsletterSubscribe',
'ChatWidget',
],
},
// 性能监控配置
monitoring: {
// Core Web Vitals 阈值
coreWebVitals: {
lcp: 2500, // Largest Contentful Paint (ms)
fid: 100, // First Input Delay (ms)
cls: 0.1, // Cumulative Layout Shift
},
// 启用性能监控
enabled: process.env.NODE_ENV === 'production',
// 性能数据上报URL
reportUrl: process.env.NEXT_PUBLIC_PERFORMANCE_API,
},
// CDN 配置
cdn: {
// 静态资源CDN域名
domain: process.env.NEXT_PUBLIC_CDN_DOMAIN || '',
// 图片CDN域名
imageDomain: process.env.NEXT_PUBLIC_IMAGE_CDN_DOMAIN || '',
// 启用CDN
enabled: process.env.NODE_ENV === 'production',
},
// 压缩配置
compression: {
// 启用gzip压缩
gzip: true,
// 启用brotli压缩
brotli: true,
// 压缩级别
level: 6,
// 最小压缩文件大小
threshold: 1024,
},
};
// 性能优化工具函数
export class PerformanceOptimizer {
// 预加载关键资源
static preloadCriticalResources() {
if (typeof window === 'undefined') return;
// 预加载关键图片
performanceConfig.prefetch.criticalImages.forEach(src => {
// 检查是否已经存在相同的预加载链接
if (!document.querySelector(`link[rel="preload"][as="image"][href="${src}"]`)) {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'image';
link.href = src;
document.head.appendChild(link);
}
});
// 预加载关键字体
const criticalFonts = [
'/fonts/inter-var.woff2',
];
criticalFonts.forEach(href => {
// 检查是否已经存在相同的预加载链接
if (!document.querySelector(`link[rel="preload"][as="font"][href="${href}"]`)) {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'font';
link.type = 'font/woff2';
link.crossOrigin = 'anonymous';
link.href = href;
document.head.appendChild(link);
}
});
}
// 监控页面性能
static monitorPerformance() {
if (typeof window === 'undefined' || !performanceConfig.monitoring.enabled) return;
// 监控Core Web Vitals (需要安装 web-vitals 包)
try {
// 动态导入web-vitals以避免类型错误
const loadWebVitals = async () => {
try {
const webVitals = await import('web-vitals');
webVitals.onCLS(this.sendToAnalytics);
// onFID已被onINP替代
if ('onINP' in webVitals) {
(webVitals as any).onINP(this.sendToAnalytics);
} else if ('onFID' in webVitals) {
(webVitals as any).onFID(this.sendToAnalytics);
}
webVitals.onLCP(this.sendToAnalytics);
} catch (err) {
console.log('web-vitals not available');
}
};
loadWebVitals();
} catch (error) {
console.log('web-vitals not available');
}
// 监控导航时间
window.addEventListener('load', () => {
setTimeout(() => {
const navigationTiming = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
if (navigationTiming) {
const metrics = {
dns: navigationTiming.domainLookupEnd - navigationTiming.domainLookupStart,
tcp: navigationTiming.connectEnd - navigationTiming.connectStart,
request: navigationTiming.responseStart - navigationTiming.requestStart,
response: navigationTiming.responseEnd - navigationTiming.responseStart,
dom: navigationTiming.domContentLoadedEventEnd - navigationTiming.domContentLoadedEventStart,
load: navigationTiming.loadEventEnd - navigationTiming.loadEventStart,
total: navigationTiming.loadEventEnd - navigationTiming.fetchStart,
};
console.log('页面性能指标:', metrics);
this.sendPerformanceData(metrics);
}
}, 0);
});
}
// 发送性能数据到分析服务
static sendToAnalytics(metric: any) {
if (performanceConfig.monitoring.reportUrl) {
fetch(performanceConfig.monitoring.reportUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(metric),
}).catch(err => console.warn('性能数据上报失败:', err));
}
}
// 发送性能数据
static sendPerformanceData(data: any) {
if (performanceConfig.monitoring.reportUrl) {
fetch(performanceConfig.monitoring.reportUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'navigation', data }),
}).catch(err => console.warn('性能数据上报失败:', err));
}
}
// 优化图片加载
static optimizeImageLoading() {
if (typeof window === 'undefined') return;
// 创建Intersection Observer监听图片懒加载
const imageObserver = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target as HTMLImageElement;
if (img.dataset.src) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
imageObserver.unobserve(img);
}
}
});
},
{
rootMargin: performanceConfig.images.lazyLoadRootMargin,
}
);
// 观察所有延迟加载的图片
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});
// 在页面卸载时断开Observer
const cleanup = () => {
imageObserver.disconnect();
};
// 监听页面卸载事件
window.addEventListener('beforeunload', cleanup);
// 返回清理函数以便手动调用
return cleanup;
}
// 预热缓存
static warmupCache(urls: string[]) {
if (typeof window === 'undefined') return;
urls.forEach(url => {
// 使用fetch预热缓存但不等待响应
fetch(url, {
method: 'HEAD',
mode: 'no-cors'
}).catch(() => {
// 忽略错误,这只是预热缓存
});
});
}
// 延迟加载非关键资源
static deferNonCriticalResources() {
if (typeof window === 'undefined') return;
// 延迟加载第三方脚本
setTimeout(() => {
// 可以在这里加载分析脚本、客服组件等
interface ScriptConfig {
src: string;
async?: boolean;
}
const scripts: ScriptConfig[] = [
// 示例:{ src: 'https://example.com/analytics.js', async: true },
];
scripts.forEach(script => {
// 检查脚本是否已经存在
if (!document.querySelector(`script[src="${script.src}"]`)) {
const scriptElement = document.createElement('script');
scriptElement.src = script.src;
scriptElement.async = script.async || true;
document.head.appendChild(scriptElement);
}
});
}, 3000); // 3秒后加载
}
}
// 页面加载优化Hook
let optimizationInitialized = false;
let imageLoadingCleanup: (() => void) | null = null;
export function usePageLoadOptimization() {
if (typeof window !== 'undefined' && !optimizationInitialized) {
optimizationInitialized = true;
// 预加载关键资源
setTimeout(() => {
PerformanceOptimizer.preloadCriticalResources();
}, performanceConfig.prefetch.prefetchDelay);
// 监控性能
PerformanceOptimizer.monitorPerformance();
// 优化图片加载
imageLoadingCleanup = PerformanceOptimizer.optimizeImageLoading() || null;
// 延迟加载非关键资源
PerformanceOptimizer.deferNonCriticalResources();
// 页面卸载和路由变化时清理
const cleanup = () => {
optimizationInitialized = false;
if (imageLoadingCleanup) {
imageLoadingCleanup();
imageLoadingCleanup = null;
}
// 清理预加载的脚本和链接
try {
const preloadedScripts = document.querySelectorAll('script[data-perf-preload]');
const preloadedLinks = document.querySelectorAll('link[data-perf-preload]');
preloadedScripts.forEach(script => {
if (script.parentNode) {
script.parentNode.removeChild(script);
}
});
preloadedLinks.forEach(link => {
if (link.parentNode) {
link.parentNode.removeChild(link);
}
});
} catch (error) {
console.warn('清理预加载资源时出错:', error);
}
};
// 监听各种页面卸载和路由变化事件
window.addEventListener('beforeunload', cleanup);
// 监听 Next.js 路由变化 (用于 SPA 导航)
if (typeof window !== 'undefined' && window.history) {
const originalPushState = window.history.pushState;
const originalReplaceState = window.history.replaceState;
window.history.pushState = function(...args) {
cleanup();
return originalPushState.apply(this, args);
};
window.history.replaceState = function(...args) {
cleanup();
return originalReplaceState.apply(this, args);
};
window.addEventListener('popstate', cleanup);
}
return cleanup;
}
}