aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
287 lines (284 loc) • 8.11 kB
JavaScript
import { detectDevice } from '../../utils/deviceCapabilities.js';
/**
* Performance-optimized CSS properties based on device capabilities
*/
const createPerformanceMixin = (options = {}) => {
const {
mode = 'balanced',
rendering = 'auto',
prefersReducedMotion = false
} = options;
let styles = {};
// Base performance optimizations
switch (mode) {
case 'high':
styles = {
willChange: 'transform, opacity',
backfaceVisibility: 'hidden',
perspective: '1000px',
transformStyle: 'preserve-3d',
contain: 'layout style paint'
};
break;
case 'balanced':
styles = {
willChange: 'auto',
backfaceVisibility: 'visible',
contain: 'layout paint'
};
break;
case 'low':
styles = {
willChange: 'auto',
transform: 'none',
filter: 'none'
// Use createGlassStyle() instead,
// Use createGlassStyle() instead,
};
break;
}
// GPU acceleration optimizations
if (rendering === 'gpu' && mode !== 'low') {
styles.transform = 'translateZ(0)';
styles.isolation = 'isolate';
}
// Reduced motion support
if (prefersReducedMotion) {
styles.animation = 'none';
styles.transition = 'none';
styles.transform = 'none';
}
return styles;
};
/**
* Optimized transition mixin with fallbacks
*/
const createOptimizedTransition = (properties, duration = 200, easing = 'cubic-bezier(0.4, 0, 0.2, 1)', prefersReducedMotion = false) => {
if (prefersReducedMotion) {
return {};
}
return {
transition: properties.map(prop => `${prop} ${duration}ms ${easing}`).join(', '),
transitionProperty: properties.join(', '),
transitionDuration: `${duration}ms`,
transitionTimingFunction: easing
};
};
/**
* Memory-efficient animation mixin
*/
const createMemoryEfficientAnimation = (name, duration = 1000, iterationCount = 1, options = {}) => {
const {
playState = 'running',
fillMode = 'both',
prefersReducedMotion = false
} = options;
if (prefersReducedMotion) {
return {};
}
return {
animation: `${name} ${duration}ms ${iterationCount} ${fillMode}`,
animationPlayState: playState,
animationFillMode: fillMode
};
};
/**
* Lazy loading optimization styles
*/
const createLazyLoadMixin = (isLoaded = false, placeholder) => {
if (isLoaded) {
return {
opacity: 1,
transform: 'none'
};
}
return {
opacity: 0,
transform: 'scale(0.95)',
transition: 'opacity 300ms ease, transform 300ms ease',
backgroundImage: placeholder ? `url(${placeholder})` : undefined,
backgroundSize: 'cover',
backgroundPosition: 'center'
};
};
/**
* Virtualization container styles
*/
const createVirtualizationMixin = (itemHeight, containerHeight, overscan = 3) => ({
height: containerHeight,
overflow: 'auto',
contain: 'strict',
scrollBehavior: 'smooth',
WebkitOverflowScrolling: 'touch' // iOS momentum scrolling
});
/**
* Performance monitoring utilities
*/
class PerformanceMonitor {
constructor() {
this.metrics = new Map();
}
static getInstance() {
if (!PerformanceMonitor.instance) {
PerformanceMonitor.instance = new PerformanceMonitor();
}
return PerformanceMonitor.instance;
}
startMeasure(name) {
if (typeof performance !== 'undefined') {
performance.mark(`${name}-start`);
}
}
endMeasure(name) {
if (typeof performance === 'undefined') return null;
try {
performance.mark(`${name}-end`);
performance.measure(name, `${name}-start`, `${name}-end`);
const measure = performance.getEntriesByName(name, 'measure')[0];
const duration = measure.duration;
// Store metric
if (!this.metrics.has(name)) {
this.metrics.set(name, []);
}
this.metrics.get(name).push(duration);
// Cleanup
performance.clearMarks(`${name}-start`);
performance.clearMarks(`${name}-end`);
performance.clearMeasures(name);
return duration;
} catch (error) {
console.warn(`Performance measurement failed for ${name}:`, error);
return null;
}
}
getAverageMetric(name) {
const metrics = this.metrics.get(name);
if (!metrics || metrics.length === 0) return null;
return metrics.reduce((sum, value) => sum + value, 0) / metrics.length;
}
clearMetrics(name) {
if (name) {
this.metrics.delete(name);
} else {
this.metrics.clear();
}
}
}
/**
* Device capability detection
*/
const detectDeviceCapabilities = () => {
if (typeof window === 'undefined') {
return {
supportsGPU: false,
supportsBackdropFilter: false,
prefersReducedMotion: false,
connectionSpeed: 'unknown',
memoryInfo: null
};
}
const device = detectDevice();
return {
supportsGPU: device.capabilities.webgl,
supportsBackdropFilter: CSS.supports('backdrop-filter', 'blur(1px)') || CSS.supports('-webkit-backdrop-filter', 'blur(1px)'),
prefersReducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)').matches,
connectionSpeed: navigator.connection?.effectiveType || 'unknown',
memoryInfo: performance.memory || null,
devicePixelRatio: window.devicePixelRatio || 1
};
};
/**
* Adaptive performance configuration
*/
const getAdaptivePerformanceConfig = () => {
const capabilities = detectDeviceCapabilities();
// Low-end device detection
const isLowEnd = !capabilities.supportsGPU || capabilities.connectionSpeed === 'slow-2g' || capabilities.connectionSpeed === '2g' || capabilities.memoryInfo && capabilities.memoryInfo.jsHeapSizeLimit < 1000000000 // < 1GB
;
// High-end device detection
const isHighEnd = capabilities.supportsGPU && capabilities.supportsBackdropFilter && (capabilities.connectionSpeed === '4g' || capabilities.connectionSpeed === '5g') && (capabilities.devicePixelRatio ?? 1) >= 2;
if (isLowEnd) {
return {
mode: 'low',
rendering: 'cpu',
prefersReducedMotion: true,
enableLazyLoading: true,
enableVirtualization: true
};
}
if (isHighEnd) {
return {
mode: 'high',
rendering: 'gpu',
prefersReducedMotion: capabilities.prefersReducedMotion,
enableLazyLoading: false,
enableVirtualization: false
};
}
return {
mode: 'balanced',
rendering: 'auto',
prefersReducedMotion: capabilities.prefersReducedMotion,
enableLazyLoading: true,
enableVirtualization: true
};
};
/**
* Debounced resize observer for performance
*/
const createDebouncedResizeObserver = (callback, delay = 100) => {
if (typeof ResizeObserver === 'undefined') return null;
let timeoutId;
return new ResizeObserver(entries => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => callback(entries), delay);
});
};
/**
* Memory leak prevention utilities
*/
const createCleanupManager = () => {
const cleanupFunctions = [];
return {
add: cleanup => {
cleanupFunctions.push(cleanup);
},
cleanup: () => {
cleanupFunctions.forEach(fn => {
try {
fn();
} catch (error) {
console.warn('Cleanup function failed:', error);
}
});
cleanupFunctions.length = 0;
}
};
};
/**
* Optimized scroll handling
*/
const createOptimizedScrollHandler = (handler, options = {}) => {
const {
throttle = 16,
passive = true
} = options; // 60fps by default
let ticking = false;
const throttledHandler = event => {
if (!ticking) {
requestAnimationFrame(() => {
handler(event);
ticking = false;
});
ticking = true;
}
};
return {
handler: throttledHandler,
options: {
passive
}
};
};
export { PerformanceMonitor, createCleanupManager, createDebouncedResizeObserver, createLazyLoadMixin, createMemoryEfficientAnimation, createOptimizedScrollHandler, createOptimizedTransition, createPerformanceMixin, createVirtualizationMixin, detectDeviceCapabilities, getAdaptivePerformanceConfig };
//# sourceMappingURL=performanceMixins.js.map