调查组件重新渲染问题
在React中,导致重新渲染发生的原因包括组件状态或属性的变化、中心化状态的更新,或者由于父组件重新渲染而触发所有子组件的重新渲染。
虽然重新渲染对于向用户反映最新信息至关重要,但过度和不必要的重新渲染会显著影响应用的性能和用户界面 (UI) 流畅度(UI的顺畅程度和响应速度)。
要调查Vega应用的重新渲染问题,可以借助why-did-you-render工具来识别不必要的重新渲染。
本页提供了在调查Vega应用的重新渲染问题时,设置和使用why-did-you-render的步骤。
设置why-did-you-render
why-did-you-render,因为这会导致React运行速度变慢。要了解详情,请阅读why-did-you-render文档(仅提供英文版)。步骤1: 在您的应用项目中安装why-did-you-render
npm install @welldone-software/why-did-you-render@8.0.3 --save-dev
安装why-did-you-render可以为您的项目增加一款至关重要的调试工具,有助于识别React组件中不必要的重新渲染,从而优化应用的性能。
运行该命令后,您应该可以看到在devDependencies部分下方,why-did-you-render程序包已添加到您的package.json文件。程序包文件会添加到项目目录中的node_modules文件夹。
步骤2: 在应用的babel.config.js中添加why-did-you-render插件
将以下配置添加到应用的babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
env: {
development: {
plugins: [['@babel/plugin-transform-react-jsx', { runtime: 'classic' }]],
},
},
}
此配置可确保与why-did-you-render程序包兼容。
步骤3: 创建wdyr.tsx文件
/// <reference types="@welldone-software/why-did-you-render" />
import React from "react";
if (process.env.NODE_ENV === "development") {
const whyDidYouRender = require("@welldone-software/why-did-you-render");
whyDidYouRender(React, {
trackAllPureComponents: true,
});
}
通过创建wdyr.tsx文件,您可以为why-did-you-render设置中央配置,从而能够初始化具有特定设置的库,并控制其在整个应用中的行为。
wdyr.tsx文件是用于配置why-did-you-render跟踪行为的入口文件。
trackAllPureComponents配置仅支持跟踪React纯组件。
要跟踪应用代码中的其他组件,请将组件的whyDidYouRender设置为true。
示例:
const MyCustomComponent = (props) => (
<div>
My Custom Component
</div>
);
MyCustomComponent.whyDidYouRender = true;
export default MyCustomComponent;
要详细了解组件跟踪和其他可用选项,请阅读why-did-you-render文档(仅提供英文版)。
步骤4: 将wdtr.tsx导入到应用的index.js中
import './wdyr';
import { AppRegistry, LogBox } from 'react-native';
import App from './src/Home';
import { name as appName } from './app.json';
// 其他应用代码
AppRegistry.registerComponent(appName, () => App);
通过将wdtr.tsx导入到应用的index.js文件中,您可以确保why-did-you-render能够正确设置其挂钩,以跟踪整个应用中的组件渲染。
步骤5: 在Debug(调试)模式下运行您的应用,然后检查why-did-you-render日志
- 在调试模式下运行您的应用。有关说明,请参阅设置和使用Vega Studio。
- 在应用中执行滚动浏览等操作。
- 检查出现在应用日志中的
why-did-you-render日志。要查看应用日志,请参阅查看日志。 - 分析重新渲染的组件进行渲染的原因。
- 修复潜在的根本原因,以消除不必要的重新渲染。
why-did-you-render日志输出示例
(NOBRIDGE) GROUP SpatialNavigationVirtualizedList
(NOBRIDGE) LOG {"SpatialNavigationVirtualizedList": [Function anonymous]} Re-rendered because of props changes:
(NOBRIDGE) GROUP props.renderItem
(NOBRIDGE) LOG different functions with the same name. (more info at http://bit.ly/wdyr02)
(NOBRIDGE) LOG {"prev renderItem": [Function renderItem]} !== {"next renderItem": [Function renderItem]}
(NOBRIDGE) GROUP Rendered by Grid
(NOBRIDGE) LOG {"Grid": [Function Grid]} Re-rendered because of hook changes:
(NOBRIDGE) GROUP [hook useState result]
(NOBRIDGE) LOG different objects. (more info at http://bit.ly/wdyr3)
(NOBRIDGE) LOG {"prev ": ""} !== {"next ": "不必要的状态更新!"}
(NOBRIDGE) GROUP SpatialNavigationVirtualizedList
(NOBRIDGE) LOG {"SpatialNavigationVirtualizedList": [Function anonymous]} Re-rendered because of props changes:
(NOBRIDGE) GROUP props.renderItem
(NOBRIDGE) LOG different functions with the same name. (more info at http://bit.ly/wdyr02)
(NOBRIDGE) LOG {"prev renderItem": [Function renderItem]} !== {"next renderItem": [Function renderItem]}
(NOBRIDGE) GROUP Rendered by Grid
(NOBRIDGE) LOG {"Grid": [Function Grid]} Re-rendered because of hook changes:
(NOBRIDGE) GROUP [hook useState result]
(NOBRIDGE) LOG different objects. (more info at http://bit.ly/wdyr3)
(NOBRIDGE) LOG {"prev ": ""} !== {"next ": "不必要的状态更新!"}
(NOBRIDGE) GROUP SpatialNavigationVirtualizedList
(NOBRIDGE) LOG {"SpatialNavigationVirtualizedList": [Function anonymous]} Re-rendered because of props changes:
(NOBRIDGE) GROUP props.renderItem
(NOBRIDGE) LOG different functions with the same name. (more info at http://bit.ly/wdyr02)
(NOBRIDGE) LOG {"prev renderItem": [Function renderItem]} !== {"next renderItem": [Function renderItem]}
(NOBRIDGE) GROUP Rendered by Grid
(NOBRIDGE) LOG {"Grid": [Function Grid]} Re-rendered because of hook changes:
(NOBRIDGE) GROUP [hook useState result]
(NOBRIDGE) LOG different objects. (more info at http://bit.ly/wdyr3)
(NOBRIDGE) LOG {"prev ": ""} !== {"next ": "不必要的状态更新!"}
在示例日志中可以看到,Grid组件重新渲染的原因是useEffect挂钩中发生了一次更新。
要解决Grid组件的重新渲染问题,请移除useEffect挂钩中不必要的状态更新。
useEffect(() => {
setHeaderTitle("Unnecessary State Update!");
}, []);
相关主题
Last updated: 2025年9月30日

