98 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			98 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | export function debounce<T extends (...args: any[]) => any>( | ||
|  |   func: T, | ||
|  |   wait: number | ||
|  | ): (...args: Parameters<T>) => void { | ||
|  |   let timeout: number | undefined; | ||
|  | 
 | ||
|  |   return function executedFunction(...args: Parameters<T>) { | ||
|  |     const later = () => { | ||
|  |       clearTimeout(timeout); | ||
|  |       func(...args); | ||
|  |     }; | ||
|  | 
 | ||
|  |     clearTimeout(timeout); | ||
|  |     timeout = window.setTimeout(later, wait); | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | export function throttle<T extends (...args: any[]) => any>( | ||
|  |   func: T, | ||
|  |   limit: number | ||
|  | ): (...args: Parameters<T>) => void { | ||
|  |   let inThrottle: boolean; | ||
|  | 
 | ||
|  |   return function executedFunction(...args: Parameters<T>) { | ||
|  |     if (!inThrottle) { | ||
|  |       func.apply(this, args); | ||
|  |       inThrottle = true; | ||
|  |       setTimeout(() => inThrottle = false, limit); | ||
|  |     } | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | export function formatFileSize(bytes: number): string { | ||
|  |   if (bytes === 0) return '0 Bytes'; | ||
|  | 
 | ||
|  |   const k = 1024; | ||
|  |   const sizes = ['Bytes', 'KB', 'MB', 'GB']; | ||
|  |   const i = Math.floor(Math.log(bytes) / Math.log(k)); | ||
|  | 
 | ||
|  |   return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]; | ||
|  | } | ||
|  | 
 | ||
|  | export function isInViewport(element: Element, margin = 0): boolean { | ||
|  |   const rect = element.getBoundingClientRect(); | ||
|  |   return ( | ||
|  |     rect.top >= -margin && | ||
|  |     rect.left >= -margin && | ||
|  |     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + margin && | ||
|  |     rect.right <= (window.innerWidth || document.documentElement.clientWidth) + margin | ||
|  |   ); | ||
|  | } | ||
|  | 
 | ||
|  | export class PerformanceMonitor { | ||
|  |   private static marks = new Map<string, number>(); | ||
|  |   private static measures: Array<{ name: string; duration: number }> = []; | ||
|  | 
 | ||
|  |   public static mark(name: string) { | ||
|  |     this.marks.set(name, performance.now()); | ||
|  |   } | ||
|  | 
 | ||
|  |   public static measure(name: string, startMark: string) { | ||
|  |     const start = this.marks.get(startMark); | ||
|  |     if (start) { | ||
|  |       const duration = performance.now() - start; | ||
|  |       this.measures.push({ name, duration }); | ||
|  |       this.marks.delete(startMark); | ||
|  |       return duration; | ||
|  |     } | ||
|  |     return 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   public static getReport() { | ||
|  |     const report = { | ||
|  |       measures: [...this.measures], | ||
|  |       averages: {} as Record<string, number>, | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Calculate averages for repeated measures
 | ||
|  |     const grouped = new Map<string, number[]>(); | ||
|  |     for (const measure of this.measures) { | ||
|  |       if (!grouped.has(measure.name)) { | ||
|  |         grouped.set(measure.name, []); | ||
|  |       } | ||
|  |       grouped.get(measure.name)!.push(measure.duration); | ||
|  |     } | ||
|  | 
 | ||
|  |     for (const [name, durations] of grouped) { | ||
|  |       report.averages[name] = durations.reduce((a, b) => a + b, 0) / durations.length; | ||
|  |     } | ||
|  | 
 | ||
|  |     return report; | ||
|  |   } | ||
|  | 
 | ||
|  |   public static clear() { | ||
|  |     this.marks.clear(); | ||
|  |     this.measures = []; | ||
|  |   } | ||
|  | } |