Skip to content

一、如何理解React、React Native 虚拟DOM

什么是虚拟DOM

  • 虚拟DOM是一种轻量级的JavaScript对象,他是对真实DOM的一直抽象表示。
  • 虚拟DOM的主要作用是提高UI更新效率

虚拟DOM的工作机制

  1. 初始渲染

    • 当React组件首次渲染时,React会创建一个虚拟DOM树,该树是由JavaScript对象组成的。
    • React会将虚拟DOM树转换为真实DOM树,然后将其呈现到浏览器或原生平台上。
  2. 状态更新

    • 当组件的状态或属性发生变化时,React会创建一棵新的虚拟DOM树。
    • React会将新的虚拟DOM树与之前的虚拟DOM树进行比较(这个过程称为“diffing”)。
  3. 计算差异

    • React使用一种高效的算法(diff算法)来计算新旧虚拟DOM树之间的差异。
    • 这个算法能够快速确定哪些部分发生了变化。
  4. 更新真实DOM

    • 根据计算出的差异,React会最小化地更新真实DOM,仅修改那些实际发生变化的部分。
    • 这种方式避免了不必要的DOM操作,提高了性能。

Diff算法是什么原理?Diff算法如何实现?

Diff算法的原理

1. 树的分层比较

React将虚拟DOM树分为若干层,并逐层进行比较。它假设不同层级的节点不会相互移动,因此只需比较相同层级的节点。

2. Key的使用

在比较同一层级的子节点时,React使用key属性来唯一标识每个子节点。如果子节点有key,React会首先根据key进行比较,这样可以快速定位哪些节点是相同的,哪些是新增或删除的。

3. 节点类型比较

  • 同类型节点:如果节点类型相同(例如都是<div>),React会继续比较它们的属性和子节点。
  • 不同类型节点:如果节点类型不同,React会认为它们是完全不同的节点,直接删除旧节点并创建新节点。

Diff算法的实现

以下是Diff算法的简化实现步骤:

  1. 对比根节点

    • 如果根节点类型不同,直接替换整个节点。
    • 如果根节点类型相同,继续比较属性和子节点。
  2. 对比属性

    • 比较新旧节点的属性,找出需要更新的属性。
    • 对于新增或删除的属性,进行相应的操作。
  3. 对比子节点

    • 使用key属性进行子节点的对比。
    • 如果没有key,则按顺序比较子节点。
    • 生成最小的操作集合来更新子节点,包括新增、删除和移动操作。

实际中的优化

在实际的React实现中,Diff算法会有更多的优化和处理,包括:

  1. 跳过静态子树:如果某个子树被标记为静态(例如PureComponent),则不会重复比较。
  2. 批量更新:React会将多次状态更新合并为一次批量更新,减少重绘次数。
  3. 异步更新:在React Fiber架构中,Diff算法可以分段执行,避免阻塞主线程,提高用户体验。

二、React Native 新框架做了哪些行为使性能得到优化?

React Native的新架构通过Fabric、TurboModules、新桥接层(JavaScript Interface(JSI))、Hermes JavaScript引擎和Codegen等多个方面的改进,显著提高了性能、启动时间和可维护性。

1. Fabric

Fabric是React Native的新渲染系统,旨在提高UI的性能和一致性。其主要优化包括:

1.1 异步渲染

Fabric允许React Native在多个线程上并行处理UI更新,而不是将所有任务集中在主线程上。这减少了主线程的负担,从而提高了应用的响应速度。

1.2 更高效的Reconciliation

Fabric改进了虚拟DOM的调和过程,使得UI更新更加高效。它可以更快地计算新旧虚拟DOM树之间的差异,并将这些差异应用到实际的UI上。

1.3 直接操作原生视图

Fabric通过直接操作原生视图而不是通过桥接层进行批量更新,减少了JavaScript和原生代码之间的通信开销。并优化了原生组件。

1.4 Yoga布局引擎优化

Fabric继续使用Yoga布局引擎,但对其进行了优化,使得布局计算更加高效。Yoga引擎已经被广泛应用于React Native,它基于Flexbox布局模型,能够高效地处理复杂的布局需求。

1.5 异步布局计算

Fabric支持异步布局计算,这意味着布局计算可以在后台线程中进行,而不会阻塞主线程。这种方式可以显著提高UI的响应速度,减少卡顿现象。

2. TurboModules

TurboModules是React Native的新模块系统,旨在提高模块加载和执行的性能。其主要优化包括:

2.1 延迟加载

TurboModules支持按需加载模块,而不是在应用启动时一次性加载所有模块。这减少了应用启动时间,并降低了内存消耗。

2.2 更高效的桥接

TurboModules使用新的桥接机制,减少了JavaScript和原生模块之间的通信开销。通过直接调用原生模块,避免了传统桥接层的性能瓶颈。

2.3 更好的类型安全

TurboModules使用Flow或TypeScript进行类型检查,提供更好的类型安全性和开发体验。

3. 新桥接层(New Architecture)

新的桥接层改进了JavaScript和原生代码之间的通信机制,主要优化包括:

3.1 同步通信

新的桥接层支持同步通信,使得某些操作可以立即完成,而不需要等待异步回调。这在某些情况下可以显著提高性能。

3.2 批量处理

新的桥接层可以批量处理多次通信请求,减少了JavaScript和原生代码之间的通信次数,从而提高了性能。

3.3 更好的错误处理

新的桥接层改进了错误处理机制,使得开发者可以更容易地调试和解决问题。

4. Hermes JavaScript引擎

Hermes是Facebook推出的一款轻量级JavaScript引擎,专门为React Native优化。其主要优化包括:

4.1 快速启动时间

Hermes通过预编译JavaScript字节码,减少了应用的启动时间。

4.2 更低的内存消耗

Hermes优化了内存管理,使得React Native应用在内存使用方面更加高效。

4.3 更快的执行速度

Hermes对JavaScript的执行进行了多种优化,使得React Native应用的运行速度更快。

5. Codegen

Codegen是React Native的新工具链,用于自动生成JavaScript和原生代码之间的接口。其主要优化包括:

5.1 减少手动编码

Codegen自动生成JavaScript和原生代码之间的接口,减少了手动编码的工作量和可能的错误。

5.2 提高类型安全

Codegen通过自动生成类型安全的接口,确保JavaScript和原生代码之间的通信更加可靠。

三、如何对React Native 进行性能监测?

在React Native开发过程中,性能监测是确保应用流畅运行的关键。以下是一些常用的方法和工具,可以帮助你有效地监测和优化React Native应用的性能:

1. 使用内置工具

1.1 Profiler

React Native自带的Profiler工具,可以帮助你测量组件的渲染时间。使用方法如下:

  • 在React DevTools中,选择需要分析的组件。
  • 启动Profiler,进行一段时间的用户交互或操作。
  • 停止Profiler,查看各个组件的渲染时间和调用堆栈。

1.2 Performance Monitor

React Native的Performance Monitor提供实时的FPS(帧率)和JS线程的使用情况。可以通过摇动设备或在模拟器菜单中启用。

2. 使用第三方工具

2.1 Flipper

Flipper是Facebook发布的一款调试工具,支持React Native应用。通过Flipper,你可以:

  • 查看和分析网络请求。
  • 检查和管理应用的数据库。
  • 查看应用的布局和层次结构。
  • 使用插件扩展功能,例如性能监控插件。

2.2 Reactotron

Reactotron是一个强大的调试工具,支持React和React Native。它可以:

  • 监控应用的状态变化。
  • 查看API请求和响应。
  • 跟踪性能问题。

3. 使用性能分析库

3.1 Reanimated

Reanimated是一个高性能的动画库,提供了更高效的动画处理机制,可以减少主线程的负担,从而提升UI的流畅度。

3.2 React Native Performance

这是一个轻量级的性能监控库,提供了简单易用的API来测量和记录应用的性能指标,例如启动时间、渲染时间等。

4. 手动性能优化

4.1 应用分区

将应用分为多个小模块,减少单个模块的复杂度,从而提高每个模块的性能。

4.2 避免不必要的渲染

使用shouldComponentUpdateReact.memo来避免不必要的组件重渲染。

4.3 优化列表渲染

使用FlatList或SectionList来处理长列表,避免使用ScrollView渲染大量数据。

4.4 减少JS线程负担

将耗时的操作移到后台线程,使用库如react-native-worker来处理复杂计算。

5. 监控和日志记录

5.1 Sentry

Sentry是一个错误监控工具,可以捕捉应用中的异常和性能问题,提供详细的堆栈信息和上下文数据。

5.2 Firebase Performance Monitoring

Firebase提供了性能监控服务,可以帮助你跟踪应用的启动时间、HTTP请求时间等关键性能指标。

通过结合以上方法和工具,你可以全面地监测和优化React Native应用的性能,确保用户获得最佳的使用体验。

四、新React Native 框架,我们可以做哪些性能优化?

在使用新React Native框架进行开发时,性能优化是确保应用流畅运行的关键。以下是一些常见的性能优化策略:

  1. 减少组件重渲染

    • 使用PureComponent: 避免不必要的重渲染。PureComponent 只会在 props 或 state 发生变化时重新渲染。
    • 使用React.memo: 对于函数组件,使用 React.memo 可以达到类似的效果。
  2. 优化列表渲染

    • 使用FlatList或SectionList: 这些组件比 ScrollView 更高效,因为它们只渲染屏幕上可见的元素。
    • 优化keyExtractor: 确保列表项有唯一的键,以便 React 能够高效地管理组件的更新。
  3. 避免匿名函数和内联函数

    • 在 render 方法中避免使用匿名函数和内联函数,因为每次 render 都会生成新的函数引用,导致不必要的重渲染。
  4. 使用Reanimated和Gesture Handler

    • React Native Reanimated 和 React Native Gesture Handler 是高性能的动画和手势处理库,可以替代传统的 Animated 和 PanResponder,以提高性能。
  5. 减少JavaScript和Native之间的桥接开销

    • 尽量减少 JavaScript 和原生代码之间的通信次数,因为频繁的桥接会带来性能开销。可以通过批量处理数据或减少通信频率来优化。
  6. 代码拆分和懒加载

    • 使用动态 import 来实现代码拆分,只有在需要时才加载特定模块,从而减少初始加载时间。
  7. 优化图片处理

    • 使用合适的图片格式和分辨率,尽量使用本地缓存。
    • 使用 react-native-fast-image 这样的库来优化图片加载和缓存。
  8. 减少不必要的库和依赖

    • 定期审查项目中的库和依赖,移除不再使用的或性能不佳的库。
  9. 调优打包过程

    • 使用 Metro bundler 的优化选项,如启用压缩和混淆。
    • 使用 Hermes 引擎来加快 JavaScript 的执行速度。
  10. 性能监控和调试

    • 使用 React DevTools 和 React Native Debugger 来分析和优化性能瓶颈。
    • 使用 profiling 工具来监控应用的性能,如 Flipper。

RN底层框架都做了哪些优化。

1.VirtualizedList: 是 React Native 中最复杂、最灵活的列表组件,无cell复用,内存占用大,滚动时动态计算布局、渲染,容易白屏;改原生渲染
2.Image组件优化 :支持webp
3.优化白屏:JSBundle分包,Base JSBundle预加载,业务JSBundle预加载 离线方案
4.提供WebGL、Canvas图形渲染能力
5.底层代码修改用于完成:
---1.RN页面和小程序接口隔离
---2.JS代码错误上报
---3.权限校验,可配置权限
---4.各种耗时统计&上报:加载耗时、成功率、错误统计、下载错误码统计、js异常统计、白屏监控
---5.扩展组件和api
6.解决一些崩溃内存泄漏

世界很美 而你正好有空