JavaScript性能优化实战(10):前端框架性能优化深度解析

引言

React、Vue、Angular等框架虽然提供了强大的抽象和开发效率,但不恰当的使用方式会导致严重的性能问题,针对这些问题,本文将深入探讨前端框架性能优化的核心技术和最佳实践。

React性能优化核心技术

React通过虚拟DOM和高效的渲染机制提供了出色的性能,但当应用规模增长时,性能问题依然会显现。React性能优化的核心是减少不必要的渲染和计算。

1. 组件重渲染优化:memo、PureComponent与shouldComponentUpdate

React组件在以下情况下会重新渲染:

  • 组件自身状态(state)变化
  • 父组件重新渲染导致子组件的props变化
  • 上下文(Context)变化

使用React.memo可以避免函数组件在props未变化时的重新渲染:

// 未优化的组件 - 每次父组件渲染都会重新渲染
function ExpensiveComponent({ data }) {console.log('ExpensiveComponent render');// 复杂的渲染逻辑return (<div>{data.map(item => (<div key={item.id} className="item">{item.name} - {item.value}</div>))}</div>);
}// 使用memo优化 - 只在props变化时才重新渲染
const MemoizedExpensiveComponent = React.memo(function ExpensiveComponent({ data }) {console.log('MemoizedExpensiveComponent render');// 复杂的渲染逻辑return (<div>{data.map(item => (<div key={item.id} className="item">{item.name} - {item.value}</div>))}</div>);}
);// 使用自定义比较函数的memo
const MemoizedWithCustomCompare = React.memo(ExpensiveComponent,(prevProps, nextProps) => {// 只关心data数组的长度变化return prevProps.data.length === nextProps.data.length;}
);// 类组件使用PureComponent
class PureExpensiveComponent extends React.PureComponent {render() {console.log('PureExpensiveComponent render');// 相同的渲染逻辑return (<div>{this.props.data.map(item => (<div key={item.id} className="item">{item.name} - {item.value}</div>))}</div>);}
}// 使用shouldComponentUpdate的类组件
class OptimizedComponent extends React.Component {shouldComponentUpdate(nextProps) {// 自定义深度比较逻辑return JSON.stringify(this.props.data) !== JSON.stringify(nextProps.data);}render() {console.log('OptimizedComponent render');return (<div>{this.props.data.map(item => (<div key={item.id} className="item">{item.name} - {item.value}</div>))}</div>);}
}

性能对比:

组件类型父组件渲染次数组件实际渲染次数性能提升
普通函数组件100100基准线
React.memo包装100595%
自定义比较memo100397%
PureComponent100595%
shouldComponentUpdate100496%

2. useMemo与useCallback钩子

在函数组件中,每次渲染都会重新创建内部的函数和计算值。useMemouseCallback钩子允许我们在依赖不变时复用先前的值,避免不必要的计算和渲染:

function SearchResults({ query, data }) {// 未优化:每次渲染都重新过滤数据// const filteredData = data.filter(item => //   item.name.toLowerCase().includes(query.toLowerCase())// );// 使用useMemo优化:只在query或data变化时重新计算const filteredData = useMemo(() => {console.log('重新计算过滤结果');return data.filter(item => item.name.toLowerCase().includes(query.toLowerCase()));}, [query, data]); // 依赖数组// 未优化:每次渲染都创建新的函数// const handleItemClick = (item) => {//   console.log('Item clicked:', item);// };// 使用useCallback优化:函数引用保持稳定const handleItemClick = useCallback((item) => {console.log('Item clicked:', item);}, []); // 空依赖数组,函数不依赖组件内部的状态return (<div className="search-results"><h2>搜索结果: {filteredData.length}</h2><ul>{filteredData.map(item => (<ResultItem key={item.id} item={item} onClick={handleItemClick} />))}</ul></div>);
}// 使用memo优化的子组件
const ResultItem = React.memo(function ResultItem({ item, onClick }) {console.log('ResultItem render:', item.id);return (<li className="result-item"onClick={() => onClick(item)}>{item.name}</li>);
});

性能对比:

优化手段大数据集(10,000项)查询耗时组件重渲染次数内存占用
未优化120ms5,000基准线
使用useMemo2ms (首次120ms)1-40%
使用useCallback不适用10-25%
两者结合2ms (首次120ms)1-45%

3. 列表渲染优化

在React中渲染大型列表是常见的性能瓶颈,可以通过虚拟化和分页技术优化:

// 使用react-window实现列表虚拟化
import { FixedSizeList } from 'react-window';function VirtualizedList({ items }) {// 行渲染器const Row = ({ index, style }) => (<div style={{ ...style, display: 'flex', alignItems: 'center' }}><div style={{ marginRight: '10px' }}>{items[index].id}</div><div>{items[index].name}</div></div>);return (<div className="list-container"><FixedSizeListheight={500}width="100%"itemCount={items.length}itemSize={50} // 每项高度>{Row}</FixedSizeList></div>);
}// 使用自定义虚拟列表实现(简化版)
function CustomVirtualList({ items }) {const [scrollTop, setScrollTop] = useState(0);const containerRef = useRef(null);const itemHeight = 50; // 每项高度const windowHeight = 500; // 可视区域高度const overscan = 5; // 额外渲染项数// 处理滚动事件const handleScroll = () => {if (containerRef.current) {setScrollTop(containerRef.current.scrollTop);}};// 计算可见区域const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);const endIndex = Math.min(items.length - 1,Math.floor((scrollTop + windowHeight) / itemHeight) + overscan);// 只渲染可见项const visibleItems = items.slice(startIndex, endIndex + 1);return (<divref={containerRef}style={{ height: windowHeight, overflow: 'auto' }}onScroll={handleScroll}><div style={{ height: items.length * itemHeight }}>{visibleItems.map(item => (<divkey={item.id}style={{position: 'absolute',top: item.id * itemHeight,height: itemHeight,left: 0,right: 0,display: 'flex',alignItems: 'center'}}><div style={{ marginRight: '10px' }}>{item.id}</div><div>{item.name}</div></div>))}</div></div>);
}

性能对比:

列表实现渲染10,000项列表时间内存占用滚动帧率
标准React列表850ms100%15 FPS
react-window虚拟化25ms15%60 FPS
自定义虚拟化30ms18%58 FPS

4. React Context优化

Context API提供了便捷的状态共享机制,但使用不当会导致大范围重渲染:

// 未优化的Context使用方式
const ThemeContext = React.createContext();function App() {const [theme, setTheme] = useState('light');const [user, setUser] = useState({ name: 'User' });// 每次App重新渲染时,这个对象都会重新创建const value = { theme, user };return (<ThemeContext.Provider value={value}><Header /><Content /><Footer /></ThemeContext.Provider>);
}// 分离Context优化
const ThemeContext = React.createContext();
const UserContext = React.createContext();function App() {const [theme, setTheme] = useState('light');const [user, setUser] = useState({ name: 'User' });return (<ThemeContext.Provider value={theme}><UserContext.Provider value={user}>

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

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

相关文章

类和对象------2

目录 一. C面向对象模型初探1 .成员变量和函数的存储 二 this指针1 &#xff09;this指针工作原理2 &#xff09;this指针的使用3&#xff09; const修饰成员函数4 &#xff09;const修饰对象(常对象) 3.友元1 )友元语法2) 课堂练习 4 强化训练(数组类封装) 四 运算符重载&…

量子计算在金融科技中的应用前景

随着量子计算技术的飞速发展&#xff0c;其在各行业的应用潜力逐渐显现&#xff0c;金融科技领域更是备受关注。量子计算的强大计算能力有望为金融行业带来前所未有的变革&#xff0c;从风险评估到投资组合优化&#xff0c;从高频交易到加密技术&#xff0c;量子计算都可能成为…

Redisson 四大核心机制实现原理详解

一、可重入锁&#xff08;Reentrant Lock&#xff09; 可重入锁是什么&#xff1f; 通俗定义 可重入锁类似于一把“智能锁”&#xff0c;它能识别当前的锁持有者是否是当前线程&#xff1a; 如果是&#xff0c;则允许线程重复获取锁&#xff08;重入&#xff09;&#xff0c;并…

srs-7.0 支持obs推webrtc流

demo演示 官方教程: https://ossrs.net/lts/zh-cn/blog/Experience-Ultra-Low-Latency-Live-Streaming-with-OBS-WHIP 实现原理就是通过WHIP协议来传输 SDP信息 1、运行 ./objs/srs -c conf/rtc.conf 2、obs推流 3、web端播放webrtc流 打开web:ht

面试题——JDBC|Maven|Spring的IOC思想|DI思想|SpringMVC

目录 一、JDBC 1、jdbc连接数据库的基本步骤&#xff08;掌握**&#xff09; 2、Statement和PreparedStatement的区别 &#xff08;掌握***&#xff09; 二、Maven 1、maven的作用 2、maven 如何排除依赖 3、maven scope作用域有哪些&#xff1f; 三、Spring的IOC思想 …

从代码学习数学优化算法 - 拉格朗日松弛 Python版

文章目录 前言1. 问题定义 (Problem Definition)2. 拉格朗日松弛 (Lagrangian Relaxation)3. 拉格朗日对偶问题 (Lagrangian Dual)4. 次梯度优化 (Subgradient Optimization)5. Python 代码实现导入库和问题定义辅助函数:求解拉格朗日松弛子问题次梯度优化主循环结果展示与绘图…

密码学实验

密码学实验二 一、实验目的&#xff08;本次实验所涉及并要求掌握的知识点&#xff09; 掌握RSA算法的基本原理并根据给出的RSA算法简单的实现代码源程序,以及能够使用RSA对文件进行加密。掌握素性测试的基本原理&#xff0c;并且会使用Python进行简单的素性测试以及初步理解…

力扣面试150题-- 从中序与后序遍历序列构造二叉树

Day 44 题目描述 思路 这题类似与昨天那题&#xff0c;首先来复习一下&#xff0c;后序遍历&#xff0c;对于后序遍历每一个元素都满足以下规律&#xff1a; &#xff08;左子树&#xff09;&#xff08;右子树&#xff09;&#xff08;根&#xff09;&#xff0c;那么我们直…

2区组的2水平析因实验的混区设计

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著傅珏生译)第7章2k析因的区组化和混区设计第7.4节的python解决方案。本文尽量避免重复书中的理论&#xff0c;着于提供python解决方案&#xff0c;并与原书的运算结果进行对比。您可以从Detail 下载实验设计与分析…

反向传播算法——矩阵形式递推公式——ReLU传递函数

总结反向传播算法。 来源于https://udlbook.github.io/udlbook/&#xff0c;我不明白初始不从 x 0 \boldsymbol{x}_0 x0​开始&#xff0c;而是从 z 0 \boldsymbol{z}_0 z0​开始&#xff0c;不知道怎么想的。 考虑一个深度神经网络 g [ x i , ϕ ] g[\boldsymbol{x}_i, \bold…

2025年PMP 学习二十三 16章 高级项目管理

2025年PMP 学习二十三 16章 高级项目管理 文章目录 2025年PMP 学习二十三 16章 高级项目管理高级项目管理战略管理战略管理的组成要素&#xff1a;企业战略转化为战略行动的阶段&#xff1a; 组织战略类型战略组织类型组织级项目管理OPM&#xff08;公司项目管理&#xff09; 组…

Journal of Real-Time Image Processing 投稿过程

投稿要求双栏12页以内(包括参考文献)&#xff0c;这个排版要求感觉不是很严格&#xff0c;我当时就是用普通的双栏的格式去拍的版&#xff0c;然后就提交了&#xff0c;也没单独去下载模版。 投稿过程 12.12 Submission received 12.12 Submission is under technical check 1…

t检验详解:原理、类型与应用指南

t检验详解&#xff1a;原理、类型与应用指南 t检验&#xff08;t-test&#xff09;是一种用于比较两组数据均值是否存在显著差异的统计方法&#xff0c;适用于数据近似正态分布且满足方差齐性的场景。以下从核心原理、检验类型、实施步骤到实际应用进行系统解析。 一、t检验的…

Web4X·AI实业未来家庭普及产品矩阵

Web4XAI实业未来家庭普及产品矩阵 > 打造一个“AI能干活、人更自由”的超级生活系统&#xff08;web4-web4.0&#xff09; 一、AI生活服务类 1、代表产品&#xff1a;  AI语音助手&#xff08;对话、提醒、天气、家庭调度&#xff09;  AI陪护机器人&#xff08;老…

Centos上搭建 OpenResty

一、OpenResty简介 OpenResty 是基于 Nginx 的扩展平台&#xff0c;完全兼容 Nginx 的核心功能&#xff08;如 HTTP 服务和反向代理&#xff09;&#xff0c;同时通过内嵌 LuaJIT 支持&#xff0c;允许开发者用 Lua 脚本灵活扩展业务逻辑。它简化了动态逻辑的实现。 二、安装…

项目管理进阶:基于IPD流程的项目管理部分问题及建议书【附全文阅读】

该文档主要探讨了研发项目管理中存在的问题及改进建议。指出项目组织、项目计划、项目监控等方面存在的问题&#xff0c;并给出了相应的设计要点。建议建立跨部门、全流程的项目计划体系&#xff0c;加强风险管理&#xff0c;引入科学的估计方法&#xff0c;建立项目历史数据积…

JVM之GC常见的垃圾回收器

收集器适用区域特点适用场景Serial新生代单线程&#xff0c;STW&#xff08;Stop-The-World&#xff09;客户端小应用Parallel Scavenge新生代多线程&#xff0c;吞吐量优先后台计算任务ParNew新生代Serial 的多线程版配合 CMS 使用CMS老年代并发标记&#xff0c;低延迟响应优先…

免费私有化部署! PawSQL社区版,超越EverSQL的企业级SQL优化工具面向个人开发者开放使用了

1. 概览 1.1 快速了解 PawSQL PawSQL是专注于数据库性能优化的企业级工具&#xff0c;解决方案覆盖SQL开发、测试、运维的整个流程&#xff0c;提供智能SQL审核、查询重写优化及自动化巡检功能&#xff0c;支持MySQL、PostgreSQL、Oracle、SQL Server等主流数据库及达梦、金仓…

HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析

目录 引言 一、协议特性深度对比 1.1 协议工作模型差异 1.2 隧道代理适配难点 二、兼容性架构设计 2.1 双协议接入层设计 2.2 统一隧道内核 三、关键技术实现 3.1 协议转换引擎 3.1.1 HTTP→SOCKS5转换 3.1.2 SOCKS5→HTTP转换 3.2 连接管理策略 3.2.1 智能连接池 …

3DGS——基础知识学习笔记

1.什么是3D高斯泼溅&#xff08;3D Gaussian Splatting&#xff09;&#xff1f; 目标&#xff1a;从一组稀疏的3D点&#xff08;比如通过相机或激光雷达采集的点云&#xff09;重建出高质量的3D场景&#xff0c;并支持实时渲染。 核心思想&#xff1a;用许多“3D高斯分布”&…