React为什么要有性能优化API
当更新组件树中的子组件时,需要遍历整个组件树,react每次更新都会重新创建一个组件树,当有的节点没有变化时,就出现了性能浪费,因此需要性能优化,跳过没有变化的组件
性能优化的法则
将变的部分与不变的部分分离,当父组件满足性能优化的条件时,子组件才可能命中性能优化
- props
- state
- context
- 寻找项目中的性能损耗严重的子树
- 在子树的根节点使用性能优化API
- 子树中运用变与bu'bia
react父组件刷新,子组件会刷新吗?
React中,当父组件的状态(state)或属性(props)发生变化时,父组件会重新渲染,子组件也会随之渲染。但如果子组件的props没有发生变化,子组件不会重新渲染。
性能优化背后的源码运行机制
props的浅比较
如果没有传入props,对比的props是一个空对象,因空对象的引用地址不同,所以无法命中优化策略,导致组件重复渲染。react的默认比较行为是全等比较,不容易命中,当使用了React.memo或useMemo后,会进行浅比较,比较key,value是否相同。
useMomo $ Memo
function useMemo(callback, dependencies) {
const fiber = getCurrentFiber();
const memoizedState = fiber.memoizedState;
const prevDeps = memoizedState ? memoizedState.dependencies : null;
if (prevDeps && areDependenciesEqual(prevDeps, dependencies)) {
// 依赖项未发生变化,直接返回缓存值
return memoizedState.value;
}
// 依赖项发生变化,重新计算值
const value = callback();
const newMemoizedState = { dependencies, value };
fiber.memoizedState = newMemoizedState;
return value;
}
function getCurrentFiber() {
// 获取当前正在渲染的Fiber节点
// 这个函数的实现涉及到Fiber架构和Hooks的实现细节,这里简化为直接返回全局变量
return currentFiber;
}
function areDependenciesEqual(prevDeps, newDeps) {
// 判断两个依赖项数组是否相等
// 这个函数的实现涉及到依赖项数组的比较逻辑,这里简化为直接比较数组长度和每个元素是否相等
return (
prevDeps.length === newDeps.length &&
prevDeps.every((dep, i) => dep === newDeps[i])
);
}