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

JavaScript性能优化实战指南

JavaScript性能优化实战指南


1. 性能分析工具与指标

核心工具链

  • Chrome DevTools

    • Performance面板:记录运行时性能,分析长任务(Long Tasks)、强制回流(Layout Shifts)、函数调用堆栈。
    • Memory面板:抓取堆快照,检测内存泄漏(Detached DOM节点、闭包残留)。
    • Coverage工具:分析未使用的JS代码(代码覆盖率),指导按需加载。
  • Lighthouse

    • 生成性能评分报告,聚焦关键指标:
      • FCP (First Contentful Paint)
      • TTI (Time to Interactive)
      • TBT (Total Blocking Time)

性能指标阈值

  • 长任务:单次主线程任务 ≤ 50ms(避免阻塞UI线程)。
  • 内存占用:页面生命周期内堆内存波动 ≤ 20%(警惕内存泄漏)。

2. 代码执行效率优化

关键优化策略

  • 减少主线程负载

    // 坏实践:同步遍历大数据
    const data = Array(1e6).fill({ value: Math.random() });
    data.forEach(item => heavyCalculation(item)); // 阻塞主线程// 优化:分片执行(使用 requestIdleCallback 或 setTimeout)
    function processChunk(start, end) {for (let i = start; i < end; i++) {heavyCalculation(data[i]);}if (end < data.length) {requestIdleCallback(() => processChunk(end, end + 1000));}
    }
    processChunk(0, 1000);
    
  • 算法复杂度优化

    • 将 O(n²) 的嵌套循环改为哈希表(Map/Set)实现 O(1) 查找。
    // 优化前:O(n²)
    const findDuplicates = (arr) => arr.filter((item, index) => arr.indexOf(item) !== index);// 优化后:O(n)
    const findDuplicates = (arr) => {const seen = new Set();return arr.filter(item => seen.has(item) || (seen.add(item), false));
    };
    
  • 避免强制同步布局(Layout Thrashing)

    // 坏实践:读写样式导致多次回流
    element.style.width = '100px';
    const height = element.offsetHeight; // 触发回流
    element.style.height = height + 'px'; // 再次触发回流// 优化:批量读写(使用 FastDOM 或手动批处理)
    requestAnimationFrame(() => {element.style.width = '100px';element.style.height = `${element.offsetHeight}px`;
    });
    

3. 内存管理优化

内存泄漏检测与修复

  • 常见泄漏场景

    • 未清除的定时器/事件监听

      // 泄漏示例
      class Component {constructor() {this.handleClick = () => console.log('click');document.addEventListener('click', this.handleClick);}// 组件销毁时未移除监听
      }// 修复:在unmount阶段移除
      class Component {destroy() {document.removeEventListener('click', this.handleClick);}
      }
      
    • 闭包引用外部变量

      // 泄漏示例:大对象被闭包长期持有
      function init() {const bigData = new Array(1e6).fill({});return () => bigData[0]; // bigData 无法被GC回收
      }// 修复:手动释放引用
      let closureRef = null;
      function init() {const bigData = new Array(1e6).fill({});closureRef = () => bigData[0];// 需要时手动置空closureRef = null;
      }
      
  • 弱引用优化

    // 使用 WeakMap/WeakSet 避免内存泄漏
    const weakCache = new WeakMap();
    function cacheHeavyObject(obj) {if (!weakCache.has(obj)) {const result = heavyCompute(obj);weakCache.set(obj, result);}return weakCache.get(obj);
    }
    

4. 异步与并行处理

Web Workers多线程优化

  • 主线程与Worker通信示例

    // 主线程
    const worker = new Worker('worker.js');
    worker.postMessage({ data: largeArray });
    worker.onmessage = (e) => console.log('Result:', e.data);// worker.js
    self.onmessage = (e) => {const result = processData(e.data); // 耗时计算self.postMessage(result);
    };
    
  • OffscreenCanvas渲染优化

    // 将Canvas渲染迁移至Worker
    const offscreen = document.querySelector('canvas').transferControlToOffscreen();
    const worker = new Worker('canvas-worker.js');
    worker.postMessage({ canvas: offscreen }, [offscreen]);
    

空闲时段调度(Idle Period)

// 使用 requestIdleCallback 执行低优先级任务
requestIdleCallback((deadline) => {while (deadline.timeRemaining() > 0) {processLowPriorityTask();}
});

5. 资源加载与执行优化

代码分割与懒加载

  • 动态导入(Dynamic Import)

    // 按需加载模块
    document.getElementById('btn').addEventListener('click', async () => {const module = await import('./heavy-module.js');module.run();
    });
    
  • Preload/Prefetch优化加载时机

    <!-- 预加载关键资源 -->
    <link rel="preload" href="critical.js" as="script">
    <!-- 预取非关键资源 -->
    <link rel="prefetch" href="next-page-chart.js" as="script">
    

执行时机控制

  • 延迟非关键脚本

    <!-- 使用 defer/async 控制执行顺序 -->
    <script src="analytics.js" defer></script>
    <script src="ads.js" async></script>
    
  • 空闲时段加载第三方脚本

    // 延迟加载非必要脚本(如评论区、广告)
    if ('requestIdleCallback' in window) {requestIdleCallback(() => loadThirdPartyScript());
    } else {setTimeout(loadThirdPartyScript, 5000);
    }
    

6. 框架级性能优化

React优化实践

  • 避免不必要的渲染

    // 使用 React.memo + useCallback 缓存组件
    const MemoizedComponent = React.memo(({ data }) => (<div>{data.value}</div>
    ));// 父组件传递稳定引用
    const Parent = () => {const data = useMemo(() => ({ value: computeValue() }), []);return <MemoizedComponent data={data} />;
    };
    
  • 虚拟列表优化大数据渲染

    // 使用 react-window 渲染长列表
    import { FixedSizeList as List } from 'react-window';const Row = ({ index, style }) => (<div style={style}>Row {index}</div>
    );const App = () => (<List height={600} itemCount={100000} itemSize={35} width={300}>{Row}</List>
    );
    

Vue优化实践

  • v-once与虚拟滚动

    <!-- 静态内容单次渲染 -->
    <div v-once>{{ staticTitle }}</div><!-- 使用 vue-virtual-scroller 优化 -->
    <VirtualScroller :items="largeList" item-height="50" />
    
  • 计算属性缓存

    export default {data() {return { list: [...] };},computed: {filteredList() { // 缓存结果,避免重复计算return this.list.filter(item => item.active);}}
    }
    

7. 实战案例

案例1:优化大数据表格渲染

  • 问题:1万行数据的表格渲染卡顿(FPS < 30)。
  • 优化步骤
    1. 使用虚拟滚动仅渲染可视区域元素。
    2. 将单元格渲染迁移至Web Worker计算。
    3. 用CSS transform 替代 top 定位滚动位置。
  • 结果:FPS提升至60,内存占用下降40%。

案例2:首屏加载性能优化

  • 问题:主JS文件体积2MB,TTI超过5秒。
  • 优化步骤
    1. 代码分割:基于路由动态加载模块。
    2. 压缩+Tree Shaking:使用Terser删除未使用代码。
    3. 预加载关键字体和图片。
  • 结果:首屏JS体积降至500KB,TTI缩短至1.8秒。

性能优化Checklist

  • 代码层面

    • 避免同步阻塞操作(如同步XHR、大循环)。
    • 使用Web Workers处理CPU密集型任务。
    • 减少全局变量,及时解除引用。
  • 渲染层面

    • 使用requestAnimationFrame调度动画。
    • 避免频繁操作DOM,批量修改样式。
  • 工程化层面

    • 启用Gzip/Brotli压缩。
    • 使用HTTP/2或HTTP/3优化资源加载。
    • 配置长期缓存(文件名Hash)。

通过**「分析→优化→监控→迭代」闭环**,结合性能火焰图与真实用户监控(RUM)数据,持续提升JavaScript应用的流畅度与响应速度。

相关文章:

JavaScript性能优化实战指南

JavaScript性能优化实战指南 1. 性能分析工具与指标 核心工具链 Chrome DevTools&#xff1a; Performance面板&#xff1a;记录运行时性能&#xff0c;分析长任务&#xff08;Long Tasks&#xff09;、强制回流&#xff08;Layout Shifts&#xff09;、函数调用堆栈。Memory面…...

宇树人形机器人开源模型

1. 下载源码 https://github.com/unitreerobotics/unitree_ros.git2. 启动Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 这个错误通常出现在虚拟机环境中运行需要OpenGL支持的应用…...

【Linux】浅谈冯诺依曼和进程

一、冯诺依曼体系结构 冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。 冯诺依曼的设计特点 二进制表示 所有数据&#xff08;包括程序指令&#xff09;均以二进制形式存储和运算&#xff0c;简化了硬件逻辑设计&#xff0c;提高了可靠性。 存储程序原理…...

env.development.local 和 env.development 的区别

env.development.local 和 env.development 的区别 区别1、场景2、git管理3、加载策略 思考原因如下 区别 1、场景 env.development: 用于开发环境的环境变量配置env.development.local: 用于存储特定于开发者的本地配置信息 2、git管理 env.development.local 会通过*.loca…...

linux操作系统实战

第一题 创建根目录结构中的所有的普通文件 [rootlocalhost ~]# cd /[rootlocalhost /]# mkdir /text[rootlocalhost /]# cd /text[rootlocalhost text]# mkdir /text/boot /text/root /text/home /text/bin /text/sbin /text/lib /text/lib64 /text/usr /text/opt /text/etc /…...

Python Cookbook-4.1 对象拷贝

任务 想拷贝某对象。不过&#xff0c;当你对一个对象赋值&#xff0c;将其作为参数传递&#xff0c;或者作为结果返回时&#xff0c;Python 通常会使用指向原对象的引用&#xff0c;并不是真正的拷贝。 解决方案 Python 标准库的 copy 模块提供了两个函数来创建拷贝。第一个…...

浅谈时钟启动和Systemlnit函数

时钟是STM32的关键&#xff0c;是整个系统的心脏&#xff0c;时钟如何启动&#xff0c;时钟源如何选择&#xff0c;各个参数如何设置&#xff0c;我们从源码来简单分析一下时钟的启动函数Systemlnit&#xff08;&#xff09;。 Systemlnit函数简介 我们先来看一下源程序的注释…...

事业单位ABCDE类

1 我刚刚查阅了一下安徽省市直单位报名的表&#xff0c;我这个专业报的岗位大多数是自然科学专技岗。 2 安徽省的岗位大多都限制计算机科学与技术&#xff0c;我这个0854计算机技术能报的岗位十分有限。 而且我没有看到一个岗位只招应届生&#xff0c;显然安徽不保护应届生的…...

Python:函数(一)

python函数相关的知识点 1. 函数定义与调用 定义&#xff1a;使用 def 关键字&#xff0c;后接函数名和参数列表。 def greet(name):"""打印问候语&#xff08;文档字符串&#xff09;"""print(f"Hello, {name}!") 调用&#xff1a…...

MySql学习_基础Sql语句

目录 1.数据库相关概念 2.SQL 2.1 SQL通用语法 2.2 SQL分类 2.3 DDL&#xff08;数据库定义语言&#xff09; 2.4 DML&#xff08;数据操作语言&#xff09; 2.5 DQL&#xff08;数据查询语言&#xff09; 2.6 DCL&#xff08;数据控制语言&#xff09; 3. 函数 3.1 字…...

Nginx 生产环境安全配置加固

以下是Nginx生产环境安全配置加固的综合方案&#xff0c;结合多个技术实践和行业标准整理&#xff1a; 一、基础安全防护 1‌. 隐藏版本信息‌ 在http或server块添加server_tokens off;&#xff0c;避免暴露Nginx版本号‌。使用headers-more-nginx-module模块彻底移除响应头…...

C#中继承的核心定义‌

1. 继承的核心定义‌ ‌继承‌ 是面向对象编程&#xff08;OOP&#xff09;的核心特性之一&#xff0c;允许一个类&#xff08;称为‌子类/派生类‌&#xff09;基于另一个类&#xff08;称为‌父类/基类‌&#xff09;构建&#xff0c;自动获得父类的成员&#xff08;字段、属…...

小白学Agent技术[5](Agent框架)

文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…...

21.dirsearch:Web 路径扫描工具

一、项目介绍 dirsearch 是一款高效、多线程的 Web 路径扫描工具&#xff0c;专为渗透测试人员和网络安全研究人员设计&#xff0c;用于发现目标网站的隐藏目录、敏感文件及未授权接口。其支持自定义字典、代理配置、请求头伪装等功能&#xff0c;适用于红队渗透、漏洞挖掘及资…...

VSTO(C#)Excel开发4:打印设置

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

设计模式Python版 模板方法模式(上)

文章目录 前言一、模板方法模式二、模板方法模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间…...

源IP泄露后如何涅槃重生?高可用架构与自动化防御体系设计

一、架构层解决方案 1. 高防代理架构设计 推荐架构&#xff1a; 用户 → CDN&#xff08;缓存静态资源&#xff09; → 高防IP&#xff08;流量清洗&#xff09; → 源站集群&#xff08;真实IP隐藏&#xff09; ↑ Web应用防火墙&#xff08;WAF&#xff09; 实施要点&a…...

transformer bert 多头自注意力

输入的&#xff08;a1,a2,a3,a4&#xff09;是最终嵌入&#xff0c;是一个(512,768)的矩阵&#xff1b;而a1是一个token&#xff0c;尺寸是768 a1通过wq权重矩阵&#xff0c;经过全连接变换得到查询向量q1&#xff1b;a2通过Wk权重矩阵得到键向量k2&#xff1b;q和k点乘就是值…...

python-leetcode-定长子串中元音的最大数目

1456. 定长子串中元音的最大数目 - 力扣&#xff08;LeetCode&#xff09; 可以使用 滑动窗口 方法来解决这个问题。步骤如下&#xff1a; 初始化&#xff1a;计算前 k 个字符中元音字母的个数&#xff0c;作为初始窗口的值。滑动窗口&#xff1a;遍历字符串&#xff0c;每次右…...

Spring Boot + MyBatis-Plus 项目目录结构

以下是一个标准的 Spring Boot MyBatis-Plus 项目目录结构及文件命名规范&#xff0c;包含每个目录和文件的作用说明&#xff0c;适用于中大型项目开发&#xff1a; 项目根目录结构 src/ ├── main/ │ ├── java/ # Java 源代码 │ │ └── com/…...

Python之变量及简单的数据类型

本文来源于《Python从入门到实践》&#xff0c;自己整理以供工作参考 基本内容 print("Hello Python World!")message "Hello Python world!" print(message)message "Helllo Python Crash Course world!" print(message)name "ada lov…...

力扣 Hot 100 刷题记录 - 翻转二叉树

力扣 Hot 100 刷题记录 - 翻转二叉树 题目描述 翻转二叉树 是力扣 Hot 100 中的一道经典题目&#xff0c;题目要求如下&#xff1a; 给你一棵二叉树的根节点 root&#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7…...

力扣215.数组中的第K个最大元素--堆排序法(java)

为了找到数组中第K个最大的元素&#xff0c;我们可以使用堆排序的方法。堆排序的核心是构建一个最大堆&#xff0c;并通过多次交换堆顶元素来找到前K个最大的元素。具体步骤如下&#xff1a; 方法思路 构建最大堆&#xff1a;将输入数组转换为最大堆&#xff0c;使得每个父节…...

MySQL增删改查操作 -- CRUD

个人主页&#xff1a;顾漂亮 目录 1.CRUD简介 2.Create新增 使用示例&#xff1a; 注意点&#xff1a; 3.Retrieve检索 使用示例&#xff1a; 注意点&#xff1a; 4.where条件查询 前置知识&#xff1a;-- 运算符 比较运算符 使用示例&#xff1a; 注意点&#xf…...

【算法day9】回文数-给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#…...

RSA混合加密RSA混合加密

RSA混合加密是一种结合非对称加密&#xff08;RSA&#xff09;和对称加密&#xff08;AES&#xff09;的技术&#xff0c;通过两者的优势互补&#xff0c;实现高效且安全的数据传输。以下是详细解释和示例&#xff1a; RSA混合加密的核心原理 非对称加密&#xff08;RSA&#x…...

蛋白质功能预测论文阅读记录2025(DPFunc、ProtCLIP)

前言 最近研究到瓶颈了&#xff0c;怎么优化都提升不了&#xff0c;遂开始看点最新的论文。 DPFunc 2025.1.2 Nature Communication 中南大学 论文地址&#xff1a;DPFunc: accurately predicting protein function via deep learning with domain-guided structure inform…...

Linux网络套接字编程——UDP服务器

Linux网络套接字编程——创建并绑定-CSDN博客 前面已经介绍了网络套接字的创建和绑定&#xff0c;这篇文章会通过UDP套接字实现一个UDP服务器。 先介绍将使用的接口。 recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr,…...

主流向量数据库对比

在 AI 的 RAG&#xff08;检索增强生成&#xff09;研发领域&#xff0c;向量数据库是存储和查询向量嵌入的核心工具&#xff0c;用于支持高效的语义搜索和信息检索。向量嵌入是文本或其他非结构化数据的数值表示&#xff0c;RAG 系统通过这些嵌入从知识库中检索相关信息&#…...

54.HarmonyOS NEXT 登录模块开发教程(八):测试与调试技巧

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT 登录模块开发教程&#xff08;八&#xff09;&#xff1a;测试与调试技巧 文章目录 HarmonyOS NEXT 登录模块开发教程&#xff08;…...