{"version":3,"file":"critical-path-analyzer.mjs","sources":["../../../../src/lib/performance/advanced/critical-path-analyzer.ts"],"sourcesContent":["/**\n * @file Critical Rendering Path Analyzer\n * @description Analyzes and optimizes the critical rendering path for faster\n * First Contentful Paint (FCP) and Largest Contentful Paint (LCP).\n *\n * Features:\n * - Render blocking resource detection\n * - Critical CSS extraction hints\n * - Resource prioritization\n * - Preload/prefetch recommendations\n * - DOM depth analysis\n * - Above-the-fold optimization\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Resource criticality level\n */\nexport type CriticalityLevel = 'critical' | 'high' | 'medium' | 'low' | 'non-critical';\n\n/**\n * Resource type\n */\nexport type ResourceType = 'script' | 'style' | 'font' | 'image' | 'other';\n\n/**\n * Render blocking resource\n */\nexport interface RenderBlockingResource {\n  url: string;\n  type: ResourceType;\n  size: number;\n  loadTime: number;\n  blockingTime: number;\n  suggestions: string[];\n}\n\n/**\n * Critical resource\n */\nexport interface CriticalResource {\n  url: string;\n  type: ResourceType;\n  criticality: CriticalityLevel;\n  size: number;\n  loadTime: number;\n  inViewport: boolean;\n  aboveTheFold: boolean;\n  recommendations: ResourceRecommendation[];\n}\n\n/**\n * Resource recommendation\n */\nexport interface ResourceRecommendation {\n  action: 'preload' | 'prefetch' | 'defer' | 'async' | 'inline' | 'lazy' | 'remove';\n  reason: string;\n  priority: 'high' | 'medium' | 'low';\n  estimatedImpact: number; // ms saved\n}\n\n/**\n * DOM analysis result\n */\nexport interface DOMAnalysis {\n  totalNodes: number;\n  maxDepth: number;\n  widestLevel: number;\n  widestLevelNodeCount: number;\n  aboveTheFoldNodes: number;\n  recommendations: string[];\n}\n\n/**\n * Critical path analysis result\n */\nexport interface CriticalPathAnalysis {\n  renderBlockingResources: RenderBlockingResource[];\n  criticalResources: CriticalResource[];\n  domAnalysis: DOMAnalysis;\n  estimatedFCP: number;\n  estimatedLCP: number;\n  optimizations: CriticalPathOptimization[];\n  score: number; // 0-100\n  timestamp: number;\n}\n\n/**\n * Critical path optimization\n */\nexport interface CriticalPathOptimization {\n  type: string;\n  description: string;\n  impact: 'high' | 'medium' | 'low';\n  estimatedSavings: number; // ms\n  implementation: string;\n}\n\n/**\n * Analyzer configuration\n */\nexport interface CriticalPathAnalyzerConfig {\n  /** Enable analysis */\n  enabled: boolean;\n  /** Viewport height for above-the-fold detection */\n  viewportHeight: number;\n  /** Consider render-blocking if blocks for more than this (ms) */\n  blockingThreshold: number;\n  /** Enable DOM analysis */\n  analyzeDom: boolean;\n  /** Enable resource analysis */\n  analyzeResources: boolean;\n  /** Debug mode */\n  debug: boolean;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_CONFIG: CriticalPathAnalyzerConfig = {\n  enabled: true,\n  viewportHeight: typeof window !== 'undefined' ? window.innerHeight : 800,\n  blockingThreshold: 50,\n  analyzeDom: true,\n  analyzeResources: true,\n  debug: false,\n};\n\n// Resource priorities\n// // const _RESOURCE_PRIORITY: Record<ResourceType, CriticalityLevel> = {\n//   style: 'critical',\n//   font: 'high',\n//   script: 'medium',\n//   image: 'medium',\n//   other: 'low',\n// };\n\n// ============================================================================\n// Critical Path Analyzer\n// ============================================================================\n\n/**\n * Analyzes critical rendering path\n */\nexport class CriticalPathAnalyzer {\n  private config: CriticalPathAnalyzerConfig;\n\n  constructor(config: Partial<CriticalPathAnalyzerConfig> = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n  }\n\n  /**\n   * Run full critical path analysis\n   */\n  analyze(): CriticalPathAnalysis {\n    const renderBlockingResources = this.config.analyzeResources\n      ? this.findRenderBlockingResources()\n      : [];\n\n    const criticalResources = this.config.analyzeResources ? this.analyzeCriticalResources() : [];\n\n    const domAnalysis = this.config.analyzeDom ? this.analyzeDOM() : this.getEmptyDOMAnalysis();\n\n    const optimizations = this.generateOptimizations(\n      renderBlockingResources,\n      criticalResources,\n      domAnalysis\n    );\n\n    const score = this.calculateScore(renderBlockingResources, criticalResources, domAnalysis);\n\n    return {\n      renderBlockingResources,\n      criticalResources,\n      domAnalysis,\n      estimatedFCP: this.estimateFCP(renderBlockingResources),\n      estimatedLCP: this.estimateLCP(criticalResources),\n      optimizations,\n      score,\n      timestamp: Date.now(),\n    };\n  }\n\n  /**\n   * Find render-blocking resources\n   */\n  findRenderBlockingResources(): RenderBlockingResource[] {\n    if (typeof document === 'undefined') {\n      return [];\n    }\n\n    const blocking: RenderBlockingResource[] = [];\n\n    // Find blocking stylesheets\n    const stylesheets = document.querySelectorAll<HTMLLinkElement>(\n      'link[rel=\"stylesheet\"]:not([media=\"print\"]):not([disabled])'\n    );\n\n    stylesheets.forEach((link) => {\n      if (!link.href) return;\n\n      const timing = this.getResourceTiming(link.href);\n      if (timing && timing.duration > this.config.blockingThreshold) {\n        blocking.push({\n          url: link.href,\n          type: 'style',\n          size: timing.decodedBodySize,\n          loadTime: timing.duration,\n          blockingTime: timing.duration,\n          suggestions: this.getStylesheetSuggestions(link),\n        });\n      }\n    });\n\n    // Find blocking scripts\n    const scripts = document.querySelectorAll<HTMLScriptElement>(\n      'script[src]:not([async]):not([defer]):not([type=\"module\"])'\n    );\n\n    scripts.forEach((script) => {\n      if (!script.src) return;\n\n      const timing = this.getResourceTiming(script.src);\n      if (timing && timing.duration > this.config.blockingThreshold) {\n        blocking.push({\n          url: script.src,\n          type: 'script',\n          size: timing.decodedBodySize,\n          loadTime: timing.duration,\n          blockingTime: timing.duration,\n          suggestions: this.getScriptSuggestions(script),\n        });\n      }\n    });\n\n    return blocking.sort((a, b) => b.blockingTime - a.blockingTime);\n  }\n\n  /**\n   * Analyze critical resources\n   */\n  analyzeCriticalResources(): CriticalResource[] {\n    if (typeof document === 'undefined') {\n      return [];\n    }\n\n    const resources: CriticalResource[] = [];\n\n    // Analyze images\n    const images = document.querySelectorAll<HTMLImageElement>('img');\n    images.forEach((img) => {\n      if (!img.src) return;\n\n      const inViewport = this.isInViewport(img);\n      const timing = this.getResourceTiming(img.src);\n\n      resources.push({\n        url: img.src,\n        type: 'image',\n        criticality: inViewport ? 'high' : 'low',\n        size: timing?.decodedBodySize ?? 0,\n        loadTime: timing?.duration ?? 0,\n        inViewport,\n        aboveTheFold: inViewport,\n        recommendations: this.getImageRecommendations(img, inViewport),\n      });\n    });\n\n    // Analyze fonts\n    const fonts = document.querySelectorAll<HTMLLinkElement>(\n      'link[rel=\"preload\"][as=\"font\"], link[href*=\".woff\"], link[href*=\".woff2\"]'\n    );\n    fonts.forEach((font) => {\n      if (!font.href) return;\n\n      const timing = this.getResourceTiming(font.href);\n      resources.push({\n        url: font.href,\n        type: 'font',\n        criticality: 'high',\n        size: timing?.decodedBodySize ?? 0,\n        loadTime: timing?.duration ?? 0,\n        inViewport: true,\n        aboveTheFold: true,\n        recommendations: this.getFontRecommendations(font),\n      });\n    });\n\n    return resources;\n  }\n\n  /**\n   * Analyze DOM structure\n   */\n  analyzeDOM(): DOMAnalysis {\n    if (typeof document === 'undefined') {\n      return this.getEmptyDOMAnalysis();\n    }\n\n    const { body } = document;\n    if (body == null) {\n      return this.getEmptyDOMAnalysis();\n    }\n\n    const walker = document.createTreeWalker(body, NodeFilter.SHOW_ELEMENT);\n    let totalNodes = 0;\n    let maxDepth = 0;\n    const levelCounts = new Map<number, number>();\n    let aboveTheFoldNodes = 0;\n\n    const countDepth = (node: Node, depth: number): void => {\n      totalNodes++;\n      maxDepth = Math.max(maxDepth, depth);\n\n      const currentCount = levelCounts.get(depth) ?? 0;\n      levelCounts.set(depth, currentCount + 1);\n\n      if (node instanceof Element && this.isInViewport(node)) {\n        aboveTheFoldNodes++;\n      }\n    };\n\n    let depth = 0;\n    let node: Node | null = walker.currentNode;\n    const nodeDepths = new Map<Node, number>();\n\n    while (node) {\n      const parentDepth = node.parentNode ? (nodeDepths.get(node.parentNode) ?? 0) : 0;\n      depth = parentDepth + 1;\n      nodeDepths.set(node, depth);\n\n      countDepth(node, depth);\n      node = walker.nextNode();\n    }\n\n    // Find widest level\n    let widestLevel = 0;\n    let widestLevelNodeCount = 0;\n    for (const [level, count] of levelCounts.entries()) {\n      if (count > widestLevelNodeCount) {\n        widestLevel = level;\n        widestLevelNodeCount = count;\n      }\n    }\n\n    const recommendations: string[] = [];\n\n    if (totalNodes > 1500) {\n      recommendations.push(\n        `DOM has ${totalNodes} nodes. Consider reducing to under 1500 for better performance.`\n      );\n    }\n\n    if (maxDepth > 32) {\n      recommendations.push(`DOM depth is ${maxDepth}. Consider flattening to under 32 levels.`);\n    }\n\n    if (widestLevelNodeCount > 60) {\n      recommendations.push(\n        `Level ${widestLevel} has ${widestLevelNodeCount} siblings. Consider reducing sibling count.`\n      );\n    }\n\n    return {\n      totalNodes,\n      maxDepth,\n      widestLevel,\n      widestLevelNodeCount,\n      aboveTheFoldNodes,\n      recommendations,\n    };\n  }\n\n  /**\n   * Get preload recommendations\n   */\n  getPreloadRecommendations(): ResourceRecommendation[] {\n    const criticalResources = this.analyzeCriticalResources();\n    const recommendations: ResourceRecommendation[] = [];\n\n    for (const resource of criticalResources) {\n      if (\n        resource.criticality === 'critical' ||\n        (resource.criticality === 'high' && resource.aboveTheFold)\n      ) {\n        // Check if not already preloaded\n        const isPreloaded = document.querySelector(`link[rel=\"preload\"][href=\"${resource.url}\"]`);\n\n        if (!isPreloaded) {\n          recommendations.push({\n            action: 'preload',\n            reason: `Critical ${resource.type} resource above the fold`,\n            priority: 'high',\n            estimatedImpact: Math.min(resource.loadTime * 0.5, 500),\n          });\n        }\n      }\n    }\n\n    return recommendations;\n  }\n\n  // ============================================================================\n  // Private Methods\n  // ============================================================================\n\n  private getResourceTiming(url: string): PerformanceResourceTiming | undefined {\n    try {\n      const entries = performance.getEntriesByType('resource');\n      return entries.find((entry) => entry.name.includes(url));\n    } catch {\n      return undefined;\n    }\n  }\n\n  private isInViewport(element: Element): boolean {\n    const rect = element.getBoundingClientRect();\n    return (\n      rect.top < this.config.viewportHeight &&\n      rect.bottom > 0 &&\n      rect.left < window.innerWidth &&\n      rect.right > 0\n    );\n  }\n\n  private getStylesheetSuggestions(link: HTMLLinkElement): string[] {\n    const suggestions: string[] = [];\n\n    if (!link.media || link.media === 'all') {\n      suggestions.push('Add media query if stylesheet is conditional');\n    }\n\n    suggestions.push('Consider inlining critical CSS');\n    suggestions.push('Use rel=\"preload\" for critical stylesheets');\n\n    return suggestions;\n  }\n\n  private getScriptSuggestions(script: HTMLScriptElement): string[] {\n    const suggestions: string[] = [];\n\n    if (!script.async && !script.defer) {\n      suggestions.push('Add async or defer attribute');\n    }\n\n    suggestions.push('Consider code splitting for large scripts');\n    suggestions.push('Move script to end of body if possible');\n\n    return suggestions;\n  }\n\n  private getImageRecommendations(\n    img: HTMLImageElement,\n    inViewport: boolean\n  ): ResourceRecommendation[] {\n    const recommendations: ResourceRecommendation[] = [];\n\n    if (!inViewport && img.loading !== 'lazy') {\n      recommendations.push({\n        action: 'lazy',\n        reason: 'Image is below the fold',\n        priority: 'medium',\n        estimatedImpact: 100,\n      });\n    }\n\n    if (inViewport) {\n      // Check for preload\n      const isPreloaded = document.querySelector(`link[rel=\"preload\"][href=\"${img.src}\"]`);\n      if (!isPreloaded) {\n        recommendations.push({\n          action: 'preload',\n          reason: 'Above-the-fold image should be preloaded',\n          priority: 'high',\n          estimatedImpact: 200,\n        });\n      }\n    }\n\n    // Check for dimensions\n    if (!img.width || !img.height) {\n      recommendations.push({\n        action: 'inline',\n        reason: 'Add width and height attributes to prevent CLS',\n        priority: 'high',\n        estimatedImpact: 50,\n      });\n    }\n\n    return recommendations;\n  }\n\n  private getFontRecommendations(font: HTMLLinkElement): ResourceRecommendation[] {\n    const recommendations: ResourceRecommendation[] = [];\n\n    // Check for font-display\n    recommendations.push({\n      action: 'inline',\n      reason: 'Use font-display: swap for better FOUT handling',\n      priority: 'medium',\n      estimatedImpact: 100,\n    });\n\n    // Check for preconnect\n    const fontUrl = new URL(font.href);\n    const hasPreconnect = document.querySelector(\n      `link[rel=\"preconnect\"][href*=\"${fontUrl.hostname}\"]`\n    );\n    if (!hasPreconnect) {\n      recommendations.push({\n        action: 'preload',\n        reason: 'Add preconnect for font origin',\n        priority: 'high',\n        estimatedImpact: 150,\n      });\n    }\n\n    return recommendations;\n  }\n\n  private generateOptimizations(\n    blocking: RenderBlockingResource[],\n    critical: CriticalResource[],\n    dom: DOMAnalysis\n  ): CriticalPathOptimization[] {\n    const optimizations: CriticalPathOptimization[] = [];\n\n    // Render-blocking optimizations\n    if (blocking.length > 0) {\n      const totalBlockingTime = blocking.reduce((sum, r) => sum + r.blockingTime, 0);\n      let impact: 'high' | 'medium' | 'low' = 'low';\n      if (totalBlockingTime > 500) {\n        impact = 'high';\n      } else if (totalBlockingTime > 200) {\n        impact = 'medium';\n      }\n      optimizations.push({\n        type: 'render-blocking',\n        description: `${blocking.length} render-blocking resources found`,\n        impact,\n        estimatedSavings: Math.min(totalBlockingTime * 0.5, 1000),\n        implementation:\n          'Defer non-critical scripts, inline critical CSS, use preload for critical resources',\n      });\n    }\n\n    // LCP element optimization\n    const lcpImages = critical.filter((r) => r.type === 'image' && r.aboveTheFold);\n    if (lcpImages.length > 0) {\n      const slowestImage = lcpImages.reduce((a, b) => (a.loadTime > b.loadTime ? a : b));\n      if (slowestImage.loadTime > 500) {\n        optimizations.push({\n          type: 'lcp-optimization',\n          description: 'LCP image can be optimized',\n          impact: 'high',\n          estimatedSavings: slowestImage.loadTime * 0.3,\n          implementation:\n            'Preload LCP image, use modern image formats (WebP/AVIF), optimize image size',\n        });\n      }\n    }\n\n    // DOM optimizations\n    if (dom.totalNodes > 1500) {\n      optimizations.push({\n        type: 'dom-size',\n        description: `Large DOM size (${dom.totalNodes} nodes)`,\n        impact: dom.totalNodes > 3000 ? 'high' : 'medium',\n        estimatedSavings: Math.min((dom.totalNodes - 1500) * 0.1, 500),\n        implementation:\n          'Virtualize long lists, lazy render below-the-fold content, remove unused elements',\n      });\n    }\n\n    return optimizations.sort((a, b) => {\n      const impactOrder = { high: 0, medium: 1, low: 2 };\n      return impactOrder[a.impact] - impactOrder[b.impact];\n    });\n  }\n\n  private calculateScore(\n    blocking: RenderBlockingResource[],\n    critical: CriticalResource[],\n    dom: DOMAnalysis\n  ): number {\n    let score = 100;\n\n    // Deduct for render-blocking resources\n    score -= Math.min(blocking.length * 5, 30);\n\n    // Deduct for slow critical resources\n    const slowCritical = critical.filter((r) => r.loadTime > 500);\n    score -= Math.min(slowCritical.length * 5, 20);\n\n    // Deduct for DOM issues\n    if (dom.totalNodes > 1500) {\n      score -= Math.min((dom.totalNodes - 1500) / 100, 20);\n    }\n    if (dom.maxDepth > 32) {\n      score -= Math.min((dom.maxDepth - 32) * 2, 15);\n    }\n\n    // Deduct for missing optimizations\n    const unoptimizedImages = critical.filter(\n      (r) =>\n        r.type === 'image' &&\n        r.aboveTheFold &&\n        r.recommendations.some((rec) => rec.action === 'preload')\n    );\n    score -= Math.min(unoptimizedImages.length * 3, 15);\n\n    return Math.max(0, Math.round(score));\n  }\n\n  private estimateFCP(blocking: RenderBlockingResource[]): number {\n    // Base FCP estimate + blocking time\n    const baseFCP = 500; // Base server + parse time\n    const blockingTime = blocking\n      .filter((r) => r.type === 'style')\n      .reduce((sum, r) => Math.max(sum, r.blockingTime), 0);\n    return baseFCP + blockingTime;\n  }\n\n  private estimateLCP(critical: CriticalResource[]): number {\n    const lcpCandidates = critical.filter((r) => r.type === 'image' && r.aboveTheFold);\n    if (lcpCandidates.length === 0) {\n      return 1000; // Estimate for text-based LCP\n    }\n\n    const slowestImage = lcpCandidates.reduce((a, b) => (a.loadTime > b.loadTime ? a : b));\n    return Math.max(1000, slowestImage.loadTime + 500);\n  }\n\n  private getEmptyDOMAnalysis(): DOMAnalysis {\n    return {\n      totalNodes: 0,\n      maxDepth: 0,\n      widestLevel: 0,\n      widestLevelNodeCount: 0,\n      aboveTheFoldNodes: 0,\n      recommendations: [],\n    };\n  }\n\n  // private log(message: string, ...args: unknown[]): void {\n  //   if (this.config.debug) {\n  //     console.log(`[CriticalPath] ${message}`, ...args);\n  //   }\n  // }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet analyzerInstance: CriticalPathAnalyzer | null = null;\n\n/**\n * Get or create the global critical path analyzer\n */\nexport function getCriticalPathAnalyzer(\n  config?: Partial<CriticalPathAnalyzerConfig>\n): CriticalPathAnalyzer {\n  analyzerInstance ??= new CriticalPathAnalyzer(config);\n  return analyzerInstance;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Generate critical CSS extraction hints\n */\nexport function generateCriticalCSSHints(): string[] {\n  if (typeof document === 'undefined') {\n    return [];\n  }\n\n  const hints: string[] = [];\n  const viewportHeight = window.innerHeight;\n\n  // Find above-the-fold elements\n  const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);\n  const aboveTheFold: Element[] = [];\n\n  let node: Node | null = walker.currentNode;\n  while (node) {\n    if (node instanceof Element) {\n      const rect = node.getBoundingClientRect();\n      if (rect.top < viewportHeight && rect.bottom > 0) {\n        aboveTheFold.push(node);\n      }\n    }\n    node = walker.nextNode();\n  }\n\n  // Generate selector hints\n  const selectors = new Set<string>();\n  aboveTheFold.forEach((el) => {\n    // Add tag name\n    selectors.add(el.tagName.toLowerCase());\n\n    // Add classes\n    el.classList.forEach((cls) => selectors.add(`.${cls}`));\n\n    // Add ID if present\n    if (el.id) {\n      selectors.add(`#${el.id}`);\n    }\n  });\n\n  hints.push(\n    `Consider extracting CSS for these selectors: ${Array.from(selectors).slice(0, 20).join(', ')}`\n  );\n  hints.push(`${aboveTheFold.length} elements are above the fold`);\n\n  return hints;\n}\n\n/**\n * Check if a resource should be preloaded\n */\nexport function shouldPreload(resource: CriticalResource, currentPreloads: string[]): boolean {\n  // Already preloaded\n  if (currentPreloads.includes(resource.url)) {\n    return false;\n  }\n\n  // Critical above-the-fold resources should be preloaded\n  if (resource.aboveTheFold && resource.criticality !== 'non-critical') {\n    return true;\n  }\n\n  // Large load times for high priority resources\n  return resource.criticality === 'high' && resource.loadTime > 300;\n}\n"],"names":["DEFAULT_CONFIG","CriticalPathAnalyzer","config","renderBlockingResources","criticalResources","domAnalysis","optimizations","score","blocking","link","timing","script","a","b","resources","img","inViewport","font","body","walker","totalNodes","maxDepth","levelCounts","aboveTheFoldNodes","countDepth","node","depth","currentCount","nodeDepths","widestLevel","widestLevelNodeCount","level","count","recommendations","resource","url","entry","element","rect","suggestions","fontUrl","critical","dom","totalBlockingTime","sum","r","impact","lcpImages","slowestImage","impactOrder","slowCritical","unoptimizedImages","rec","lcpCandidates","analyzerInstance","getCriticalPathAnalyzer","generateCriticalCSSHints","hints","viewportHeight","aboveTheFold","selectors","el","cls","shouldPreload","currentPreloads"],"mappings":"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"}