React-native-snap-carousel: Substituir FlatList por outro componente?

Criado em 22 jan. 2018  ·  28Comentários  ·  Fonte: meliorence/react-native-snap-carousel

O componente FlatList é muito problemático, ponto final.

Esses plug-ins podem constituir uma substituição interessante:

enhancement help wanted

Comentários muito úteis

Obrigado pelo aviso @PublicParadise!

FlatList nunca para de surpreender ... Parece que um InteractionManager pode estar sendo executado em algum lugar, adiando assim a execução da lógica do componente.

Definitivamente, é hora de se livrar de FlatList para sempre :-)

Todos 28 comentários

Duas desvantagens principais:

  • O primeiro estende ScrollView .
  • O segundo é um plugin nativo, mas não implementa os recursos ausentes de FlatList que melhorariam muito o carrossel (duração da rolagem, retorno de rolagem da rolagem ...).

Francamente, acho FlatList inutilizável. Minha solução alternativa para react-native-snap-carousel (que adoro BTW) é definir initialNumToRender para data.length . Essa é a única maneira de obter uma versão sem erros.
Este é um snippet do meu script pós-instalação:

# Stupid bug in flat list.
# <strong i="11">@see</strong> comment in ListCarousel.tsx
sed -i.bak -e "s/initialNumToRender={initialNumToRender}/initialNumToRender={data.length}/" node_modules/react-native-snap-carousel/src/carousel/Carousel.js

Agora, seria bom se react-native-snap-carousel suportasse um recurso que me permitisse definir initialNumToRender de fora para que eu não tivesse que corrigir Carousel.js mais.
Eu também argumentaria que Carousel.js pode querer definir initialNumToRender para data.length por padrão se o número esperado de itens for inferior a 100 (provavelmente 90% de todos os casos de uso).

Das duas bibliotecas que você encontrou acima, acho react-native-largelist muito intrigante. Seria possível contornar os recursos ausentes ou talvez convencer o autor a adicioná-los?

Ei @PublicParadise ,

Bem, initialNumToRender faz parte dos adereços substituíveis, então você deve ser capaz de usar <Carousel initialNumToRender={data.length} /> sem a necessidade de um patch ;-) Posso garantir que funciona, já que experimentei em # 235.

Mas se você tiver que fazer isso e, portanto, está pronto para esquecer as otimizações de desempenho que deveriam vir com FlatList , eu recomendaria apenas definir useScrollView para true . Recentemente, apresentei esse prop com esse tipo de caso de uso em mente e para ignorar completamente o FlatList bugs. Além disso, permite a introdução de recursos incríveis como este : p

Em relação aos dois plug-ins que estou considerando, primeiro preciso executar muitos testes. Definitivamente ajudaria se pudéssemos convencer o autor de react-native-largelist a implementar os recursos ausentes, mas necessários!

Observe que, no momento, não me sinto confiante em basear meu próprio plugin em um nativo, já que não seria capaz de mantê-lo se o autor parasse de fazê-lo (embora eu não tivesse nenhum problema em assumir um JS).

Olá @ bd-arc,

Obrigado pelas dicas. Para ser honesto, fiquei tão frustrado com FlatList que fiz o hack e nunca mais toquei no componente. Naquela época, initialNumToRender não era um prop substituível e useScrollView parece ainda melhor.

Parece que FlatList tem alguma dependência estranha de Animated . É provavelmente aí que a maioria das pessoas tem problemas. Apenas 6 dias atrás, alguém apresentou um novo bug sobre isso.

Eu também estava pensando em substituir FlatList e fiz algumas pesquisas. Janelas de listas e renderização do que está à vista não parecem ser considerados um problema difícil. Eu gostei mais das soluções RxJS / most.js.

Você teve alguma sorte ao implementar uma dessas duas soluções como uma substituição?

Não, eu só fiz a pesquisa. Naquela época, eu ainda esperava que eles consertassem FlatList .
Deixe-me compartilhar alguns links de minha pesquisa:

Mas tenho a sensação de que o plugin nativo ( react-native-largelist ) é o caminho certo a seguir.

Obrigado por compartilhar sua pesquisa 👍

Para ser honesto, não tenho tempo agora para colocar tudo isso à prova. Se você quiser mergulhar em react-native-largelist , isso seria de grande ajuda. Se não, vamos nos manter informados ;-)

Atualização: enquanto procurava esses links, percebi que Tal Kol de wix.com tem um blog do Medium realmente bom. Até agora, gosto de todos os seus artigos. Este também pode ser relevante para nossa discussão:

@ bd-arc Mesmo aqui, tenho um trabalho diurno bastante exigente e meu tempo e recursos são limitados.
Eu posso olhar para BindingListView . Mas sim: vamos nos manter informados :)

Sim, Tal Kol escreveu alguns artigos de alta qualidade sobre React Native e otimização de desempenho.

Além disso, eu estava particularmente interessado no plugin do Wix react-native-interactable , mas infelizmente eles não tiveram tempo recentemente para resolver alguns problemas incômodos.

@ bd-arc Qual é o problema de recyclerlistview estender ScrollView ? Tanto large-list quanto FlatList constroem sobre o mesmo.
Eu escrevi recyclerlistview e recentemente minha equipe usou esse componente carrossel. Trocamos FlatList por recyclerlistview e funciona muito bem.

Ei @naqvitalha , obrigado por brilhar!

Da minha experiência, e até agora, tudo baseado em ScrollView mostra limitações de desempenho quando há um grande número de itens para lidar e / ou limitações de recursos. Mas fique tranquilo, pois meu objetivo é provar que estou errado ;-)

Você estaria interessado em enviar um PR para esta evolução para que ela possa ser ampla e exaustivamente testada?

@ bd-arc Claro. Deixe-me fazer isso.

@naqvitalha @ bd-arc Alguma atualização de status com o PR para substituir flatlist por recyclerlistview ? Eu adoraria usar isso

Não relacionado a ScrollView FlatList e recyclerlistview , mas alguém já investigou como o manipulador de gestos react-native pode ser capaz de melhorar esta lib?

Dos documentos:

Com esta biblioteca, os gestos não são mais controlados pelo sistema respondedor JS, mas, em vez disso, são reconhecidos e rastreados no encadeamento da IU. Ele torna as interações de toque e o rastreamento de gestos não apenas suaves, mas também confiáveis ​​e deterministas.

Requer react-native link , o que é lamentável em termos de manter esta dependência lib livre. Mas agora está incluído na Expo / CRNA.

Ei @ pcooney10 ,

Já considerei a implementação de um PanResponder em cima de ScrollView / FlatList one (como você pode ver em # 40).

Você tentou algo semelhante com react-native-gesture-handler ? Adoraria receber algum feedback para determinar se esta é uma ideia legítima ou um caminho direto para a loucura

@amitassaraf Os contratos desse componente são muito semelhantes ao FlatList, pois os adereços são transmitidos. Para provedor de layout RLV é obrigatório. Será uma mudança significativa ou precisaremos introduzir um novo modo.

Olá a todos, gostaria de compartilhar um pouco da minha experiência no uso deste componente. Eu precisava usá-lo dentro de ScrollView que gerou o problema de que todos os itens serão mostrados por mais do que você indicaria na propriedade removeClippedSubviews os elementos não são deletados da memória, caso contrário, cada caminho criou novos elementos que fazem com que o aplicativo drene a memória RAM no Android. Para obter uma operação correta da lista em ScrollView ( ou outra lista ), use as seguintes FlatList propriedades.

maxToRenderPerBatch={4}

initialNumToRender={4}

windowSize={4}

removeClippedSubviews={Platform.OS != 'ios'}

Dependendo do seu caso, você pode configurar os valores que melhor atendem às suas necessidades. desta forma, você terá o desempenho esperado com quase nenhum vazamento de memória

@ machester4 Obrigado por compartilhar suas descobertas! Esses valores não cabem no caso de uso de todos, mas a abordagem é sólida ;-)

Você pode aplicar essa lógica às suas listas horizontais que estão dentro de uma lista vertical. no meu caso, todas as minhas listas horizontais têm 3 elementos visíveis de cada vez. por isso os valores são maxToRenderPerBatch e initialNumToRender estão em 4 que é onde obtenho uma melhor experiência para o usuário.

@naqvitalha Você poderia compartilhar como substituiu FlatList pelo RecylerView dentro do carrossel? Além disso, você oferece suporte a algo como https://github.com/facebook/react-native/issues/20500 no RecyclerView?

@ bd-arc Atenção, tenho certeza que isso afetará react-native-snap-carousel clientes:
https://github.com/facebook/react-native/issues/21070

Obrigado pelo aviso @PublicParadise!

FlatList nunca para de surpreender ... Parece que um InteractionManager pode estar sendo executado em algum lugar, adiando assim a execução da lógica do componente.

Definitivamente, é hora de se livrar de FlatList para sempre :-)

Olá, alguma atualização neste campo até agora?

Na verdade, FlatList na minha opinião tem o que é preciso para se tornar um ótimo componente de lista.
Tudo o que falta é o conceito de "altura estimada da linha" que UITableView tem no iOS.
Portanto, você NÃO precisa de uma propriedade para "quantas linhas devo fazer o layout de forma assíncrona para fazer alguns truques e truques".

Tudo o que precisamos é, como eu disse, um estimatedRowHeight (possivelmente com retorno de chamada para permitir diferentes estimativas por linha, mas ainda estimativas!).

  • Isso será usado para calcular o tamanho do conteúdo da visualização de rolagem.
  • Rolar para um deslocamento irá rolar diretamente para ele.
  • Sempre que você renderizar linhas - armazene em cache seus tamanhos após serem dispostos.
  • Use tamanhos em cache + alturas estimadas de linha para calcular rapidamente o deslocamento para um item ou o item para um deslocamento.
  • Também não podemos considerar estimativas / caches para todas as linhas antes de um índice de item muito alto, apenas use algum tipo de tamanho de janela e uma estimativa média para o resto.

Portanto, o tamanho do conteúdo mudará dinamicamente, mas ninguém se importará ou sentirá, pois você pode rolar para o último item ou qualquer outro índice e ele chegará lá sem falhas, e você não estará fazendo tanto trabalho que terá itens ausentes durante a rolagem.

Olá @naqvitalha , Você tem algum ramo ou PR prestes a migrar a lista plana para RLV para este componente? Será muito útil para mim. Obrigado.

Obrigado por experimentar meu componente.

Para quase todas as cenas, você deve fazer assim:

<Carousel  containerCustomStyle={{flex:1}} contentContainerCustomStyle={{flex:1}} renderItem={()=><LargeList ...props/>}/>

E certifique-se de que todos os pais do Carrossel contenham o estilo { flex: 1 }.

Preste atenção a esta dica:

LargeList default has a {flex:1} style,please be sure its parent has a bounded height.

LargeList não pode funcionar bem se você quiser que seus itens aumentem o tamanho de LargeList. Você deve confirmar se o tamanho de LargeList é herdado de seu pai ou de uma altura limitada.

Perdoe-me pelo meu inglês de piscina, se você entende chinês. Verifique este problema

O componente FlatList é muito problemático, ponto final.

Esses plug-ins podem constituir uma substituição interessante:

* https://github.com/Flipkart/recyclerlistview

* https://github.com/bolan9999/react-native-largelist

bem dito

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Dr1992 picture Dr1992  ·  4Comentários

ajonno picture ajonno  ·  4Comentários

sujitpk-perennial picture sujitpk-perennial  ·  3Comentários

naffiq picture naffiq  ·  5Comentários

KarlosQ picture KarlosQ  ·  4Comentários