简体   繁体   English

对具有大量图像的视图反应本机渲染性能

[英]React Native rendering performance for views with a lot of images

I'm experimenting with React Native and have to render a seemingly not complicated page with multiple horizontal FlatLists of images. 我正在使用React Native进行实验,并且不得不渲染一个看似不复杂的页面,其中包含图像的多个水平FlatList。

Looks something like this: 看起来像这样:

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

However I noticed that whenever that page (component) gets mounted (or loaded for that matter) there is a very noticeable screen freeze before the components are fully rendered and the UI becomes functional. 但是,我注意到,每当该页面(组件)被安装(或为此加载)时,在完全呈现组件并使UI起作用之前,屏幕就会出现非常明显的冻结。

Is there something I'm missing/doing wrong or is this to be expected. 有什么我想念/做错的事吗? There is at least upwards of 50 images (loaded from the web) in total but by using FlatList it should be lazy loaded, so this lag in performance is quite strange. 总共至少有50张以上的图像(从Web加载),但是通过使用FlatList应该将其延迟加载,因此这种性能上的滞后是很奇怪的。

You can improve your performance in different ways. 您可以通过不同的方式来提高性能。

  1. First of all you can use cached images with https://github.com/kfiroo/react-native-cached-image (don't forget to add a long ttl and the useQueryParamsInCacheKey if the image url has params) 首先,您可以将缓存的图像与https://github.com/kfiroo/react-native-cached-image一起使用 (如果图像URL中包含参数,请不要忘记添加长ttl和useQueryParamsInCacheKey)
  2. If you know image dimensions or you are displaying in the FlatList some views with images inside (and the views have always the same size) you can improve performance with getItemLayout 如果您知道图像的尺寸,或者在FlatList中显示了一些带有内部图像的视图(并且这些视图始终具有相同的大小),则可以使用getItemLayout来提高性能
  3. Use initialNumToRender in your FlatLists 使用initialNumToRender在FlatLists
  4. Have you checked the performance page ? 您是否查看了性能页面 Maybe the JS thread is "full" and the app has to do multiple operations. 也许JS线程已“满”,并且该应用程序必须执行多项操作。 You can use the InteractionManager and requestAnimationFrame to improve performances. 您可以使用InteractionManagerrequestAnimationFrame来提高性能。

I have created a ThreadHelper in my React Native app and the performance are better than before (90% faster). 我在我的React Native应用程序中创建了一个ThreadHelper,性能比以前更好(提高了90%)。 Here is the code: 这是代码:

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();
        });
    }
}

You can import the ThreadHelper in your component and, when you retrieve the images you can call: 您可以在组件中导入ThreadHelper,并且在检索图像时可以调用:

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

In my app I have multiple image galleries with more than 100 images each and I can display them fast. 在我的应用程序中,我有多个图像画廊,每个画廊有100多个图像,并且可以快速显示它们。 User can interact with the page without been blocked. 用户可以与页面进行交互而不会被阻止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM