理解React页面渲染原理,如何优化React性能?

React JSX转换成真实DOM过程

当使用React编写应用程序时,可以使用JSX语法来描述用户界面的结构。JSX是一种类似于HTML的语法,但实际上它是一种JavaScript的扩展,用于定义React元素。React元素描述了我们想要在界面上看到的内容和结构。

在运行React应用程序时,JSX会被转换成真实的DOM元素,这个过程主要涉及以下几个步骤:

  1. JSX代码编写: 你使用JSX语法编写React组件的界面结构。JSX允许你使用类似HTML的标记来描述UI层次结构,例如:

    const element = <div>Hello, React!</div>;
    
  2. Babel转换: JSX语法并不是浏览器原生支持的,所以需要使用工具将JSX代码转换为浏览器可识别的JavaScript代码。通常会使用Babel这样的工具来进行这种转换。

    在上述示例中,JSX代码会被转换成类似以下的形式:

    const element = React.createElement("div", null, "Hello, React!");
    

    React.createElement 是一个用于创建React元素的函数,它接受标签名、属性和子元素作为参数。

  3. 创建虚拟DOM: 在转换后的JavaScript代码中,React.createElement 函数会创建一个称为虚拟DOM的JavaScript对象。虚拟DOM是React内部用来表示界面结构的一种轻量级表示形式。

  4. 虚拟DOM对比: 当状态发生变化导致界面需要更新时,React会使用虚拟DOM来比较前后两次状态的差异。这个过程被称为"协调。

  5. 生成真实DOM更新: 通过协调过程,React能够计算出哪些部分的DOM需要被更新。然后,它将针对实际需要更新的部分,生成一系列DOM操作,然后将其应用于浏览器的实际DOM上。这个过程是优化的,React会尽量最小化实际DOM操作的次数,以提高性能。

虚拟dom 与真实dom的区别

真实DOM: 真实DOM是浏览器实际生成的文档对象模型,它代表了网页的实际结构,由HTML元素组成,每个元素都有对应的属性和方法。当应用程序的状态发生变化时,直接操作真实DOM会导致浏览器进行重绘和重排,这是一种消耗性能的操作。更新真实DOM的频繁操作可能会导致性能问题,因为DOM操作是相对昂贵的操作,特别是在有大量元素需要更新时。

优点: 真实DOM是浏览器的基础,它可以完全呈现应用程序的状态,对于一些复杂的应用场景,真实DOM可能更能够准确地反映UI状态。

虚拟DOM: 虚拟DOM是一个轻量级的JavaScript对象,它是对真实DOM的抽象表示。它类似于真实DOM,但不是实际的网页结构,而是一个虚拟的副本。 当应用程序的状态发生变化时,React等库会首先在虚拟DOM上进行操作,然后通过比较前后两个虚拟DOM的差异,找出需要更新的部分,最终只会对真实DOM进行最小化的操作。

优点: 虚拟DOM的更新机制减少了对真实DOM的频繁操作,从而提高了性能。通过批量更新、合并操作等方式,可以有效减少重绘和重排的次数。

优缺点对比:

真实DOM优点:

  • 它是浏览器的基础,可以准确地呈现应用状态。
  • 适用于一些简单的应用,或者需要直接操作DOM的场景。

真实DOM 缺点:

  • 更新时性能开销大,频繁的DOM操作会导致重排和重绘。
  • 不适合大型或复杂的应用,容易导致性能问题。

虚拟DOM 优点:

  • 提供了一种优化DOM更新的方式,减少了性能开销。
  • 通过批量更新和最小化DOM操作,提高了应用的性能。

虚拟DOM 缺点:

  • 虽然减少了DOM操作,但引入了额外的内存和计算开销,需要管理虚拟DOM树。
  • 对于一些简单的应用或者性能不是关键问题的应用,引入虚拟DOM可能会过于复杂。

React中的key有什么作用?

相信在平时的开发中遇到过的警告warning: Each child in a list should have react.development.js:315 a unique "key" prop 。这就是在循环渲染的时候,如果忘记给元素加上key,浏览器给出警告。那么key到底有什么作用呢?

  • 元素识别: key 用于帮助React识别列表中各个元素的唯一性。React使用 key 来判断哪些元素是新增、删除或更新的,从而进行高效的重渲染。
  • 性能优化: 使用正确的 key 可以优化列表的更新性能。React会根据 key 判断元素是否需要重新渲染,从而避免不必要的重绘。
  • 元素复用: 如果列表中的元素没有唯一的 key,React会难以识别元素之间的差异,从而可能导致错误的元素被重用,影响应用的正确性。
  • 使用稳定的、与数据关联的 key 可以使得列表渲染的结果更加可预测。相同的数据对应相同的 key,从而更容易理解和追踪。

可以使用index作为key吗
绝大部分情况下使用 index 作为 key值,对性能没有优化。因为它可能导致性能问题和不稳定的渲染结果。

  • 性能问题: 使用索引作为 key 可能导致不必要的重绘和性能问题。当列表中的元素发生变化时,React可能会错误地认为相同索引处的元素没有变化,从而无法正确更新。

  • 列表重排序问题: 当列表中的元素发生重新排序时,如果仅仅依赖于索引作为 key,可能会导致元素混乱,不符合预期。

  • 动态添加和删除问题: 在列表中动态添加或删除元素时,使用索引作为 key 可能导致React无法准确识别新增和删除的元素,从而导致错误的渲染。

  • 不稳定的渲染结果: 使用索引作为 key 可能导致不稳定的渲染结果。不同的渲染顺序可能会导致相同的数据在不同索引处渲染,从而引起错误。

React 性能优化的手段有哪些?

  1. 使用合适的组件: 将应用划分为合适的组件,每个组件关注特定功能。避免过大的组件,因为较小的组件更新更快。

  2. 使用PureComponent和React.memo: 使用PureComponentReact.memo来避免不必要的组件重新渲染,它们会在props或state没有变化时阻止不必要的渲染。

  3. 避免不必要的渲染: 通过使用shouldComponentUpdate生命周期方法或者函数组件的React.memo来控制组件是否需要重新渲染。

  4. 列表性能优化: 对于大型列表,使用列表虚拟化库(如react-virtualizedreact-windowreact-infinite-scroll-component)来仅渲染可见部分的数据,减少渲染开销。

  5. 使用key属性: 在渲染列表时,为每个子元素提供唯一的key属性,以帮助React准确地识别变化。

  6. 异步渲染: 使用React.lazySuspense实现组件的异步加载,从而减少初始加载时的资源消耗。

  7. 使用Memoization: 在函数组件中,使用useMemouseCallback来避免不必要的函数重新计算,减少渲染开销。

  8. 使用Immutability: 使用不可变数据结构来更新状态,以帮助React检测状态变化。这可以通过展开运算符、Object.assignArray.concat等方式实现。

  9. 组件拆分和懒加载: 将大型组件拆分成更小的子组件,并使用动态导入和代码分割来实现按需加载。

  10. 使用Profiler组件: React提供的<Profiler>组件可以帮助你识别渲染性能问题,并分析组件的渲染时间和调用次数。

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

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

相关文章

maven搭建spring项目

前提 安装jdk 安装maven 安装eclipse 创建maven项目 搭建spring项目 pom.xml <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.4.RELEASE</version> </dependency&…

【java 入侵 C# 之路】1-入门

感谢 https://www.cnblogs.com/mww-NOTCOPY/p/12213373.html 百度百科 jvm对应clr java se runtime对应 .net framework&#xff0c; jdk对应 .net framework sdk&#xff0c; java对应C# .NET 是开发者平台&#xff0c;它包含开发环境、技术框架、社区论坛、服务支持等&…

学习pytorch8 土堆说卷积操作

土堆说卷积操作 官网debug torch版本只有nn 没有nn.functional代码执行结果 B站小土堆视频学习笔记 官网 https://pytorch.org/docs/stable/nn.html#convolution-layers 常用torch.nn, nn是对nn.functional的封装&#xff0c;使函数更易用。 卷积核从输入图像左上角&#xf…

Lambda表达式第二版

1、Lambda概述 Lambda表达式是JDK8开始后的一种新语法形式作用&#xff1a;简化匿名内部类的代码写法注意&#xff1a;Lambda表达式只能简化函数式 接口 的匿名内部类的写法形式 1.1、什么是函数式接口&#xff1f; 首先必须是接口、其次接口中有且仅有一个抽象方法的形式通常我…

Bito使用手册

第一步&#xff1a;输入网站 https://alpha.bito.co/bitoai/ 第二步&#xff1a;填写邮箱 第三步&#xff1a;登录邮箱&#xff0c;获取验证码 第四步&#xff1a;填写验证码 第五步&#xff1a;完成

【LeetCode-中等题】994. 腐烂的橘子

文章目录 题目方法一&#xff1a;bfs层序遍历 题目 该题值推荐用bfs&#xff0c;因为是一层一层的感染&#xff0c;而不是一条线走到底的那种&#xff0c;所以深度优先搜索不适合 方法一&#xff1a;bfs层序遍历 广度优先搜索&#xff0c;就是从起点出发&#xff0c;每次都尝…

我的Vim学习笔记(不定期更新)

2023年9月3日&#xff0c;周日上午 学到了啥就写啥&#xff0c;不定期更新 目录 字体 文件 标签页 分屏 调用系统命令 字体 设置字体大小 :set guifont字体:h字体大小 例如&#xff0c;:set guifontMonospace:h20 查询当前使用的字体和字体大小 :set guifont? 查看…

UG\NX CAM二次开发 查询工序所在的几何组TAG UF_OPER_ask_geom_group

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 查询工序所在的几何组TAG UF_OPER_ask_geom_group 效果: 代码: void MyClass::do_it() { int count=0;tag_t * objects;UF_UI_ONT_ask_selected_nodes(&count, &objects);for (in…

linux 下安装配置nexus

一、安装包获取方式 方式一 1、直接把下载好的安装包上传到服务器中 方式二 2、通过wget安装Nexus压缩包 ①、可以使用以下命令进行安装Nexus的最新版本 wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz②、也可以点击官网复制想要下载的Nexus压缩包进行安装…

【Linux系列】离线安装openjdk17的rpm包

首发博客地址 首发博客地址[1] 系列文章地址[2] 视频地址[3] 准备 RPM 包 请从官网下载&#xff1a;https://www.oracle.com/java/technologies/downloads/#java17[4] 如需不限速下载&#xff0c;请关注【程序员朱永胜】并回复 1020 获取。 安装 yum localinstall jdk-17_linux…

C++智能指针之weak_ptr(保姆级教学)

目录 C智能指针之weak_ptr 概述 作用 本文涉及的所有程序 使用说明 weak_ptr的常规操作 lock(); use_count(); expired(); reset(); shared_ptr & weak_ptr 尺寸 智能指针结构框架 常见使用问题 shared_ptr多次引用同一数据&#xff0c;会导致两次释放同一内…

没有使用sniffer dongle在windows抓包蓝牙方法分享

网上很多文章都是介绍买一个sniffer dongle来抓蓝牙数据,嫌麻烦又费钱,目前找到一个好方法,不需要sniffer就可以抓蓝牙数据过程,现分享如下: (1)在我资源附件找到相关安装包或者查看如下链接 https://learn.microsoft.com/zh-cn/windows-hardware/drivers/bluetooth/testing-bt…

【WebRTC---源码篇】(二:二)视频源VideoSourceBase

作用 这个类继承自VideoSourceInterface<webrtc::VideoFrame>模板类,并且可以处理webrtc::VideoFrame class VideoSourceBase : public VideoSourceInterface<webrtc::VideoFrame> 重要成员变量 struct SinkPair {SinkPair(VideoSinkInterface<webrtc::Vid…

【Python】批量下载页面资源

【背景】 有一些非常不错的资源网站,比如一些MP3资源网站。资源很丰富,但是每一个资源都不大,一个一个下载费时费力,想用Python快速实现可复用的批量下载程序。 【思路】 获得包含资源链接的静态页面,用beautifulsoup分析页面,获得所有MP3资源的实际地址,然后下载。…

安卓逆向 - Frida反调试绕过

本文仅供学习交流&#xff0c;只提供关键思路不会给出完整代码&#xff0c;严禁用于非法用途&#xff0c;谢绝转载&#xff0c;若有侵权请联系我删除&#xff01; 本文案例 app&#xff1a;5Lqs5LicYXBwMTEuMy4y 一、引言&#xff1a; Frida是非常优秀的一款 Hook框架&#…

MATLAB/Python编程:绘图属性的确定

注1:本文系“MATLAB/Python的编程教程”系列之一,致力于使用Python和Matlab实现特定的功能。本次要实现的功能是:绘图属性(字体、大小、坐标范围等)的确定。 文章目录 MATLAB/Python编程:绘图属性的确定Python 中的绘图安装matplotlib创建一个简单的图形设置字体与大小查看…

PlotlyJs 指定画布的宽度并页面居中

可以通过CSS样式来实现指定画布的宽度并使其在页面居中。具体方法如下&#xff1a; 在HTML文件中定义一个div&#xff0c;用来包含PlotlyJs画布。如下所示&#xff1a; <div id"plotly-div"></div>在CSS样式中指定该div的宽度和居中方式。如下所示&…

uni-app:允许字符间能自动换行(英文字符、数字等)

<template><view class"container"><!-- 这里是你的文本内容 -->{{ multilineText }}</view> </template><style> .container {word-break: break-all; } </style>例如&#xff1a; <template><view class"…

2023年全国职业院校技能大赛信息安全管理与评估网络安全事件响应、数字取证调查、应用程序安全任务书

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 任务书 模块二 网络安全事件响应、数字取证调查、应用程序安全 比赛时间及注意事项 本阶段比赛时长为180分钟&#xff0c;时间为13:30-16:30。 【注意事项】 比赛结束&#xff0c;不得关机&#xff1b;选手首先需要…

jQuery成功之路——jQuery的DOM操作简单易懂

jQuery的DOM操作 1.jQuery操作内容 jQuery操作内容 1. text() 获取或修改文本内容 类似于 dom.innerText 2. html() 获取或修改html内容 类似 dom.innerHTML 注意: 1. text() 是获取设置所有 2. html() 是获取第一个,设置所有 <!DOCTYPE html> <html lang"zh…