File size: 5,404 Bytes
4c1e4ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import React, { lazy, Suspense } from 'react';
import { memoize } from './PerformanceOptimizer';
import { intelligentPreloader, resourceHints } from './BundleOptimizer';

// Função para criar componentes lazy com preload otimizado
const createOptimizedLazyComponent = (importFn: () => Promise<{ default: React.ComponentType<any> }>, key: string) => {
  const LazyComponent = lazy(importFn);
  
  // Registrar para preload inteligente
  intelligentPreloader.register(key, importFn);
  
  // Adicionar método de preload manual
  (LazyComponent as any).preload = importFn;
  
  return LazyComponent;
};

// Lazy loading dos componentes pesados para otimizar bundle
export const DualGameViewer = createOptimizedLazyComponent(() => import('../components/DualGameViewer'), 'DualGameViewer');
export const Statistics = createOptimizedLazyComponent(() => import('../components/Statistics'), 'Statistics');
export const ResultsAnalysis = createOptimizedLazyComponent(() => import('../components/ResultsAnalysis'), 'ResultsAnalysis');
export const ProbabilityCalculator = createOptimizedLazyComponent(() => import('../components/ProbabilityCalculator'), 'ProbabilityCalculator');
export const EnhancedLotomaniaGrid = createOptimizedLazyComponent(() => import('../components/EnhancedLotomaniaGrid'), 'EnhancedLotomaniaGrid');
export const LotomaniaFeatures = createOptimizedLazyComponent(() => import('../components/LotomaniaFeatures'), 'LotomaniaFeatures');
export const PrizeAnalysis = createOptimizedLazyComponent(() => import('../components/PrizeAnalysis'), 'PrizeAnalysis');
export const GameProfitabilityAnalysis = createOptimizedLazyComponent(() => import('../components/GameProfitabilityAnalysis'), 'GameProfitabilityAnalysis');
export const HistoricalTrends = createOptimizedLazyComponent(() => import('../components/HistoricalTrends'), 'HistoricalTrends');
export const SmartNumberGenerator = createOptimizedLazyComponent(() => import('../components/SmartNumberGenerator'), 'SmartNumberGenerator');

// Componente de loading personalizado com otimizações
interface ComponentLoaderProps {
  message?: string;
  size?: 'sm' | 'md' | 'lg';
}

export const ComponentLoader: React.FC<ComponentLoaderProps> = React.memo(({ 
  message = 'Carregando...', 
  size = 'md'
}) => {
  const sizeClasses = {
    sm: 'h-6 w-6',
    md: 'h-12 w-12',
    lg: 'h-16 w-16'
  };

  return (
    <div className="flex items-center justify-center p-8">
      <div className="flex flex-col items-center space-y-4">
        <div className={`animate-spin rounded-full border-b-2 border-blue-600 ${sizeClasses[size]}`}></div>
        <p className="text-gray-600 font-medium">{message}</p>
      </div>
    </div>
  );
});

ComponentLoader.displayName = 'ComponentLoader';

// HOC para adicionar loading automático a componentes lazy
export function withLoadingFallback<P extends object>(
  WrappedComponent: React.ComponentType<P>,
  loadingMessage?: string
): React.FC<P> {
  const WrappedWithSuspense: React.FC<P> = (props: P) => {
    return (
      <Suspense fallback={<ComponentLoader message={loadingMessage} />}>
        <WrappedComponent {...props} />
      </Suspense>
    );
  };
  
  WrappedWithSuspense.displayName = `withLoadingFallback(${WrappedComponent.displayName || WrappedComponent.name})`;
  
  return WrappedWithSuspense;
}

// Preload function para componentes críticos com cache memoizado
export const preloadCriticalComponents = memoize(async (): Promise<void> => {
  try {
    // Configurar resource hints
    resourceHints.setupApiHints();
    
    // Precarregar componentes críticos usando preloader inteligente
    await intelligentPreloader.preloadByPriority([
      'DualGameViewer',
      'EnhancedLotomaniaGrid',
      'Statistics'
    ]);
    
    console.log('✅ Componentes críticos pré-carregados');
  } catch (error) {
    console.warn('❌ Falha ao precarregar componentes:', error);
  }
});

// Função para preload condicional baseado na conexão e performance
export const conditionalPreload = (): void => {
  // Verificar performance e conexão antes de precarregar
  const shouldPreload = checkPreloadConditions();
  
  if (shouldPreload) {
    // Precarregar após idle callback se disponível
    if ('requestIdleCallback' in window) {
      (window as any).requestIdleCallback(
        () => preloadCriticalComponents(),
        { timeout: 3000 }
      );
    } else {
      setTimeout(() => preloadCriticalComponents(), 1000);
    }
  }
};

// Verificar condições para preload
function checkPreloadConditions(): boolean {
  // Verificar conexão
  if ('connection' in navigator) {
    const connection = (navigator as any).connection;
    if (connection) {
      // Não precarregar em conexões lentas ou dados limitados
      if (connection.saveData || connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g') {
        return false;
      }
    }
  }
  
  // Verificar memória disponível
  if ('memory' in performance) {
    const memory = (performance as any).memory;
    if (memory && memory.usedJSHeapSize / memory.jsHeapSizeLimit > 0.8) {
      return false; // Não precarregar se usando muita memória
    }
  }
  
  // Verificar CPU (hardware concurrency como proxy)
  if (navigator.hardwareConcurrency && navigator.hardwareConcurrency < 4) {
    return false; // Não precarregar em dispositivos com poucos cores
  }
  
  return true;
}