JavaScript系列(54)--性能优化技术详解

时间:2025-02-03 10:20:50

JavaScript性能优化技术详解 ⚡

今天,让我们继续深入研究JavaScript的性能优化技术。掌握这些技术对于构建高性能的JavaScript应用至关重要。

性能优化基础概念 ????

???? 小知识:JavaScript性能优化涉及多个方面,包括代码执行效率、内存使用、DOM操作、网络请求等。通过合理的优化策略,可以显著提升应用的响应速度和用户体验。

性能分析工具实现 ????

// 1. 性能计时器
class PerformanceTimer {
    constructor() {
        this.marks = new Map();
        this.measures = new Map();
    }
    
    mark(name) {
        this.marks.set(name, performance.now());
    }
    
    measure(name, startMark, endMark) {
        const startTime = this.marks.get(startMark);
        const endTime = this.marks.get(endMark);
        
        if (startTime && endTime) {
            const duration = endTime - startTime;
            this.measures.set(name, duration);
            return duration;
        }
        
        return null;
    }
    
    getMeasure(name) {
        return this.measures.get(name);
    }
    
    clearMarks() {
        this.marks.clear();
    }
    
    clearMeasures() {
        this.measures.clear();
    }
}

// 2. 代码性能分析器
class CodeProfiler {
    constructor() {
        this.profiles = new Map();
    }
    
    startProfile(name) {
        const startTime = performance.now();
        const startMemory = performance.memory?.usedJSHeapSize;
        
        this.profiles.set(name, {
            startTime,
            startMemory,
            calls: 0,
            totalTime: 0,
            maxTime: 0
        });
    }
    
    endProfile(name) {
        const profile = this.profiles.get(name);
        if (!profile) return;
        
        const endTime = performance.now();
        const endMemory = performance.memory?.usedJSHeapSize;
        
        const duration = endTime - profile.startTime;
        const memoryDiff = endMemory - profile.startMemory;
        
        profile.calls++;
        profile.totalTime += duration;
        profile.maxTime = Math.max(profile.maxTime, duration);
        profile.lastMemoryImpact = memoryDiff;
    }
    
    getProfile(name) {
        const profile = this.profiles.get(name);
        if (!profile) return null;
        
        return {
            ...profile,
            averageTime: profile.totalTime / profile.calls
        };
    }
    
    getAllProfiles() {
        const results = {};
        for (const [name, profile] of this.profiles) {
            results[name] = this.getProfile(name);
        }
        return results;
    }
}

// 3. 函数执行时间分析装饰器
function profileExecution(target, propertyKey, descriptor) {
    const originalMethod = descriptor.value;
    const profiler = new CodeProfiler();
    
    descriptor.value = function(...args) {
        profiler.startProfile(propertyKey);
        const result = originalMethod.apply(this, args);
        profiler.endProfile(propertyKey);
        
        console.log(`Function ${propertyKey} profile:`, profiler.getProfile(propertyKey));
        return result;
    };
    
    return descriptor;
}

代码优化技术 ????

// 1. 循环优化
class LoopOptimizer {
    // 优化数组遍历
    static optimizedForEach(array, callback) {
        const length = array.length;
        for (let i = 0; i < length; i++) {
            callback(array[i], i);
        }
    }
    
    // 分块处理大数组
    static *chunkedProcess(array, chunkSize = 1000) {
        const length = array.length;
        for (let i = 0; i < length; i += chunkSize) {
            yield array.slice(i, Math.min(i + chunkSize, length));
        }
    }
    
    // 使用Web Worker处理耗时操作
    static createWorkerProcess(workerFunction) {
        const blob = new Blob([`(${workerFunction.toString()})()`], 
            { type: 'application/javascript' });
        return new Worker(URL.createObjectURL(blob));
    }
}

// 2. 函数优化
class FunctionOptimizer {
    constructor() {
        this.cache = new Map();
    }
    
    // 函数记忆化
    memoize(fn) {
        return (...args) => {
            const key = JSON.stringify(args);
            if (this.cache.has(key)) {
                return this.cache.get(key);
            }
            
            const result = fn.apply(this, args);
            this.cache.set(key, result);
            return result;
        };
    }
    
    // 函数防抖
    debounce(fn, delay) {
        let timeoutId;
        return (...args) => {
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => fn.apply(this, args), delay);
        };
    }
    
    // 函数节流
    throttle(fn, limit) {
        let inThrottle;
        return (...args) => {
            if (!inThrottle) {
                fn.apply(this, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    }
}

// 3. DOM优化
class DOMOptimizer {
    constructor() {
        this.mutationObserver = null;
        this.virtualDOM = new Map();
    }
    
    // 批量DOM更新
    batchUpdate(updates) {
        const fragment = document.createDocumentFragment();
        
        updates.forEach(update => {
            const element = this.createElement(update);
            fragment.appendChild(element);
        });
        
        document.body.appendChild(fragment);
    }
    
    // 虚拟DOM实现
    createElement(vnode) {
        if (typeof vnode === 'string') {
            return document.createTextNode(vnode);
        }
        
        const element = document.createElement(vnode.tag);
        
        for (const [key, value] of Object.entries(vnode.props || {})) {
            element.setAttribute(key, value);
        }
        
        (vnode.children || []).forEach(child => {
            element.appendChild(this.createElement(child));
        });
        
        return element;
    }
    
    // DOM变更监控
    observeChanges(target, callback) {
        this.mutationObserver = new MutationObserver(callback);
        this.mutationObserver.observe(target, {
            childList: true,
            subtree: true,
            attributes: true
        });
    }
}

高级优化模式 ????

// 1. 虚拟滚动实现
class VirtualScroller {
    constructor(container, items, itemHeight) {
        this.container = container;
        this.items = items;
        this.itemHeight = itemHeight;
        this.visibleItems = new Map();
        this.scrollTop = 0;
        
        this.container.style.overflow = 'auto';
        this.container.style.position = 'relative';
        
        this.init();
    }
    
    init() {
        // 设置容器高度
        this.container.style.height = `${this.items.length * this.itemHeight}px`;
        
        // 监听滚动事件
        this.container.addEventListener('scroll', this.onScroll.bind(this));
        
        // 初始渲染
        this.render();
    }
    
    onScroll() {
        this.scrollTop = this.container.scrollTop;
        this.render();
    }
    
    render() {
        const startIndex = Math.floor(this.scrollTop / this.itemHeight);
        const endIndex = Math.min(
            startIndex + Math.ceil(this.container.clientHeight / this.itemHeight),
            this.items.length
        );
        
        // 移除不可见项
        for (const [index, element] of this.visibleItems) {
            if (index < startIndex || index >= endIndex) {
                element.remove();
                this.visibleItems.delete(index);
            }
        }
        
        // 添加可见项
        for (let i = startIndex; i < endIndex; i++) {
            if (!this.visibleItems.has(i)) {
                const element = this.createItem(i);
                this.container.appendChild(element);
                this.visibleItems.set(i, element);
            }
        }
    }
    
    createItem(index) {
        const element = document.createElement('div');
        element.style.position = 'absolute';
        element.style.top = `${index * this.itemHeight}px`;
        element.style.height = `${this.itemHeight}px`;
        element.textContent = this.items[index];
        return element;
    }
}

// 2. 资源预加载器
class ResourcePreloader {
    constructor() {
        this.cache = new Map();
        this.loading = new Set();
    }
    
    preload(resources) {
        resources.forEach(resource => {
            if (!this.cache.has(resource) && !this.loading.has(resource)) {
                this.loading.add(resource);
                
                const promise = this.loadResource(resource)
                    .then(result => {
                        this.cache.set(resource, result);
                        this.loading.delete(resource);
                    })
                    .catch(error => {
                        console.error(`Failed to preload ${resource}:`, error);
                        this.loading.delete(resource);
                    });
                
                return promise;
            }
        });
    }
    
    loadResource(resource) {
        if (resource.endsWith('.js')) {
            return this.loadScript(resource);
        } else if (resource.endsWith('.css')) {
            return this.loadStyle(resource);
        } else if (/\.(png|jpg|gif|svg)$/.test(resource)) {
            return this.loadImage(resource);
        }
        
        return Promise.reject(new Error('Unsupported resource type'));
    }
    
    loadScript(url) {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = url;
            script.onload = () => resolve(script);
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }
    
    loadStyle(url) {
        return new Promise((resolve, reject