npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

shadowlist

v0.4.19

Published

60fps, high-performance list for React Native.

Downloads

937

Readme

shadowlist [alpha release]

ShadowList is a new alternative to FlatList for React Native, created to address common performance issues and enhance the UX when dealing with large lists of data. It invokes Yoga for precise layout measurements of Shadow Nodes and constructs a Fenwick Tree with layout metrics for efficient offset calculations. By virtualizing children and rendering only items within the visible area, ShadowList ensures optimal performance. It's built on Fabric and works with React Native version 0.75 and newer.

Out of box comparison to FlatList

| Feature | ShadowList | FlatList / FlashList | |----------------------------------|--------------|------------| | 60 FPS Scrolling | ✅ | ❌ | | No Estimated Size required | ✅ | ❌ | | No Content Flashing | ✅ | ❌ | | No Sidebar Indicator Jump | ✅ | ❌ | | Native Bidirectional List | ✅ | ❌ | | Instant initialScrollIndex | ✅ | ❌ | | Instant initialScrollIndex | ✅ | ❌ | | Nested ShadowList (ScrollView) | ✅ | ❌ | | Natively Inverted List Support | ✅ | ❌ | | Smooth Scrolling | ✅ | ❌ |

Scroll Performance

| Number of Items | ShadowList | FlatList | FlashList | |------------------|----------------------------|----------------------|----------------------| | 100 (text only) | ~~156mb memory~~ - 60fps | ~~195mb~~ (38-43fps) | ~~180mb (56fps)~~* | | 1000 (text only) | ~~187mb memory~~ - 60fps | ~~200mb~~ (33-38fps) | ~~180mb (56fps)~~* |

*FlashList is unreliable and completely breaks when scrolling, resulting in unrealistic metrics.
Given measurements show memory usage and FPS on fully loaded content, see demo here and implementation details here.

Note on Performance Considerations

ShadowList initiates ShadowNode creation for each child. This process can be slower when rendering a large number of items at once, which may impact performance compared to purely JS-based solutions. However, once the children are measured, it performs real-time virtualization ensuring smooth, flicker-free scrolling.

One temporary way to mitigate this is by implementing list pagination until the following problem is addressed.

Installation

  • CLI: Add the package to your project via yarn add shadowlist and run pod install in the ios directory.
  • Expo: Add the package to your project via npx expo install shadowlist and run npx expo prebuild in the root directory.

Usage

import {Shadowlist} from 'shadowlist';

<Shadowlist
  contentContainerStyle={styles.container}
  ref={shadowListContainerRef}
  data={data}
  ListHeaderComponent={ListHeaderComponent}
  ListHeaderComponentStyle={styles.ListHeaderComponentStyle}
  ListFooterComponent={ListFooterComponent}
  ListHeaderComponentStyle={styles.ListFooterComponentStyle}
  ListEmptyComponent={ListEmptyComponent}
  ListEmptyComponentStyle={styles.ListFooterComponentStyle}
  renderItem={({ item, index }) => (
    <CustomComponent item={item} index={index} />
  )}
/>

API

| Prop | Type | Required | Description | |----------------------------|---------------------------|----------|-------------------------------------------------| | data | Array | Required | An array of data to be rendered in the list. | | keyExtractor | Function | Required | Used to extract a unique key for a given item at the specified index. | | contentContainerStyle | ViewStyle | Optional | These styles will be applied to the scroll view content container which wraps all of the child views. | | ListHeaderComponent | React component | Optional | A custom component to render at the top of the list. | | ListHeaderComponentStyle | ViewStyle | Optional | Styling for internal View for ListHeaderComponent | | ListFooterComponent | React component | Optional | A custom component to render at the bottom of the list. | | ListFooterComponentStyle | ViewStyle | Optional | Styling for internal View for ListFooterComponent | | ListEmptyComponent | React component | Optional | A custom component to render when the list is empty. | | ListEmptyComponentStyle | ViewStyle | Optional | Styling for internal View for ListEmptyComponent | | renderItem | Function | Required | A function to render each item in the list. It receives an object with item and index properties. | | initialScrollIndex | Number | Optional | The initial index of the item to scroll to when the list mounts. | | inverted | Boolean | Optional | If true, the list will be rendered in an inverted order. | | horizontal | Boolean | Optional | If true, renders items next to each other horizontally instead of stacked vertically. | | onEndReached | Function | Optional | Called when the end of the content is within onEndReachedThreshold. | | onEndReachedThreshold | Double | Optional | The threshold (in content length units) at which onEndReached is triggered. | | onStartReached | Function | Optional | Called when the start of the content is within onStartReachedThreshold. | | onStartReachedThreshold | Double | Optional | The threshold (in content length units) at which onStartReached is triggered. |

Methods

| Method | Type | Description | |-----------------|-------------------------------------|-----------------------------------------------------------| | scrollToIndex | Function | Scrolls the list to the specified index. | | scrollToOffset| Function | Scrolls the list to the specified offset. |

License

MIT