Git Product home page Git Product logo

flash-list's Introduction

FlashList Image

WebsiteDiscordGetting startedUsagePerformanceWriting performant componentsKnown Issues

Fast & performant React Native list. No more blank cells.

Swap from FlatList in seconds. Get instant performance.

Installation

Add the package to your project via yarn add @shopify/flash-list and run pod install in the ios directory.

Usage

We recommend reading the detailed documentation for using FlashList here.

But if you are familiar with FlatList, you already know how to use FlashList. You can try out FlashList by changing the component name and adding the estimatedItemSize prop or refer to the example below:

import React from "react";
import { View, Text } from "react-native";
import { FlashList } from "@shopify/flash-list";

const DATA = [
  {
    title: "First Item",
  },
  {
    title: "Second Item",
  },
];

const MyList = () => {
  return (
    <FlashList
      data={DATA}
      renderItem={({ item }) => <Text>{item.title}</Text>}
      estimatedItemSize={200}
    />
  );
};

To avoid common pitfalls, you can also follow these steps for migrating from FlatList, based on our own experiences:

  1. Switch from FlatList to FlashList and render the list once. You should see a warning about missing estimatedItemSize and a suggestion. Set this value as the prop directly.
  2. Important: Scan your renderItem hierarchy for explicit key prop definitions and remove them. If you’re doing a .map() use indices as keys.
  3. Check your renderItem hierarchy for components that make use of useState and verify whether that state would need to be reset if a different item is passed to that component (see Recycling)
  4. If your list has heterogenous views, pass their types to FlashList using getItemType prop to improve performance.
  5. Do not test performance with JS dev mode on. Make sure you’re in release mode. FlashList can appear slower while in dev mode due to a small render buffer.

App / Playground

The fixture is an example app showing how to use the library.

flash-list's People

Contributors

brentvatne avatar cursedcoder avatar davebcn87 avatar dependabot[bot] avatar elviraburchik avatar fortmarek avatar gorhom avatar gvarandas avatar iamshadmirza avatar imranbarbhuiya avatar jamesism avatar jamsch avatar jenshenny avatar jlepp avatar kassemitani avatar kelum-p avatar kubilaysalih avatar markrickert avatar mauriciomeirelles avatar mironiasty avatar mmmoussa avatar naqvitalha avatar okwasniewski avatar randall71 avatar services-db[bot] avatar sherifmega avatar simek avatar spy-v2[bot] avatar sterlingwes avatar yhkaplan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flash-list's Issues

Fix headers and separators for numColumns >= 2

Item Separator implementation adds a view own its own to draw additional children. This view changes the flexDirection chosen by recyclerlistview.
The header, footer and item separator implementations will not work with columns today.
Standardize and align contract with FlatList for the header

Implement FlashList for web

We will need to build the following to make it work on web

  • AutoLayoutView for web
  • Cell container for web
  • Blank events (optional)

In the meantime we can replace them with views and it should still work

Fix blank area events on fast scroll | iOS?

What

 ### Context

The RecyclerFlatList allows enabling reporting blank areas on scroll via enableInstrumentation prop. When enabled, useOnNativeBlankAreaEvents hook reports the number of blank points when the list is scrolled.

Problem

When scroll happens too fast - via side scroll or status bar click - the numbers become larger than the window size

image

These numbers probably are correct, but might be confusing when used to profiling reports.

Where should decide how to approach these numbers. One solution could be to report windowSize along with blankArea, so we can optionally strip it to the windowSize. Note: here windowSize should be the size of the list - the name of the prop might be misleading but it's from RecyclerListView

Reproducing

Screenshare.-.2022-01-25.10_06_15.AM.mp4

Measure FPS against FlatList using averages

What

We want to have a more scientific results gathering of FPS (both UI and JS) compared to FlatList. We should run this in both iOS and Android. Please edit this issues with your devices so we have more than one type of device per platform:

Device Owner
iPhone 13 Pro David
Moto G10 David

How

We can use the Twitter timeline as an example. Run 5 times with both solutions, FlatList and RecyclerFlatList and calculate the average.

Considerations

  • Should we run this in release mode? In iOS will be more complicated but the results would be better.
  • The device should be disconnected and we should prevent extra logs that could affect performance.
  • Where should we document this? Is this part of the Tech doc?
  • Should we use the tool that Shop created? Should we use this?

Fix scrollToTop blanking

Problem

When scrolling to top using the status bar tap in iOS, we see some blanks even in the top performing devices.

Possible solution

FlatList does not remove the first elements of the screen, this could compromise memory but solve this problem.

Horizontal list cannot be non deterministic in size

What

RFL uses absolute positions to render children and what this means is that the height of the parent is not impacted by children. So, scrollview doesn't automatically size itself. RLV internally enforces a size to workaround this. This size is not changed automatically based on children size.

How to reproduce:

Create any RFL and give it a minHeight that is less than content size. Ideally it should expand to fit height of the largest child but it won't. It will stick to minHeight.

Ideas

We can listen to match the size of the biggest child either on JS or native side. Doing on native size might look cleaner although propagating size changes to JS layout is cumbersome. JS version might resize. We need to experiment and decide how to do this.

Set Repo Description

Set Repo Description

TL;DR

Set a description for your service in Slack with spy: /spy github repo description :repo *description

Why is this being asked?

A repo description makes your service more discoverable in Services DB, especially when it comes to differing internal and external project names.

What will happen if it doesn't get done within the expected timeframe?

This is mandatory. If this is not done your service will not be easily discoverable in Services DB.

When does it need to get done?

At the latest, this should be done before 2022-04-28.

This doesn't apply to my service. What do I do?

First, leave a comment explaining why it doesn't apply. Then, leave another comment as /not_applicable, and close the issue.
If you change your mind, make sure to comment any reason and reopen the issue.

I have questions/concerns about this

Please contact the Production Excellence team using Slack at #core-build-manage.
Your service: recycler-flat-list
Owners: @Shopify/react-native-foundations

Measure blanks against FlatList using averages

What

We want to have a more scientific results gathering of blanks compared to FlatList. We should run this in both iOS and Android. Please edit this issues with your devices so we have more than one type of device per platform:

Device Owner
iPhone 13 Pro David
Moto G10 David

How

We can use the Twitter timeline as an example. Run 5 times with both solutions, FlatList and RecyclerFlatList and calculate the average.

Considerations

  • Should we run this in release mode? In iOS will be more complicated but the results would be better.
  • The device should be disconnected and we should prevent extra logs that could affect performance.
  • Where should we document this? Is this part of the Tech doc?

Docusaurus microsite

As our documentation expands, we should look into docusaurus microsite to make reading the documentation easier and more manageable.

The guide to create one can be found here.

Flipper dependency breaks the app

I tried the package in Shopify mobile. It broke on flipper import as it wasn't referred in the project. We should make it optional.

Create known issue documentation

Document all known issues in one place. This make it easier for people trying the prototype on what to report and what is expected. It should be a readme in github.
We should capture major ones first.

Calculate list render overhead (in JS)

The time that is added to overall rendering because of using lists. Imagine if there were only five items to render that just fill the screen and there was no need to virtualize. In such a scenario how much faster would it be to just render a ScrollView?

It might be important to measure this metric because a lot of developers used to native code never use scroll views. Everything is usually a list so, ideally it should be fast to render even if the number of items is small.

Lab measurement: We can have code that renders the same items in scrollview and then list and compute the diff.

Realtime: We can try and measure how soon we get the onLayout for the first item. A direct comparison to scrollview maynot be a good idea however, we can plot number of items vs time to layout first items and observe the trend.

We can compare to other lists also.

Convert onEndReachedThreshold from pixels to ratio

Problem

RecyclerListView uses number of pixels for onEndReachedThreshold (ex: 100). FlatList uses percentage of screen (ex: 0.2).

Proposed solution

To simplify for a developer using RecyclerFlatList we should do this conversion inside the wrapper

Services DB

We should add this repository to Services DB along with service.yml

Animated.event support on onScroll

What

Developers can pass an Animated.event to FlatList and ScrollView to sync some animations with scroll offset. If used with native drive this can work on native side completely. This is missing from RFL today.

More info:
While RFL and RLV use ScrollVIew internally they don't expose scrollableNode. If that can be added or we pass our own scrollview to RLV we can add this function. createAnimatedComponent can work on any component that can implement getScrollableNode function and return ref to the scrollview.

So, in summary we need to implement getScrollableNode method inside RFL which should return ref of internal ScrollView. Once this is done we can just call createAnimatedComponent(RFL) and export this as AnimatedRFL. In theory, this should work.

Detect key prop usage in list components

What

If key prop is used directly on component react will unmount and create a new one if the value is modified. RFL relies on keys to achieve recycling. In Shopify/react-native-foundations#558 I noticed similar usage and only after removing them was I able to get performance boost.
It's possible that other apps have similar setup, this prop is not necessary and we need to catch it some way.

Proposal

A lint rule can be a great build time addition. We can also explore other ideas.

Release the library untranspiled

What

React Native libraries are usually released untranspiled. This also makes it easier to debug since users have access to the code directly.

Override type of first item if list has to render a header

What

We add header on top of first item instead of scrollview. It's to simplify our compute and avoid applying corrections to offset values. Given first cell is a list item it can be recycled which will cause header to be unmounted and recreated on reverse scroll.

Changing the type of first item will prevent it from being recycled.

Measure TTI against FlatList and regular ScrollView using averages

What

We want to have a more scientific results gathering of TTI compared to FlatList. We should run this in both iOS and Android. Please edit this issues with your devices so we have more than one type of device per platform:

Device Owner
iPhone 13 Pro David
Moto G10 David

How

We can use the Twitter timeline as an example. Run 5 times with both solutions, FlatList and RecyclerFlatList and calculate the average.

Considerations

  • Should we run this in release mode? In iOS will be more complicated but the results would be better.
  • The device should be disconnected and we should prevent extra logs that could affect performance.
  • Where should we document this? Is this part of the Tech doc?

Allow blank area to support multiple lists on the screen

What

Per discussion.

More context:

The RecyclerFlatList allows enabling reporting blank areas on scroll via enableInstrumentation prop. When enabled, useOnNativeBlankAreaEvents hook reports the number of blank points when the list is scrolled.

However, it's possible to use multiple instances of RecyclerFlatList on the screen. In this case, the hook reports events from all instances through the same callback. There is no way to distinguish the metrics of different lists from each other.

One way to allow separate profiling of multiple lists is to make enableInstrumentation prop include listName. This allows discerning between lists based on the name.

Implement FlatList API on top of RecyclerListView

Implement autolayoutview on iOS

AutoLayoutView is exposed to react native as a native UI component. RecyclerListView renders all of its children inside this container if it's provided to it.

Given that this is a custom view we can intercept when the actual draw happens on the native side and check for overlaps and gaps and correct them. This doesn't impact RLV layout because RLV will update itself in the next frame and become consistent.

Here's the view: https://github.com/Shopify/flatlistpro/blob/main/android/app/src/main/java/com/flatlistpro/AutoLayoutView.kt
and the view manager: https://github.com/Shopify/flatlistpro/blob/main/android/app/src/main/java/com/flatlistpro/AutoLayoutViewManager.kt

RLV is also wrapping each cell in a custom view called CellContainer which provides you with an index field using which items can be sorted. It's available here: https://github.com/Shopify/flatlistpro/blob/main/android/app/src/main/java/com/flatlistpro/CellContainer.kt

The algorithm only check for issues in the placement of adjacent items and is expected to work with variable grid layouts and doesn't solve for masonry.

Tests: test data isn't available right now however, JS application included in this repo has implementation that can be used for testing: https://github.com/Shopify/flatlistpro/blob/main/List.js

Screen Shot 2022-01-05 at 7 21 09 AM

Refine estimatedHeight requirement for RFL

What

In order to compute the number of items to render on first draw we need some sort of estimate. This value being an average will help both load times and scroll perf by preventing unnecessary mounts.

The question is how do we take this value without impacting developer experience

Ideas

  • Compute within list and show a suggestion using console.warn
  • Make the prop mandatory. Knowing about this might help the dev in the long run. Having a crappy list and figuring out what's wrong might be worse than seeing this as a requirement upfront
  • Estimate internally, hard to do. We can thing of something
  • If we keep it then list should also throw an exception if it doesn't get this value.

AutoLayout skips cells if header is too large

What

If the header is large enough to push the content so far down that it goes beyond the view port then there could be visible movement. It's minor but can still happen. The reason is that AutoLayout checks for a cell to be in view port before correcting its neighbour. If cell gets pushed beyond viewport and it's neighbour isn't then it can overlap with cell.

Fix

A simple fix could be to not do bounds check on first run which won't hurt performance and solve this problems. The will be no issues if we skip it on the first run.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.