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

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) => {const link = document.createElement('link');link.rel = 'stylesheet';link.href = url;link.onload = () => resolve(link);link.onerror = reject;document.head.appendChild(link);});}loadImage(url) {return new Promise((resolve, reject) => {const img = new Image();img.src = url;img.onload = () => resolve(img);img.onerror = reject;});}
}// 3. Web Worker任务管理器
class WorkerTaskManager {constructor(workerScript) {this.worker = new Worker(workerScript);this.taskQueue = new Map();this.taskId = 0;this.worker.onmessage = this.handleMessage.bind(this);this.worker.onerror = this.handleError.bind(this);}executeTask(task, data) {return new Promise((resolve, reject) => {const id = this.taskId++;this.taskQueue.set(id, { resolve, reject });this.worker.postMessage({id,task,data});});}handleMessage(event) {const { id, result, error } = event.data;const task = this.taskQueue.get(id);if (task) {if (error) {task.reject(error);} else {task.resolve(result);}this.taskQueue.delete(id);}}handleError(error) {console.error('Worker error:', error);}terminate() {this.worker.terminate();this.taskQueue.clear();}
}

最佳实践建议 💡

  1. 性能监控模式
// 1. 性能监控器
class PerformanceMonitor {constructor() {this.metrics = new Map();this.thresholds = new Map();}setThreshold(metric, value) {this.thresholds.set(metric, value);}recordMetric(metric, value) {if (!this.metrics.has(metric)) {this.metrics.set(metric, []);}const values = this.metrics.get(metric);values.push({value,timestamp: Date.now()});// 保持最近100个记录if (values.length > 100) {values.shift();}// 检查是否超过阈值const threshold = this.thresholds.get(metric);if (threshold && value > threshold) {this.handleThresholdExceeded(metric, value, threshold);}}getMetricStats(metric) {const values = this.metrics.get(metric);if (!values || values.length === 0) {return null;}const numbers = values.map(v => v.value);return {average: numbers.reduce((a, b) => a + b) / numbers.length,max: Math.max(...numbers),min: Math.min(...numbers),current: numbers[numbers.length - 1]};}handleThresholdExceeded(metric, value, threshold) {console.warn(`Performance threshold exceeded for ${metric}:`, {value,threshold,stats: this.getMetricStats(metric)});}
}// 2. 性能优化建议生成器
class PerformanceAdvisor {constructor() {this.rules = new Map();this.initializeRules();}initializeRules() {this.addRule('longTask', metrics => {if (metrics.taskDuration > 50) {return {severity: 'warning',message: '检测到长任务,考虑使用Web Worker或任务分割'};}});this.addRule('memoryLeak', metrics => {if (metrics.memoryGrowth > 10000000) { // 10MBreturn {severity: 'error',message: '检测到可能的内存泄漏'};}});this.addRule('domSize', metrics => {if (metrics.domNodes > 1000) {return {severity: 'warning',message: 'DOM节点数量过多,考虑使用虚拟滚动或延迟加载'};}});}addRule(name, checkFn) {this.rules.set(name, checkFn);}analyze(metrics) {const issues = [];for (const [name, checkFn] of this.rules) {const result = checkFn(metrics);if (result) {issues.push({rule: name,...result});}}return issues;}
}// 3. 性能报告生成器
class PerformanceReporter {constructor() {this.monitor = new PerformanceMonitor();this.advisor = new PerformanceAdvisor();}generateReport() {const metrics = {taskDuration: this.monitor.getMetricStats('taskDuration'),memoryGrowth: this.monitor.getMetricStats('memoryGrowth'),domNodes: this.monitor.getMetricStats('domNodes'),fps: this.monitor.getMetricStats('fps')};const issues = this.advisor.analyze(metrics);return {timestamp: Date.now(),metrics,issues,recommendations: this.generateRecommendations(issues)};}generateRecommendations(issues) {const recommendations = new Set();issues.forEach(issue => {switch (issue.rule) {case 'longTask':recommendations.add('考虑使用Web Worker处理耗时任务');recommendations.add('实现任务分割和调度');break;case 'memoryLeak':recommendations.add('检查闭包和事件监听器');recommendations.add('使用WeakMap/WeakSet存储对象引用');break;case 'domSize':recommendations.add('实现虚拟滚动');recommendations.add('使用文档片段批量更新DOM');break;}});return Array.from(recommendations);}
}

结语 📝

JavaScript性能优化是一个持续的过程,需要从多个维度进行考虑和实践。通过本文,我们学习了:

  1. 性能分析工具的实现
  2. 代码优化技术
  3. 高级优化模式
  4. 性能监控和优化建议
  5. 最佳实践和设计模式

💡 学习建议:在实际开发中,要根据具体场景选择合适的优化策略。性能优化不是一蹴而就的,需要持续监控和改进。同时,过度优化可能会带来代码可维护性的问题,要在性能和可维护性之间找到平衡。


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

终身学习,共同成长。

咱们下一期见

💻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/11595.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【react+redux】 react使用redux相关内容

首先说一下&#xff0c;文章中所提及的内容都是我自己的个人理解&#xff0c;是我理逻辑的时候&#xff0c;自我说服的方式&#xff0c;如果有问题有补充欢迎在评论区指出。 一、场景描述 为什么在react里面要使用redux&#xff0c;我的理解是因为想要使组件之间的通信更便捷…

JAVA安全—反射机制攻击链类对象成员变量方法构造方法

前言 还是JAVA安全&#xff0c;哎&#xff0c;真的讲不完&#xff0c;太多啦。 今天主要是讲一下JAVA中的反射机制&#xff0c;因为反序列化的利用基本都是要用到这个反射机制&#xff0c;还有一些攻击链条的构造&#xff0c;也会用到&#xff0c;所以就讲一下。 什么是反射…

vim交换文件的作用

1.数据恢复&#xff1a;因为vim异常的退出&#xff0c;使用交换文件可以恢复之前的修改内容。 2.防止多人同时编辑&#xff1a;vim检测到交换文件的存在,会给出提示&#xff0c;以避免一个文件同时被多人编辑。 &#xff08;vim交换文件的工作原理&#xff1a;vim交换文件的工作…

无用知识之:std::initializer_list的秘密

先说结论&#xff0c;用std::initializer_list初始化vector&#xff0c;内部逻辑是先生成了一个临时数组&#xff0c;进行了拷贝构造&#xff0c;然后用这个数组的起终指针初始化initializer_list。然后再用initializer_list对vector进行初始化&#xff0c;这个动作又触发了拷贝…

CoRAG 来自微软与人大的创新RAG框架技术

微软与人大合作开发的CoRAG(Chain-of-Retrieval Augmented Generation)是一种创新的检索增强生成(RAG)框架,旨在通过模拟人类思考方式来提升大语言模型(LLM)在复杂问题上的推理和回答能力。以下是对CoRAG的深度介绍: 1. CoRAG的核心理念 CoRAG的核心思想是通过动态调…

一文讲解HashMap线程安全相关问题(上)

HashMap不是线程安全的&#xff0c;主要有以下几个问题&#xff1a; ①、多线程下扩容会死循环。JDK1.7 中的 HashMap 使用的是头插法插入元素&#xff0c;在多线程的环境下&#xff0c;扩容的时候就有可能导致出现环形链表&#xff0c;造成死循环。 JDK 8 时已经修复了这个问…

网络基础知识

1 互联网本质 ​ 互联网&#xff08;英语&#xff1a;Internet&#xff09;是指20世纪末期兴起电脑网络与电脑网络之间所串连成的庞大网络系统。这些网络以一些标准的网络协议相连。它是由从地方到全球范围内几百万个私人、学术界、企业和政府的网络所构成&#xff0c;通過电子…

DeepSeek R1本地化部署 Ollama + Chatbox 打造最强 AI 工具

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; Ollama &#x1f98b; 下载 Ollama&#x1f98b; 选择模型&#x1f98b; 运行模型&#x1f98b; 使用 && 测试 二&#xff1a;&#x1f525; Chat…

012-51单片机CLD1602显示万年历+闹钟+农历+整点报时

1. 硬件设计 硬件是我自己设计的一个通用的51单片机开发平台&#xff0c;可以根据需要自行焊接模块&#xff0c;这是用立创EDA画的一个双层PCB板&#xff0c;所以模块都是插针式&#xff0c;不是表贴的。电路原理图在文末的链接里&#xff0c;PCB图暂时不选择开源。 B站上传的…

首发!ZStack 智塔支持 DeepSeek V3/R1/ Janus Pro,多种国产 CPU/GPU 可私有化部署

2025年2月2日&#xff0c;针对日益强劲的AI推理需求和企业级AI应用私有化部署场景&#xff08;Private AI&#xff09;&#xff0c;云轴科技 ZStack 宣布 AI Infra 平台 ZStack 智塔全面支持企业私有化部署 DeepSeek V3/R1/ Janus Pro三种模型&#xff0c;并可基于海光、昇腾、…

谭浩强C语言程序设计(4) 8章(下)

1、输入三个字符串按照字母顺序从小到大输出 #include <cstdio> // 包含cstdio头文件&#xff0c;用于输入输出函数 #include <cstring> // 包含cstring头文件&#xff0c;用于字符串处理函数#define N 20 // 定义字符串的最大长度为20// 函数&#xff1a;…

洛谷 P10289 [GESP样题 八级] 小杨的旅游 C++ 完整题解

一、题目链接 P10289 [GESP样题 八级] 小杨的旅游 - 洛谷 二、题目大意 n个节点之间有n - 1条边&#xff0c;其中k个节点是传送门&#xff0c;任意两个传送门之间可以 以0单位地时间相互到达。问从u到v至少需要多少时间&#xff1f; 三、解题思路 输入不必多讲。 cin >> …

【Linux系统】信号:信号保存 / 信号处理、内核态 / 用户态、操作系统运行原理(中断)

理解Linux系统内进程信号的整个流程可分为&#xff1a; 信号产生 信号保存 信号处理 上篇文章重点讲解了 信号的产生&#xff0c;本文会讲解信号的保存和信号处理相关的概念和操作&#xff1a; 两种信号默认处理 1、信号处理之忽略 ::signal(2, SIG_IGN); // ignore: 忽略#…

Python 网络爬虫实战:从基础到高级爬取技术

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 网络爬虫&#xff08;Web Scraping&#xff09;是一种自动化技术&#xff0c;利用程序从网页中提取数据&#xff0c;广泛…

Windows程序设计10:文件指针及目录的创建与删除

文章目录 前言一、文件指针是什么&#xff1f;二、设置文件指针的位置&#xff1a;随机读写&#xff0c;SetFilePointer函数1.函数说明2.函数实例 三、 目录的创建CreateDirectory四、目录的删除RemoveDirectory总结 前言 Windows程序设计10&#xff1a;文件指针及目录的创建与…

关于安卓greendao打包时报错问题修复

背景 项目在使用greendao的时候&#xff0c;debug安装没有问题&#xff0c;一到打包签名就报了。 环境 win10 jdk17 gradle8 项目依赖情况 博主的greendao是一个独立的module项目&#xff0c;项目目前只适配了java&#xff0c;不支持Kotlin。然后被外部集成。greendao版本…

设计模式 - 行为模式_Template Method Pattern模板方法模式在数据处理中的应用

文章目录 概述1. 核心思想2. 结构3. 示例代码4. 优点5. 缺点6. 适用场景7. 案例&#xff1a;模板方法模式在数据处理中的应用案例背景UML搭建抽象基类 - 数据处理的 “总指挥”子类定制 - 适配不同供应商供应商 A 的数据处理器供应商 B 的数据处理器 在业务代码中整合运用 8. 总…

FlashAttention v1 论文解读

论文标题&#xff1a;FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness 论文地址&#xff1a;https://arxiv.org/pdf/2205.14135 FlashAttention 是一种重新排序注意力计算的算法&#xff0c;它无需任何近似即可加速注意力计算并减少内存占用。…

stm32硬件实现与w25qxx通信

使用的型号为stm32f103c8t6与w25q64。 STM32CubeMX配置与引脚衔接 根据stm32f103c8t6引脚手册&#xff0c;采用B12-B15四个引脚与W25Q64连接&#xff0c;实现SPI通信。 W25Q64SCK&#xff08;CLK&#xff09;PB13MOSI&#xff08;DI&#xff09;PB15MISO(DO)PB14CS&#xff08…

软件工程概论试题五

一、多选 1.好的软件的基本属性包括()。 A. 效率 B. 可依赖性和信息安全性 C. 可维护性 D.可接受性 正答&#xff1a;ABCD 2.软件工程的三要素是什么()? A. 结构化 B. 工具 C.面向对象 D.数据流! E.方法 F.过程 正答&#xff1a;BEF 3.下面中英文术语对照哪些是正确的、且是属…