React Native:使用 useCallback 优化平面列表渲染项
React Native: optimizing flatlist render item with useCallback
我试图找出尽可能多的方法来优化平面列表,因为我的平面列表组件抱怨我的平面列表项渲染时间太长(我已经在使用 removeClippedSubviews、windowSize、maxToRenderPerBatch、React.memo 等.).
用 useCallback 包装渲染函数是个好主意吗?
例如,假设我的函数组件最初是这样的:
const FlatListItem = ({ color1, color2, color3, color4 }) => {
function renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
return (
<View>
{renderViewWithColorLogic(color1)}
{renderViewWithColorLogic(color2)}
{renderViewWithColorLogic(color3)}
{renderViewWithColorLogic(color4)}
</View>
);
};
如果我用 useCallback 包装渲染函数为:
const FlatListItem = ({ color1, color2, color3, color4 }) => {
function _renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
const renderViewWithColorLogic1 = useCallback(()=>_renderViewWithColorLogic(color1), [color1])
const renderViewWithColorLogic2 = useCallback(()=>_renderViewWithColorLogic(color2), [color2])
const renderViewWithColorLogic3 = useCallback(()=>_renderViewWithColorLogic(color3), [color3])
const renderViewWithColorLogic4 = useCallback(()=>_renderViewWithColorLogic(color4), [color4])
return (
<View>
{renderViewWithColorLogic1()}
{renderViewWithColorLogic2()}
{renderViewWithColorLogic3()}
{renderViewWithColorLogic4()}
</View>
);
};
它会提高平面列表的性能吗?
任何其他优化平面列表的建议也将不胜感激。
就 Andres 所说,我认为通过一些计算实现平面列表项组件的更好方法如下:
const FlatListItem = ({ color1, color2, color3, color4 }) => (
const viewWithColorLogic1 = useMemo(()=>_renderViewWithColorLogic(color1), [color1]);
const viewWithColorLogic2 = useMemo(()=>_renderViewWithColorLogic(color2), [color2]);
const viewWithColorLogic3 = useMemo(()=>_renderViewWithColorLogic(color3), [color3]);
const viewWithColorLogic4 = useMemo(()=>_renderViewWithColorLogic(color4), [color4]);
return (
<View>
{viewWithColorLogic1}
{viewWithColorLogic2}
{viewWithColorLogic3}
{viewWithColorLogic4}
</View>
);
);
function renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
useCallback()
hook 只是在你需要将它作为 prop 传递给某些 memoized/pure 组件时保留相同的回调引用。如果您只是在每个渲染器上调用函数 - 没有必要用 useCallback()
.
包装它
如果这个函数不依赖于其他属性然后颜色,你可以从你的组件中提取它并避免在每次渲染时创建函数:
const FlatListItem = ({ color1, color2, color3, color4 }) => (
<View>
{renderViewWithColorLogic(color1)}
{renderViewWithColorLogic(color2)}
{renderViewWithColorLogic(color3)}
{renderViewWithColorLogic(color4)}
</View>
);
function renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
如果您的函数中有一些繁重的计算,最好使用 useMemo()
来记忆结果:
const FlatListItem = ({ color1, color2, color3, color4 }) => {
const viewWithColorLogic1 = useMemo(()=>_renderViewWithColorLogic(color1), [color1]);
const viewWithColorLogic2 = useMemo(()=>_renderViewWithColorLogic(color2), [color2]);
const viewWithColorLogic3 = useMemo(()=>_renderViewWithColorLogic(color3), [color3]);
const viewWithColorLogic4 = useMemo(()=>_renderViewWithColorLogic(color4), [color4]);
return (
<View>
{viewWithColorLogic1}
{viewWithColorLogic2}
{viewWithColorLogic3}
{viewWithColorLogic4}
</View>
);
};
我试图找出尽可能多的方法来优化平面列表,因为我的平面列表组件抱怨我的平面列表项渲染时间太长(我已经在使用 removeClippedSubviews、windowSize、maxToRenderPerBatch、React.memo 等.).
用 useCallback 包装渲染函数是个好主意吗?
例如,假设我的函数组件最初是这样的:
const FlatListItem = ({ color1, color2, color3, color4 }) => {
function renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
return (
<View>
{renderViewWithColorLogic(color1)}
{renderViewWithColorLogic(color2)}
{renderViewWithColorLogic(color3)}
{renderViewWithColorLogic(color4)}
</View>
);
};
如果我用 useCallback 包装渲染函数为:
const FlatListItem = ({ color1, color2, color3, color4 }) => {
function _renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
const renderViewWithColorLogic1 = useCallback(()=>_renderViewWithColorLogic(color1), [color1])
const renderViewWithColorLogic2 = useCallback(()=>_renderViewWithColorLogic(color2), [color2])
const renderViewWithColorLogic3 = useCallback(()=>_renderViewWithColorLogic(color3), [color3])
const renderViewWithColorLogic4 = useCallback(()=>_renderViewWithColorLogic(color4), [color4])
return (
<View>
{renderViewWithColorLogic1()}
{renderViewWithColorLogic2()}
{renderViewWithColorLogic3()}
{renderViewWithColorLogic4()}
</View>
);
};
它会提高平面列表的性能吗? 任何其他优化平面列表的建议也将不胜感激。
就 Andres 所说,我认为通过一些计算实现平面列表项组件的更好方法如下:
const FlatListItem = ({ color1, color2, color3, color4 }) => (
const viewWithColorLogic1 = useMemo(()=>_renderViewWithColorLogic(color1), [color1]);
const viewWithColorLogic2 = useMemo(()=>_renderViewWithColorLogic(color2), [color2]);
const viewWithColorLogic3 = useMemo(()=>_renderViewWithColorLogic(color3), [color3]);
const viewWithColorLogic4 = useMemo(()=>_renderViewWithColorLogic(color4), [color4]);
return (
<View>
{viewWithColorLogic1}
{viewWithColorLogic2}
{viewWithColorLogic3}
{viewWithColorLogic4}
</View>
);
);
function renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
useCallback()
hook 只是在你需要将它作为 prop 传递给某些 memoized/pure 组件时保留相同的回调引用。如果您只是在每个渲染器上调用函数 - 没有必要用 useCallback()
.
如果这个函数不依赖于其他属性然后颜色,你可以从你的组件中提取它并避免在每次渲染时创建函数:
const FlatListItem = ({ color1, color2, color3, color4 }) => (
<View>
{renderViewWithColorLogic(color1)}
{renderViewWithColorLogic(color2)}
{renderViewWithColorLogic(color3)}
{renderViewWithColorLogic(color4)}
</View>
);
function renderViewWithColorLogic(color) {
// do some computationally heavy process
// ...
return <View>{/* some components */}</View>;
}
如果您的函数中有一些繁重的计算,最好使用 useMemo()
来记忆结果:
const FlatListItem = ({ color1, color2, color3, color4 }) => {
const viewWithColorLogic1 = useMemo(()=>_renderViewWithColorLogic(color1), [color1]);
const viewWithColorLogic2 = useMemo(()=>_renderViewWithColorLogic(color2), [color2]);
const viewWithColorLogic3 = useMemo(()=>_renderViewWithColorLogic(color3), [color3]);
const viewWithColorLogic4 = useMemo(()=>_renderViewWithColorLogic(color4), [color4]);
return (
<View>
{viewWithColorLogic1}
{viewWithColorLogic2}
{viewWithColorLogic3}
{viewWithColorLogic4}
</View>
);
};