马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
性能监控 和优化是确保 Tailwind CSS 项目高效运行的关键。本节将详细先容怎样实行性能监控 和举行相应的优化。
性能指标监控
Web Vitals 监控
- // utils/vitals.ts
- import { getCLS, getFID, getLCP, getTTFB, getFCP } from 'web-vitals';
- const reportWebVitals = (onPerfEntry: (metric: any) => void) => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- getCLS(onPerfEntry); // Cumulative Layout Shift
- getFID(onPerfEntry); // First Input Delay
- getLCP(onPerfEntry); // Largest Contentful Paint
- getTTFB(onPerfEntry); // Time to First Byte
- getFCP(onPerfEntry); // First Contentful Paint
- }
- };
- export const setupVitalsReporting = () => {
- reportWebVitals((metric) => {
- // 发送到分析服务
- console.log(metric);
-
- // 可以发送到 Google Analytics
- const analytics = (window as any).ga;
- if (analytics) {
- analytics('send', 'event', {
- eventCategory: 'Web Vitals',
- eventAction: metric.name,
- eventValue: Math.round(metric.value),
- eventLabel: metric.id,
- nonInteraction: true,
- });
- }
- });
- };
复制代码 自界说性能监控
- // utils/performance.ts
- export class PerformanceMonitor {
- private marks: Map<string, number> = new Map();
-
- startMark(name: string) {
- this.marks.set(name, performance.now());
- performance.mark(`${name}-start`);
- }
-
- endMark(name: string) {
- const startTime = this.marks.get(name);
- if (startTime) {
- const duration = performance.now() - startTime;
- performance.mark(`${name}-end`);
- performance.measure(name, `${name}-start`, `${name}-end`);
-
- return {
- name,
- duration,
- timestamp: new Date().toISOString()
- };
- }
- }
-
- getMeasurements() {
- return performance.getEntriesByType('measure');
- }
-
- clearMeasurements() {
- performance.clearMarks();
- performance.clearMeasures();
- this.marks.clear();
- }
- }
- // 使用示例
- const monitor = new PerformanceMonitor();
- monitor.startMark('componentRender');
- // 组件渲染
- monitor.endMark('componentRender');
复制代码 样式性能分析
样式加载监控
- // utils/styleMonitor.ts
- export const monitorStyleLoading = () => {
- const observer = new PerformanceObserver((list) => {
- list.getEntries().forEach((entry) => {
- if (entry.entryType === 'resource' && entry.name.endsWith('.css')) {
- console.log('CSS Performance:', {
- name: entry.name,
- duration: entry.duration,
- startTime: entry.startTime,
- transferSize: entry.transferSize
- });
- }
- });
- });
-
- observer.observe({ entryTypes: ['resource'] });
- };
- // 监控样式变化
- const styleChangeObserver = new MutationObserver((mutations) => {
- mutations.forEach((mutation) => {
- if (mutation.attributeName === 'class') {
- console.log('Style Change:', {
- element: mutation.target,
- oldValue: mutation.oldValue,
- newValue: (mutation.target as HTMLElement).className
- });
- }
- });
- });
- // 开始监控
- styleChangeObserver.observe(document.body, {
- attributes: true,
- attributeOldValue: true,
- attributeFilter: ['class'],
- subtree: true
- });
复制代码 样式分析工具
- // utils/styleAnalyzer.ts
- export class StyleAnalyzer {
- analyzeDuplicateClasses() {
- const elements = document.querySelectorAll('*');
- const classCount = new Map<string, number>();
-
- elements.forEach((element) => {
- const classes = element.className.split(' ');
- classes.forEach((className) => {
- classCount.set(
- className,
- (classCount.get(className) || 0) + 1
- );
- });
- });
-
- return Array.from(classCount.entries())
- .filter(([_, count]) => count > 1)
- .sort(([_, a], [__, b]) => b - a);
- }
-
- analyzeUnusedStyles() {
- const styleSheets = Array.from(document.styleSheets);
- const usedSelectors = new Set();
-
- // 收集使用的选择器
- styleSheets.forEach((sheet) => {
- try {
- const rules = Array.from(sheet.cssRules);
- rules.forEach((rule) => {
- if (rule instanceof CSSStyleRule) {
- const elements = document.querySelectorAll(rule.selectorText);
- if (elements.length > 0) {
- usedSelectors.add(rule.selectorText);
- }
- }
- });
- } catch (e) {
- console.warn('Cannot read cssRules from stylesheet', e);
- }
- });
-
- return usedSelectors;
- }
- }
复制代码 优化计谋
样式优化
- // utils/styleOptimizer.ts
- export class StyleOptimizer {
- // 合并相似的类名
- optimizeClassNames(element: HTMLElement) {
- const classes = element.className.split(' ');
- const optimized = new Set<string>();
-
- // 处理边距和内边距
- const spacingClasses = {
- margin: [] as string[],
- padding: [] as string[]
- };
-
- classes.forEach((cls) => {
- if (cls.startsWith('m-')) {
- spacingClasses.margin.push(cls);
- } else if (cls.startsWith('p-')) {
- spacingClasses.padding.push(cls);
- } else {
- optimized.add(cls);
- }
- });
-
- // 合并边距类
- if (spacingClasses.margin.length > 0) {
- optimized.add(this.mergeSpacingClasses(spacingClasses.margin));
- }
-
- // 合并内边距类
- if (spacingClasses.padding.length > 0) {
- optimized.add(this.mergeSpacingClasses(spacingClasses.padding));
- }
-
- return Array.from(optimized).join(' ');
- }
-
- private mergeSpacingClasses(classes: string[]): string {
- // 实现边距类合并逻辑
- return classes[classes.length - 1];
- }
- }
复制代码 运行时优化
- // utils/runtimeOptimizer.ts
- export class RuntimeOptimizer {
- private styleCache = new Map<string, HTMLStyleElement>();
-
- // 缓存动态生成的样式
- cacheStyles(className: string, styles: string) {
- if (!this.styleCache.has(className)) {
- const styleElement = document.createElement('style');
- styleElement.textContent = styles;
- document.head.appendChild(styleElement);
- this.styleCache.set(className, styleElement);
- }
- return className;
- }
-
- // 清理未使用的样式
- cleanupUnusedStyles() {
- const usedClasses = new Set<string>();
-
- // 收集当前使用的类名
- document.querySelectorAll('*').forEach((element) => {
- element.className.split(' ').forEach((cls) => {
- usedClasses.add(cls);
- });
- });
-
- // 清理未使用的缓存样式
- this.styleCache.forEach((style, className) => {
- if (!usedClasses.has(className)) {
- style.remove();
- this.styleCache.delete(className);
- }
- });
- }
- }
复制代码 性能陈诉
陈诉天生器
- // utils/reportGenerator.ts
- export class PerformanceReportGenerator {
- generateReport() {
- const report = {
- timestamp: new Date().toISOString(),
- webVitals: this.collectWebVitals(),
- resourceMetrics: this.collectResourceMetrics(),
- styleMetrics: this.collectStyleMetrics(),
- recommendations: this.generateRecommendations()
- };
-
- return report;
- }
-
- private collectWebVitals() {
- // 收集 Web Vitals 指标
- }
-
- private collectResourceMetrics() {
- // 收集资源加载指标
- return performance.getEntriesByType('resource')
- .filter(entry => entry.name.endsWith('.css'))
- .map(entry => ({
- name: entry.name,
- duration: entry.duration,
- size: entry.transferSize
- }));
- }
-
- private collectStyleMetrics() {
- // 收集样式相关指标
- const styleSheets = document.styleSheets;
- return {
- styleSheetCount: styleSheets.length,
- totalRules: Array.from(styleSheets).reduce((count, sheet) => {
- try {
- return count + sheet.cssRules.length;
- } catch (e) {
- return count;
- }
- }, 0)
- };
- }
-
- private generateRecommendations() {
- // 生成优化建议
- const recommendations = [];
-
- // 检查样式表数量
- if (document.styleSheets.length > 5) {
- recommendations.push({
- type: 'warning',
- message: '考虑合并样式表以减少请求数'
- });
- }
-
- // 检查大型样式规则
- Array.from(document.styleSheets).forEach((sheet) => {
- try {
- if (sheet.cssRules.length > 1000) {
- recommendations.push({
- type: 'warning',
- message: `样式表 ${sheet.href} 包含过多规则`
- });
- }
- } catch (e) {}
- });
-
- return recommendations;
- }
- }
复制代码 监控面板
性能仪表盘
- // components/PerformanceDashboard.tsx
- interface PerformanceMetrics {
- cls: number;
- fid: number;
- lcp: number;
- ttfb: number;
- fcp: number;
- }
- const PerformanceDashboard: React.FC = () => {
- const [metrics, setMetrics] = useState<PerformanceMetrics>();
-
- useEffect(() => {
- getCLS((metric) => {
- setMetrics(prev => ({ ...prev, cls: metric.value }));
- });
-
- getFID((metric) => {
- setMetrics(prev => ({ ...prev, fid: metric.value }));
- });
-
- getLCP((metric) => {
- setMetrics(prev => ({ ...prev, lcp: metric.value }));
- });
-
- getTTFB((metric) => {
- setMetrics(prev => ({ ...prev, ttfb: metric.value }));
- });
-
- getFCP((metric) => {
- setMetrics(prev => ({ ...prev, fcp: metric.value }));
- });
- }, []);
-
- return (
- <div className="grid grid-cols-3 gap-4 p-4">
- {metrics && Object.entries(metrics).map(([key, value]) => (
- <div key={key} className="p-4 bg-white rounded-lg shadow">
- <h3 className="text-lg font-semibold">{key.toUpperCase()}</h3>
- <p className="text-2xl">{value.toFixed(2)}</p>
- </div>
- ))}
- </div>
- );
- };
复制代码 最佳实践
- 监控计谋
- 优化发起
- 定期清算未使用样式
- 归并重复样式类
- 优化样式加载次序
- 开辟发起
- 维护计谋
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|