Snelle lijsten in React Native zonder omwerkoplossingen voor afmetingen of native modules
Als je ooit een complexe interface in React Native hebt gebouwd, heb je waarschijnlijk gevloekt bij lijsten. De standaard FlatList begint FPS te verliezen bij lange lijsten en verstopt het geheugen. FlashList van Shopify is merkbaar sneller dankzij componenthergebruik, maar probeer het eens te voeden met elementen met onvoorspelbare hoogte zoals berichten met variërende hoeveelheden tekst en afbeeldingen. Micro-freezes tijdens snel scrollen of layout-trillingen beginnen wanneer de lijst celgroottes probeert te raden via estimatedItemSize.
Onlangs heeft het LegendApp-team de Legend List bibliotheek uitgebracht. Het is een lijstcomponent volledig geschreven in TypeScript, zonder een enkele regel native code, die dit dynamische dimensioneringsprobleem precies oplost.
Het Concept
Het hoofddoel van het project is om een vervanging te bieden voor FlatList en FlashList met een vertrouwde API, maar zonder prestatieverminderingen bij elementen met variabele hoogte. De ontwikkelaars hebben bewust alleen puur JavaScript en TypeScript gebruikt. Er hoeven geen native modules te worden gelinkt. Dit vereenvoudigt het bouwen voor Expo Go en webversies, en vermindert ook het risico om iets te breken bij het updaten van de React Native-versie.
Het project is lichtgewicht en werkt als een drop-in vervanging. Als je al een scherm hebt geschreven met FlatList, vereist een basale migratie alleen het wijzigen van de import en componentnaam.
Wat de Bibliotheek Kan Doen
De ontwikkelaars richtten zich op typische problemen met lijsten in mobiele apps. Hier zijn vier dingen die hier merkbaar handiger zijn:
Dynamische hoogte out of the box. Je hoeft geen exacte kaartafmetingen vooraf te berekenen of geschatte waarden door te geven. De lijst past zich vanzelf aan aan inhoudsgroottes zonder rendervertraging.
Correcte chatinterface. De klassieke truc voor het maken van een messengerscherm is om de lijst om te draaien via
inverted. Dit veroorzaakt vervelende bugs met toetsenbordanimaties, omgekeerd scrollen en positionering. Legend List heeft eenalignItemsAtEndprop die inhoud uitlijnt op de onderrand zonder omkering, enmaintainScrollAtEnddat de scroll bij het laatste bericht houdt wanneer nieuwe gegevens binnenkomen.Bidirectioneel oneindig scrollen. Gegevens laden omhoog en omlaag werkt zonder witte schermflitsen en abrupte sprongen in viewportpositie.
Gecontroleerde celrecycling. Via de
recycleItemsprop kun je componenthergebruik in- of uitschakelen. Als een complexe lokaleuseStateis opgeslagen binnen een lijstelement, leidt hergebruik soms tot onaangename neveneffecten met het weergeven van iemand anders zijn staat. In Legend List is recycling standaard uitgeschakeld voor veiligheid, maar je kunt het inschakelen met één regel voor maximale snelheid.
Hoe Het Er Uitziet in Code
Installatie is standaard:
npm install @legendapp/list
# или через bun / yarn
bun add @legendapp/list
We importeren de component uit de runtime subfolder en geven vertrouwde props:
import React, { useRef } from "react"
import { View, Image, Text, StyleSheet } from "react-native"
import { LegendList, LegendListRef, LegendListRenderItemProps } from "@legendapp/list/react-native"
interface PostItem {
id: string
author: string
content: string
photoUrl?: string
}
export const FeedScreen = ({ posts }: { posts: PostItem[] }) => {
const listRef = useRef<LegendListRef | null>(null)
const renderItem = ({ item }: LegendListRenderItemProps<PostItem>) => {
return (
<View style={styles.card}>
<Text style={styles.author}>{item.author}</Text>
<Text style={styles.text}>{item.content}</Text>
{item.photoUrl && (
<Image source={{ uri: item.photoUrl }} style={styles.image} />
)}
</View>
)
}
return (
<LegendList
data={posts}
renderItem={renderItem}
keyExtractor={(item) => item.id}
recycleItems={true}
maintainVisibleContentPosition
ref={listRef}
/>
)
}
const styles = StyleSheet.create({
card: { padding: 16, borderBottomWidth: 1, borderColor: "#eee" },
author: { fontWeight: "bold", marginBottom: 4 },
text: { fontSize: 14, lineHeight: 20 },
image: { width: "100%", height: 200, marginTop: 8, borderRadius: 8 },
})
De maintainVisibleContentPosition prop houdt inhoud op het scherm als elementafmetingen boven het zichtbare gebied veranderen of nieuwe gegevens binnenkomen.
Beperkingen en Plannen
De repository is jong, hij verscheen eind 2024. In de roadmap geven de auteurs openlijk aan wat er nog niet is:
- Masonry-rasters (tegels van variërende hoogtes)
- Sticky headers
- Kolomoverspanningen
- Afzonderlijke itemtypes (
getItemType)
Als je scherm afhankelijk is van een complex raster met sticky secties, is het te vroeg om te migreren.
Voor Wie Het De Moeite Waard Is Om Te Proberen
De bibliotheek is nuttig voor wie moe is van het vechten tegen interface-sprongen in chats, nieuwsfeeds of reactielijsten. Als FlashList trilt op je dynamische kaarten en FlatList niet de soepelheid biedt die je nodig hebt, installeer @legendapp/list in een testbranch. Het kost maar een paar minuten om te controleren aangezien je de componentstructuur niet hoeft te wijzigen of native wrappers hoeft te schrijven.
Gerelateerde projecten