首页 > 解决方案 > 具有大量图像的视图的 React Native 渲染性能

问题描述

我正在尝试使用 React Native,并且必须渲染一个看似不复杂的页面,其中包含多个水平的 FlatLists 图像。

看起来像这样:

render() {
    return (
        <View>
            <CustomImagesFlatListView data={data1} />
            <CustomImagesFlatListView data={data2} />
            <SomeOtherComponent />
            <CustomImagesFlatListView data={data3} />
        </View>
    );
}

但是我注意到,每当该页面(组件)被挂载(或为此而加载)时,在组件完全呈现并且 UI 变得正常运行之前,都会出现非常明显的屏幕冻结。

是否有什么我遗漏/做错的事情,或者这是可以预料的。总共至少有 50 张以上的图像(从网络加载),但使用 FlatList 应该是延迟加载的,所以这种性能滞后是很奇怪的。

标签: reactjsreact-nativemobile

解决方案


你可以通过不同的方式提高你的表现。

  1. 首先,您可以使用带有 https://github.com/kfiroo/react-native-cached-image的缓存图像(如果图像 url 有参数,请不要忘记添加长 ttl 和 useQueryParamsInCacheKey)
  2. 如果您知道图像尺寸或者您在 FlatList 中显示一些内部带有图像的视图(并且视图始终具有相同的大小),您可以使用getItemLayout提高性能
  3. 在 FlatLists中使用initialNumToRender
  4. 你检查过性能页面吗?也许 JS 线程是“满的”,应用程序必须执行多个操作。您可以使用InteractionManagerrequestAnimationFrame来提高性能。

我在我的 React Native 应用程序中创建了一个 ThreadHelper,性能比以前更好(快 90%)。这是代码:

import {InteractionManager } from 'react-native';

export default class ThreadHelper{

    /**
    * Promise resolved as soon as the requestAnimationFrame goes on
    */
    nextFrame(){
        return new Promise((resolve, reject) => {
                requestAnimationFrame(() => {
                LOG.debug("ThreadHelper :: requestAnimationFrame");
                resolve();
            }); 
        })
    }


    runWhenThreadIsReady(callback){
        InteractionManager.runAfterInteractions(async () => {
            LOG.debug("ThreadHelper :: runAfterInteractions...");
            await this.nextFrame();
            callback();
        });
    }
}

您可以在组件中导入 ThreadHelper,并且在检索图像时可以调用:

this.threadHelper.runWhenThreadIsReady(() => {
   //your code here
   //For example getImagesFromEndpoint and then this.setState({images:Array});
});

在我的应用程序中,我有多个图像库,每个图像库有 100 多张图像,我可以快速显示它们。用户可以与页面交互而不会被阻止。


推荐阅读