react-native-masked-view / masked-view

React Native Masked View Library
MIT License
960 stars 120 forks source link

Slow performance when using many masked views #179

Open iqqmuT opened 1 year ago

iqqmuT commented 1 year ago

Here is a simple app which runs very slow on Android phone:

import React from 'react';
import {ScrollView, StyleSheet, Text, View} from 'react-native';
import MaskedView from '@react-native-masked-view/masked-view';

const BOXES = 100;
const boxes = [];
for (let i = 0; i < BOXES; i++) {
  boxes.push({id: i, text: `Box ${i}`});
}

function Box({box}) {
  return (
    <View style={styles.boxContainer}>
      <MaskedView maskElement={<View style={styles.mask} />}>
        <View style={styles.box}>
          <Text style={styles.boxText}>{box.text}</Text>
        </View>
      </MaskedView>
    </View>
  );
}

export default function App() {
  return (
    <ScrollView>
      {boxes.map(box => (
        <Box key={box.id} box={box} />
      ))}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  mask: {
    flex: 1,
    backgroundColor: 'black',
  },

  boxContainer: {
    width: 250,
    height: 250,
  },

  box: {
    width: '100%',
    height: '100%',
    backgroundColor: 'lawngreen',
    borderColor: 'black',
    borderWidth: 1,
  },

  boxText: {
    fontSize: 20,
  },
});

Setting the boxContainer size affects the performance:

morris14 commented 1 year ago

+1 on this

fukemy commented 1 year ago

better using FlatList to avoid inflate all view once time

Saphirah commented 9 months ago

This is kinda expected behaviour. A Masked View needs to render what it's displaying. If you have a 500x500px Masked View, it needs to render those 500x500 pixels. It does that only once, when created, and then stores the rendering to save performance.

Now when you instantiate 100 Masked Views you are in theory rendering a 50.000x500 display. Which your smartphone obviously can not handle.

That's why you use FlatList, like Fukemy said, because flatlist creates the components on the fly, while you scroll. Which will make the MaskedViews render one by one, once you need them.

But this is basic app Optimization and has nothing to do with MaskedView's bad performance...