当前位置: 首页 > article >正文

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

JavaScript性能优化技术详解 ⚡

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

性能优化基础 🌟

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

代码执行优化 📊

// 1. 循环优化
function loopOptimization() {
    const arr = new Array(1000000).fill(1);
    
    // 不好的做法
    for (let i = 0; i < arr.length; i++) {
        // 每次都要获取数组长度
    }
    
    // 好的做法
    for (let i = 0, len = arr.length; i < len; i++) {
        // 缓存数组长度
    }
    
    // 更好的做法
    arr.forEach(item => {
        // 使用原生方法
    });
    
    // 最好的做法(特定场景)
    const typedArr = new Float64Array(1000000);
    // 使用类型化数组提升性能
}

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

// 3. 数据结构优化
class DataStructureOptimizer {
    // Map vs Object性能比较
    static mapVsObject() {
        const map = new Map();
        const obj = {};
        const iterations = 1000000;
        
        console.time('Map');
        for (let i = 0; i < iterations; i++) {
            map.set(i, i);
            map.get(i);
        }
        console.timeEnd('Map');
        
        console.time('Object');
        for (let i = 0; i < iterations; i++) {
            obj[i] = i;
            obj[i];
        }
        console.timeEnd('Object');
    }
    
    // Set vs Array性能比较
    static setVsArray() {
        const set = new Set();
        const arr = [];
        const iterations = 1000000;
        
        console.time('Set');
        for (let i = 0; i < iterations; i++) {
            set.add(i);
            set.has(i);
        }
        console.timeEnd('Set');
        
        console.time('Array');
        for (let i = 0; i < iterations; i++) {
            arr.push(i);
            arr.includes(i);
        }
        console.timeEnd('Array');
    }
}

内存优化技术 🚀

// 1. 对象池实现
class ObjectPool {
    constructor(factory, initialSize = 10) {
        this.factory = factory;
        this.pool = [];
        this.init(initialSize);
    }
    
    init(size) {
        for (let i = 0; i < size; i++) {
            this.pool.push(this.factory());
        }
    }
    
    acquire() {
        return this.pool.length > 0 
            ? this.pool.pop() 
            : this.factory();
    }
    
    release(obj) {
        if (this.pool.length < this.maxSize) {
            if (obj.reset) obj.reset();
            this.pool.push(obj);
        }
    }
}

// 2. 内存泄漏防护
class MemoryLeakGuard {
    constructor() {
        this.observers = new WeakSet();
        this.eventHandlers = new WeakMap();
    }
    
    observe(target) {
        if (!this.observers.has(target)) {
            this.observers.add(target);
            this.eventHandlers.set(target, new Map());
        }
    }
    
    addHandler(target, event, handler) {
        if (this.eventHandlers.has(target)) {
            const handlers = this.eventHandlers.get(target);
            handlers.set(event, handler);
            target.addEventListener(event, handler);
        }
    }
    
    removeHandler(target, event) {
        if (this.eventHandlers.has(target)) {
            const handlers = this.eventHandlers.get(target);
            const handler = handlers.get(event);
            if (handler) {
                target.removeEventListener(event, handler);
                handlers.delete(event);
            }
        }
    }
    
    cleanup(target) {
        if (this.eventHandlers.has(target)) {
            const handlers = this.eventHandlers.get(target);
            handlers.forEach((handler, event) => {
                target.removeEventListener(event, handler);
            });
            this.eventHandlers.delete(target);
            this.observers.delete(target);
        }
    }
}

// 3. 大数据处理优化
class BigDataProcessor {
    // 分片处理
    static async processInChunks(items, chunkSize, processor) {
        const results = [];
        
        for (let i = 0; i < items.length; i += chunkSize) {
            const chunk = items.slice(i, i + chunkSize);
            const chunkResults = await Promise.all(
                chunk.map(item => processor(item))
            );
            results.push(...chunkResults);
            
            // 让出主线程
            await new Promise(resolve => setTimeout(resolve, 0));
        }
        
        return results;
    }
    
    // 虚拟列表实现
    static createVirtualList(container, items, rowHeight) {
        let scrollTop = 0;
        let visibleItems = [];
        
        function updateVisibleItems() {
            const containerHeight = container.clientHeight;
            const startIndex = Math.floor(scrollTop / rowHeight);
            const endIndex = Math.min(
                startIndex + Math.ceil(containerHeight / rowHeight),
                items.length
            );
            
            visibleItems = items.slice(startIndex, endIndex).map((item, index) => ({
                ...item,
                style: {
                    position: 'absolute',
                    top: (startIndex + index) * rowHeight + 'px',
                    height: rowHeight + 'px'
                }
            }));
            
            render();
        }
        
        function render() {
            container.innerHTML = '';
            visibleItems.forEach(item => {
                const element = document.createElement('div');
                Object.assign(element.style, item.style);
                element.textContent = item.content;
                container.appendChild(element);
            });
        }
        
        container.style.height = items.length * rowHeight + 'px';
        container.style.position = 'relative';
        container.style.overflow = 'auto';
        
        container.addEventListener('scroll', () => {
            scrollTop = container.scrollTop;
            updateVisibleItems();
        });
        
        updateVisibleItems();
    }
}

网络优化策略 🌐

// 1. 请求优化
class RequestOptimizer {
    constructor() {
        this.cache = new Map();
        this.pendingRequests = new Map();
    }
    
    // 请求去重
    async request(url, options = {}) {
        const key = `${url}-${JSON.stringify(options)}`;
        
        // 检查缓存
        if (this.cache.has(key)) {
            return this.cache.get(key);
        }
        
        // 检查是否有相同的请求正在进行
        if (this.pendingRequests.has(key)) {
            return this.pendingRequests.get(key);
        }
        
        // 发起新请求
        const promise = fetch(url, options)
            .then(response => response.json())
            .finally(() => {
                this.pendingRequests.delete(key);
            });
            
        this.pendingRequests.set(key, promise);
        const result = await promise;
        this.cache.set(key, result);
        
        return result;
    }
    
    // 批量请求
    async batchRequest(urls, options = {}) {
        return Promise.all(
            urls.map(url => this.request(url, options))
        );
    }
}

// 2. 资源预加载
class ResourcePreloader {
    constructor() {
        this.loaded = new Set();
    }
    
    preloadImage(url) {
        if (this.loaded.has(url)) return Promise.resolve();
        
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.onload = () => {
                this.loaded.add(url);
                resolve();
            };
            img.onerror = reject;
            img.src = url;
        });
    }
    
    preloadScript(url) {
        if (this.loaded.has(url)) return Promise.resolve();
        
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.onload = () => {
                this.loaded.add(url);
                resolve();
            };
            script.onerror = reject;
            script.src = url;
            document.head.appendChild(script);
        });
    }
    
    preloadStyle(url) {
        if (this.loaded.has(url)) return Promise.resolve();
        
        return new Promise((resolve, reject) => {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.onload = () => {
                this.loaded.add(url);
                resolve();
            };
            link.onerror = reject;
            link.href = url;
            document.head.appendChild(link);
        });
    }
}

// 3. 数据缓存策略
class CacheStrategy {
    constructor(storage = localStorage) {
        this.storage = storage;
        this.prefix = 'cache_';
    }
    
    set(key, value, ttl = 3600000) { // 默认1小时
        const item = {
            value,
            timestamp: Date.now(),
            ttl
        };
        this.storage.setItem(
            this.prefix + key,
            JSON.stringify(item)
        );
    }
    
    get(key) {
        const item = JSON.parse(
            this.storage.getItem(this.prefix + key)
        );
        
        if (!item) return null;
        
        if (Date.now() - item.timestamp > item.ttl) {
            this.storage.removeItem(this.prefix + key);
            return null;
        }
        
        return item.value;
    }
    
    clear() {
        Object.keys(this.storage)
            .filter(key => key.startsWith(this.prefix))
            .forEach(key => this.storage.removeItem(key));
    }
}

渲染性能优化 🎨

// 1. DOM操作优化
class DOMOptimizer {
    // 批量DOM更新
    static batchUpdate(elements, updates) {
        const fragment = document.createDocumentFragment();
        
        elements.forEach(element => {
            const clone = element.cloneNode(true);
            updates(clone);
            fragment.appendChild(clone);
        });
        
        elements[0].parentNode.replaceChildren(fragment);
    }
    
    // 虚拟DOM实现
    static createVirtualDOM(element) {
        return {
            type: element.tagName.toLowerCase(),
            props: Array.from(element.attributes).reduce((props, attr) => {
                props[attr.name] = attr.value;
                return props;
            }, {}),
            children: Array.from(element.childNodes).map(node => {
                if (node.nodeType === 3) return node.textContent;
                return this.createVirtualDOM(node);
            })
        };
    }
    
    // 最小化重排重绘
    static optimizeReflow(element, updates) {
        const originalDisplay = element.style.display;
        element.style.display = 'none';
        
        updates(element);
        
        element.style.display = originalDisplay;
    }
}

// 2. 动画性能优化
class AnimationOptimizer {
    constructor() {
        this.animations = new Map();
    }
    
    // 使用requestAnimationFrame
    animate(element, properties, duration) {
        const startTime = performance.now();
        const initialValues = {};
        
        Object.keys(properties).forEach(prop => {
            initialValues[prop] = parseFloat(
                getComputedStyle(element)[prop]
            );
        });
        
        const animation = timestamp => {
            const progress = (timestamp - startTime) / duration;
            
            if (progress < 1) {
                Object.keys(properties).forEach(prop => {
                    const initial = initialValues[prop];
                    const target = properties[prop];
                    const current = initial + (target - initial) * progress;
                    element.style[prop] = current + 'px';
                });
                
                this.animations.set(
                    element,
                    requestAnimationFrame(animation)
                );
            } else {
                Object.keys(properties).forEach(prop => {
                    element.style[prop] = properties[prop] + 'px';
                });
                this.animations.delete(element);
            }
        };
        
        this.animations.set(
            element,
            requestAnimationFrame(animation)
        );
    }
    
    // 停止动画
    stop(element) {
        if (this.animations.has(element)) {
            cancelAnimationFrame(this.animations.get(element));
            this.animations.delete(element);
        }
    }
}

// 3. 图片优化
class ImageOptimizer {
    // 图片懒加载
    static lazyLoad(images) {
        const observer = new IntersectionObserver(
            (entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const img = entry.target;
                        img.src = img.dataset.src;
                        observer.unobserve(img);
                    }
                });
            }
        );
        
        images.forEach(img => observer.observe(img));
    }
    
    // 图片预加载
    static preload(urls) {
        return Promise.all(
            urls.map(url => {
                return new Promise((resolve, reject) => {
                    const img = new Image();
                    img.onload = resolve;
                    img.onerror = reject;
                    img.src = url;
                });
            })
        );
    }
    
    // 响应式图片
    static createResponsiveImage(url, sizes) {
        const img = document.createElement('img');
        img.srcset = sizes.map(size => 
            `${url}-${size}w.jpg ${size}w`
        ).join(', ');
        img.sizes = '(max-width: 768px) 100vw, 50vw';
        return img;
    }
}

最佳实践建议 💡

  1. 性能监控
// 1. 性能监控工具
class PerformanceMonitor {
    constructor() {
        this.metrics = new Map();
    }
    
    // 测量执行时间
    measure(name, fn) {
        const start = performance.now();
        const result = fn();
        const duration = performance.now() - start;
        
        this.metrics.set(name, {
            duration,
            timestamp: Date.now()
        });
        
        return result;
    }
    
    // 异步操作测量
    async measureAsync(name, fn) {
        const start = performance.now();
        const result = await fn();
        const duration = performance.now() - start;
        
        this.metrics.set(name, {
            duration,
            timestamp: Date.now()
        });
        
        return result;
    }
    
    // 获取性能报告
    getReport() {
        return Array.from(this.metrics.entries())
            .map(([name, data]) => ({
                name,
                duration: data.duration,
                timestamp: new Date(data.timestamp).toISOString()
            }));
    }
}

// 2. 性能优化检查清单
class PerformanceChecker {
    static checkDOMSize() {
        return document.querySelectorAll('*').length;
    }
    
    static checkEventListeners() {
        const elements = document.querySelectorAll('*');
        let count = 0;
        
        elements.forEach(element => {
            const listeners = getEventListeners(element);
            count += Object.keys(listeners).reduce(
                (sum, type) => sum + listeners[type].length,
                0
            );
        });
        
        return count;
    }
    
    static checkMemoryUsage() {
        if (performance.memory) {
            return {
                usedJSHeapSize: performance.memory.usedJSHeapSize,
                totalJSHeapSize: performance.memory.totalJSHeapSize
            };
        }
        return null;
    }
}

结语 📝

JavaScript性能优化是一个持续的过程,需要我们在开发过程中不断关注和改进。我们学习了:

  1. 代码执行优化技术
  2. 内存使用优化策略
  3. 网络请求优化方法
  4. 渲染性能优化技巧
  5. 性能监控和最佳实践

💡 学习建议:性能优化应该是渐进式的,先找出性能瓶颈,然后针对性地进行优化。使用性能监控工具来量化优化效果,避免过早优化。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻


http://www.kler.cn/a/504086.html

相关文章:

  • 深度学习中的学习率调度器(scheduler)分析并作图查看各方法差异
  • 【C++】PP5015 [NOIP2018 普及组] 标题统计
  • 【端云一体化】云函数的使用
  • CSS | 实现三列布局(两边边定宽 中间自适应,自适应成比)
  • 算法妙妙屋-------2..回溯的奇妙律动
  • 自动连接校园网wifi脚本实践(自动网页认证)
  • 如何通过NMudbus读取寄存器数据
  • Vue环境变量配置指南:如何在开发、生产和测试中设置环境变量
  • mysql 与Redis 数据强一致方案
  • Jenkins简单的安装运行
  • 线程间通信
  • 当生活低迷时,如何醒过走出迷境?
  • SQL从入门到实战-2
  • Scala语言的字符串处理
  • 【某大型互联网企业】软件测试面试经验分享(1 ~ 3年)
  • MySQL表的增删改查(基础)-下篇
  • 面试: 工作中常用的linux命令
  • OpenCV基础:矩阵的创建、检索与赋值
  • Java Stream流操作List全攻略:Filter、Sort、GroupBy、Average、Sum实践
  • 在使用 GitLab API 时,如果只能获取少量的 Merge Request(MR)信息,而没有完整的数据
  • ubuntu 下生成 core dump
  • 2025制定一个高级java开发路线:分布式系统、多线程编程、高并发经验
  • SQL 详解数据库
  • Spring Boot中如何处理跨域请求(CORS)
  • 【Linux】Linux基础命令(二)
  • 《Openlayers零基础教程》第六课:地图控件