All files / types/constants performance.ts

100% Statements 15/15
100% Branches 8/8
100% Functions 2/2
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258                                                                                                          245x                                                                                                                           94x   86x 15x         71x 65x       6x       8x 3x       5x                                                                                     72x 72x                   245x                                                           245x                                           245x                            
/**
 * Performance constants and optimization settings for Black Trigram
 * 
 * Optimized settings for different device categories to maintain 60fps target
 * Special attention to low-end mobile devices (<380px, older hardware)
 * 
 * @module types/constants/performance
 * @category Performance
 * @korean 성능설정상수
 */
 
/**
 * Performance tier levels based on device capabilities
 * 
 * @category Performance
 * @korean 성능등급
 */
export type PerformanceTier = 'low' | 'medium' | 'high' | 'mobile-high';
 
/**
 * Performance settings for different device tiers
 * Balances visual quality with frame rate targets
 * 
 * @category Performance
 * @korean 성능설정
 */
export interface PerformanceSettings {
  /** Maximum particle count for effects */
  readonly maxParticles: number;
  /** Shadow map resolution (512, 1024, 2048) */
  readonly shadowMapSize: number;
  /** Enable antialiasing */
  readonly antialias: boolean;
  /** Device pixel ratio limit ([min, max] or single value) */
  readonly dpr: number | [number, number];
  /** Enable post-processing effects */
  readonly postProcessing: boolean;
  /** Target frame rate (fps) */
  readonly targetFPS: number;
}
 
/**
 * Performance settings by tier
 * 
 * Low tier: Extra-small mobile (<380px), older devices, budget hardware
 * Medium tier: Standard mobile (380-768px), tablets
 * Mobile-high tier: High-resolution mobile devices (≥768px, 2K+, Motorola Edge, etc.)
 * High tier: Desktop, large displays, modern hardware
 * 
 * @constant
 * @category Performance
 * @korean 성능등급별설정
 */
export const PERFORMANCE_SETTINGS_BY_TIER: Record<PerformanceTier, PerformanceSettings> = {
  low: {
    maxParticles: 20,
    shadowMapSize: 512,
    antialias: false, // Disable AA for performance
    dpr: 1, // Cap at 1x for low-end devices
    postProcessing: false,
    targetFPS: 50, // Realistic target for low-end
  },
  medium: {
    maxParticles: 40,
    shadowMapSize: 1024,
    antialias: true,
    dpr: [1, 2], // Allow up to 2x
    postProcessing: false, // Keep disabled for mobile
    targetFPS: 55,
  },
  'mobile-high': {
    maxParticles: 50, // Between medium and high
    shadowMapSize: 1536, // Between 1024 and 2048
    antialias: true,
    dpr: [1, 3.5], // Support up to 3.5x for Super HD displays (2712x1220)
    postProcessing: false, // Keep disabled for mobile battery life
    targetFPS: 55, // Realistic for high-end mobile
  },
  high: {
    maxParticles: 100,
    shadowMapSize: 2048,
    antialias: true,
    dpr: [1, 2],
    postProcessing: true,
    targetFPS: 60,
  },
} as const;
 
/**
 * Determine performance tier based on device characteristics
 * 
 * Now properly handles high-resolution mobile devices (Motorola Edge 60 Pro, etc.)
 * by checking isMobile flag before using screen width to determine tier.
 * 
 * @param screenWidth - Screen width in pixels
 * @param isMobile - Whether device is mobile (from user-agent detection)
 * @returns Performance tier
 * 
 * @example
 * ```typescript
 * getPerformanceTier(320, true);   // 'low' (extra-small mobile)
 * getPerformanceTier(768, true);   // 'medium' (standard mobile)
 * getPerformanceTier(2712, true);  // 'mobile-high' (Motorola Edge 60 Pro, 2K+ mobile)
 * getPerformanceTier(768, false);  // 'medium' (tablet)
 * getPerformanceTier(1920, false); // 'high' (desktop)
 * ```
 * 
 * @public
 * @korean 성능등급결정
 */
export function getPerformanceTier(
  screenWidth: number,
  isMobile: boolean
): PerformanceTier {
  // Mobile device tiers (user-agent detection takes priority)
  if (isMobile) {
    // Extra-small mobile devices (<380px) are always low tier
    if (screenWidth < 380) {
      return 'low';
    }
    
    // High-resolution mobile devices (≥768px, 2K+ displays like Motorola Edge 60 Pro)
    // Get optimized settings for Super HD mobile displays
    if (screenWidth >= 768) {
      return 'mobile-high';
    }
    
    // Standard mobile devices (380-768px)
    return 'medium';
  }
  
  // Non-mobile devices (tablets and desktop)
  if (screenWidth < 1024) {
    return 'medium'; // Tablet tier
  }
  
  // Desktop and large displays are high tier
  return 'high';
}
 
/**
 * Get performance settings for current device
 * 
 * Properly handles high-resolution mobile devices (2K+, Super HD) by using
 * the isMobile flag from user-agent detection before screen width classification.
 * 
 * This ensures devices like Motorola Edge 60 Pro (2712x1220) get mobile-optimized
 * settings with proper dpr support up to 3.5x for their Super HD displays.
 * 
 * @param screenWidth - Screen width in pixels
 * @param isMobile - Whether device is mobile (from user-agent detection)
 * @returns Performance settings object
 * 
 * @example
 * ```typescript
 * // Standard mobile (iPhone SE)
 * const settings = getPerformanceSettings(375, true);
 * // { maxParticles: 40, shadowMapSize: 1024, dpr: [1, 2], ... }
 * 
 * // High-res mobile (Motorola Edge 60 Pro)
 * const settingsHD = getPerformanceSettings(2712, true);
 * // { maxParticles: 50, shadowMapSize: 1536, dpr: [1, 3.5], ... }
 * 
 * // Desktop
 * const settingsDesktop = getPerformanceSettings(1920, false);
 * // { maxParticles: 100, shadowMapSize: 2048, dpr: [1, 2], ... }
 * 
 * <Canvas
 *   dpr={settings.dpr}
 *   gl={{ antialias: settings.antialias }}
 * />
 * ```
 * 
 * @public
 * @korean 성능설정얻기
 */
export function getPerformanceSettings(
  screenWidth: number,
  isMobile: boolean
): PerformanceSettings {
  const tier = getPerformanceTier(screenWidth, isMobile);
  return PERFORMANCE_SETTINGS_BY_TIER[tier];
}
 
/**
 * Frame time budget in milliseconds for target FPS
 * 
 * @constant
 * @category Performance
 * @korean 프레임시간예산
 */
export const FRAME_TIME_BUDGET = {
  /** 60fps = 16.67ms per frame */
  FPS_60: 16.67,
  /** 55fps = 18.18ms per frame */
  FPS_55: 18.18,
  /** 50fps = 20ms per frame */
  FPS_50: 20,
  /** 30fps = 33.33ms per frame (minimum acceptable) */
  FPS_30: 33.33,
} as const;
 
/**
 * Performance optimization thresholds for mobile
 * 
 * Target values for mobile performance optimization:
 * - FPS: 55+ sustained during combat
 * - Draw calls: <100 per frame
 * - Memory: <200MB heap usage
 * - Particle count: 50% of desktop
 * 
 * Note: shadowMapSize (512) represents the baseline/minimum for mobile.
 * The adaptive quality system can dynamically adjust above this baseline
 * (512 → 1024 → 1536) when performance allows, providing better visuals
 * on higher-end mobile devices while maintaining the 512 minimum for
 * low-end devices.
 * 
 * @constant
 * @category Performance
 * @korean 모바일성능임계값
 */
export const MOBILE_PERFORMANCE_THRESHOLDS = {
  /** Target FPS for mobile devices */
  targetFPS: 55,
  /** Minimum acceptable FPS before quality downgrade */
  minAcceptableFPS: 45,
  /** Maximum draw calls per frame */
  maxDrawCalls: 100,
  /** Maximum memory usage in MB */
  maxMemoryMB: 200,
  /** Particle count reduction factor (0.5 = 50% of desktop) */
  particleReduction: 0.5,
  /** Shadow map size for mobile (baseline - adaptive quality can increase) */
  shadowMapSize: 512,
} as const;
 
/**
 * Desktop performance thresholds
 * 
 * @constant
 * @category Performance
 * @korean 데스크톱성능임계값
 */
export const DESKTOP_PERFORMANCE_THRESHOLDS = {
  /** Target FPS for desktop */
  targetFPS: 60,
  /** Minimum acceptable FPS before quality downgrade */
  minAcceptableFPS: 55,
  /** Maximum draw calls per frame */
  maxDrawCalls: 150,
  /** Maximum memory usage in MB */
  maxMemoryMB: 300,
  /** Particle count reduction factor (1.0 = full desktop quality) */
  particleReduction: 1.0,
  /** Shadow map size for desktop */
  shadowMapSize: 2048,
} as const;