You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Implement new RecyclerView prototype with enhanced features and React Native 0.78 support
* Skip core swapping in tests
* Add header offset to initial scroll
* Add index to CellRendererComponent
* Remove completed TODO comments
* Fix memoization in samples
* temporarily ignore fixture ts errors
* Update yarn.lock
* remove random in samples
* build fix
* Fix and add new e2e tests
* pod update
* Unit testing most of the code
* Fix lint errors
* Fix sticky overflow
* Add docs 1.x and further edits to current docs
* Fix chat flickers
* Added TODO
* Improve scrollToIndex alogrithm
* version bump
* Optimize scrollTo for non animated situations
* v2.0.0-alpha.5
* Fix RTL horizontal lists
* Add known issue for horizontal RTL
* v2.0.0-alpha.6
* Fix unwanted mounts on data addition to top
* Add note about horizontal lists
* Update usage guide
* Fix missing custom refresh control
* v2.0.0-alpha.7
* Fix memo in docs
* Reduce draw distance in chat sample
* change load time log
* Add new useMappingHelper hook for solving .map
* Fix duplicate onStartReached calls
* v2.0.0-alpha.8
* Fix flicker when switching to masonry from grid
* Fix rendering on web and add a sample
* Add more improvements for web
* Fix e2e test
* v2.0.0-alpha.9
* Add delay in e2e
* bump flash-list in web fixture
* Improve scrollTo accuracy even more
* Improve velocity tracking which was missing on web and iOS
* Fix bugs introduced by buffer improvements
* Improve buffer with render time
* Add wait to e2e
* Fix e2e flakiness
* v2.0.0-alpha.10
* Add an auto scroll script
* Fix sticky crash
* Improve twitter sample
* Upgrade fixture to RN 0.79.1
* Update readme
* Fix lint errors and cleanup
* Code cleanup and add few more methods to FlashList's handler
* Fix lint errors
* Add measureLayout mocks
* Update reanimated doc a bit
* bug fixes
* Add/Fix tests
* Fix infinite render loop in Grid Layout
* Improve sticky header compute
* Link to v1 docs
* Refactor recycling manager to be faster and more efficient
* Reconfigure benchmarks
* Export RecyclerView as AnimatedFlashList
* Change displayName of RecyclerView
* export recyclerview as default FlashList for tests
* v2.0.0-alpha.11
* Improve sticky headers animated setup
* Fix intermitttent animation skips in sticky headers
* Sample improvements
* Revert Animated.subtract as it breaks native driver
* exp with mvcp in horizontal
* Implement clearLayoutCacheOnUpdate API from v1
* v2.0.0-alpha.12
* Enable strict mode in few samples
* Workaround for cases where useLayoutEffect fails to block paint
* Fix missing itemType in average compute
* Improve reconciliation (#1672)
* Fix missing itemType in average compute
* Improve reconciliation algo
* Improve render stack update
* Add comment
* v2.0.0-alpha.13
* Remove completed TODOs
* Prevent getItemType calls for negative indices
* 2.0.0-alpha.14
* Fix documentation build
* Improve docs
* Doc improvements
* Fix any in ViewToken
* 2.0.0-rc.1
@@ -16,19 +15,33 @@ Swap from FlatList in seconds. Get instant performance.
16
15
17
16
</div>
18
17
19
-
## React Native's new architecture support
18
+
#FlashList v2
20
19
21
-
FlashList v1 is compatible with React Native's new architecture however, we have a new version (v2) in alpha that fully leverages the new architecture and comes with more features. Click [here](https://github.com/Shopify/flash-list/tree/new-rlv-prototype?tab=readme-ov-file#flashlist-v2) to know more.
20
+
FlashList v2 has been rebuilt from the ground up for RN's new architecture and delivers fast performance, higher precision, and better ease of use compared to v1. We've achieved all this while moving to a JS-only solution! One of the key advantages of FlashList v2 is that it doesn't require any estimates. It also introduces several new features compared to v1.
21
+
22
+
> ⚠️ **IMPORTANT:** FlashList v2.x has been designed to fully leverage the new architecture. **Old architecture will only be supported while FlashList v2 is in alpha/beta/rc and will be dropped once it's ready.** When run on old architecture, we just fall back to v1.x which doesn't have any of the new features.
23
+
24
+
### Is v2 production ready?
25
+
26
+
Yes, please use one of the release candidates if you want to ship to production `2.0.0-rc.x`. While we can make some changes in the final version, we expect release candidates to be quite stable. Use the alpha track if you want to test new changes quickly and don't mind occasional bugs.
27
+
28
+
> ⚠️ **IMPORTANT:** FlashList v2.x's alpha track moves quickly and can have some issues. Please report any issues or edge cases you run into. We're actively working on testing and optimizing v2. We also highly recommend using it with RN 0.78+ for optimal performance.
29
+
30
+
### Old architecture / FlashList v1
31
+
32
+
If you're running on old architecture or using FlashList v1.x, you can access the documentation specific to v1 here: [FlashList v1 Documentation](https://shopify.github.io/flash-list/docs/1.x/).
33
+
34
+
### Web support
35
+
36
+
FlashList v2 has web support. Most of the features should work but we're not actively testing it right now. If you run into an issue, please raise it on GitHub.
22
37
23
38
## Installation
24
39
25
-
Add the package to your project via `yarn add @shopify/flash-list` and run `pod install` in the `ios` directory.
40
+
Add the package to your project via `yarn add @shopify/flash-list@rc` and run `pod install` in the `ios` directory.
26
41
27
42
## Usage
28
43
29
-
We recommend reading the detailed documentation for using `FlashList`[here](https://shopify.github.io/flash-list/docs/usage).
30
-
31
-
But if you are familiar with [FlatList](https://reactnative.dev/docs/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:
44
+
But if you are familiar with [FlatList](https://reactnative.dev/docs/flatlist), you already know how to use `FlashList`. You can try out `FlashList` by changing the component name or refer to the example below:
To avoid common pitfalls, you can also follow these steps for migrating from `FlatList`, based on our own experiences:
70
+
To avoid common pitfalls, you can also follow these steps for migrating from `FlatList`, based on our own experience:
59
71
60
-
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.
61
-
2.**Important**: Scan your [`renderItem`](https://shopify.github.io/flash-list/docs/usage/#renderitem) hierarchy for explicit `key` prop definitions and remove them. If you’re doing a `.map()` use indices as keys.
72
+
1.Simply from `FlatList` to `FlashList` and render the list.
73
+
2.**Important**: Scan your [`renderItem`](https://shopify.github.io/flash-list/docs/usage/#renderitem) hierarchy for explicit `key` prop definitions and remove them. If you’re doing a `.map()` use our hook called [`useMappingHelper`](https://shopify.github.io/flash-list/docs/usage/#usemappinghelper).
62
74
3. Check your [`renderItem`](https://shopify.github.io/flash-list/docs/usage/#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](https://shopify.github.io/flash-list/docs/recycling))
63
75
4. If your list has heterogenous views, pass their types to `FlashList` using [`getItemType`](https://shopify.github.io/flash-list/docs/usage/#getitemtype) prop to improve performance.
64
76
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.
77
+
6. Memoizing props passed to FlashList is more important in v2. v1 was more selective about updating items, but this was often perceived as a bug by developers. We will not follow that approach and will instead allow developers to ensure that props are memoized. We will stop re-renders of children wherever it is obvious.
78
+
79
+
## Other things to know
80
+
81
+
-`keyExtractor` is important to prevent glitches due to item layout changes when going upwards. We highly recommend having a valid `keyExtractor` with v2.
82
+
-`useLayoutState`: This is similar to `useState` but communicates the change in state to FlashList. It's useful if you want to resize a child component based on a local state. Item layout changes will still be detected using `onLayout` callback in the absence of `useLayoutState`, which might not look as smooth on a case-by-case basis.
-`useRecyclingState`: Similar to `useState` but accepts a dependency array. On change of deps, the state gets reset without an additional `setState` call. Useful for maintaining local item state if really necessary. It also has the functionality of `useLayoutState` built in.
-`useMappingHelper`: Returns a function that helps create optimal mapping keys for items when using `.map()` in your render methods. Using this ensures optimized recycling and performance for FlashList.
- If you're nesting horizontal FlashLists in vertical lists, we highly recommend the vertical list to be FlashList too. We have optimizations to wait for child layout to complete which can improve load times.
65
157
66
158
## App / Playground
67
159
68
-
The [fixture](https://github.com/Shopify/flash-list/tree/main/fixture) is an example app showing how to use the library.
160
+
The [fixture](./fixture/) is an example app showing how to use the library.
Copy file name to clipboardExpand all lines: documentation/docs/fundamentals/performant-components.md
+42-30Lines changed: 42 additions & 30 deletions
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,19 @@
1
1
---
2
-
id: performant-components
3
-
title: Writing performant components
2
+
id: performance
3
+
title: Performance
4
4
---
5
5
6
+
## Profiling
7
+
8
+
:::warning
9
+
Before assessing your list's performance, make sure you are in release mode. On Android, you can disable JS dev mode inside the developer menu, whereas you need to run the release configuration on iOS.
10
+
FlashList can appear to be slower than FlatList in dev mode. The primary reason is a much smaller and fixed [window size](https://reactnative.dev/docs/virtualizedlist#windowsize) equivalent. Click [here](https://reactnative.dev/docs/performance#running-in-development-mode-devtrue) to know more about why you shouldn't profile with dev mode on.
11
+
:::
12
+
13
+
Memoizing props passed to FlashList is more important in v2. v1 was more selective about updating items, but this was often perceived as a bug by developers. We will not follow that approach and will instead allow developers to ensure that props are memoized. We will stop re-renders of children wherever it is obvious.
14
+
15
+
# Writing Performant Components
16
+
6
17
While `FlashList` does its best to achieve high performance, it will still perform poorly if your item components are slow to render. In this post, let's dive deeper into how you can remedy this.
7
18
8
19
## Recycling
@@ -11,16 +22,12 @@ One important thing to understand is how `FlashList` works under the hood. When
11
22
12
23
## Optimizations
13
24
14
-
There's lots of optimizations that are applicable for _any_ React Native component and which might help render times of your item components as well. Usage of `useCallback`, `useMemo`, and `useRef` is advised - but don't use these blindly, always [measure the performance](/performance-troubleshooting) before and after making your changes.
25
+
There's lots of optimizations that are applicable for _any_ React Native component and which might help render times of your item components as well. Usage of `useCallback`, `useMemo`, and `useRef` is advised - but don't use these blindly, always measure the performance before and after making your changes.
15
26
16
27
:::note
17
28
Always profile performance in the release mode. `FlashList`'s performance between JS dev and release mode differs greatly.
18
29
:::
19
30
20
-
### `estimatedItemSize`
21
-
22
-
Ensure [`estimatedItemSize`](/usage#estimateditemsize) is as close as possible to the real average value - see [here](/estimated-item-size#how-to-calculate) how to properly calculate the value for this prop.
23
-
24
31
### Remove `key` prop
25
32
26
33
:::warning
@@ -29,6 +36,10 @@ Using `key` prop inside your item and item's nested components will highly degra
29
36
30
37
Make sure your **item components and their nested components don't have a `key` prop**. Using this prop will lead to `FlashList` not being able to recycle views, losing all the benefits of using it over `FlatList`.
31
38
39
+
#### Why are keys harmful to FlashList?
40
+
41
+
FlashList's core performance advantage comes from **recycling** components instead of creating and destroying them however, when you add a `key` prop that changes between different data items, React treats the component as entirely different and forces a complete re-creation of the component tree.
42
+
32
43
For example, if we had a following item component:
33
44
34
45
```tsx
@@ -46,7 +57,7 @@ const MyItem = ({ item }) => {
46
57
};
47
58
```
48
59
49
-
Then the `key` prop should be removed from both `MyItem` and `MyNestedComponent`:
60
+
Then the `key` prop should be removed from both `MyItem` and `MyNestedComponent`. It isn't needed and react can alredy take care of updating the components.
There might be cases where React forces you to use `key` prop, such as when using `map`. In such cirumstances, ensure that the `key` is not tied to the `item` prop in any way, so the keys don't change when recycling.
67
-
68
-
Let's imagine we want to display names of users:
77
+
There might be cases where React forces you to use `key` prop, such as when using `map`. In such circumstances, **use `useMappingHelper`** to ensure optimal performance:
Although using index as a `key` in `map` is not recommended by React, in this case since the data is derived from the list's data, the items will update correctly.
95
+
The `useMappingHelper` hook intelligently provides the right key strategy:
96
+
97
+
-**When inside FlashList**: Uses stable keys that don't change during recycling
98
+
-**When outside FlashList**: Uses the provided item key for proper React reconciliation
99
+
100
+
This approach ensures that:
101
+
102
+
- Components can be recycled properly within FlashList
103
+
- React's reconciliation works correctly
104
+
- Performance remains optimal
105
+
106
+
:::info
107
+
`useMappingHelper` should be used whenever you need to map over arrays inside FlashList item components. It automatically handles the complexity of providing recycling-friendly keys.
Copy file name to clipboardExpand all lines: documentation/docs/fundamentals/recycling.md
+5-9Lines changed: 5 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -4,16 +4,14 @@ title: Recycling
4
4
slug: /recycling
5
5
---
6
6
7
-
One important thing to understand is how `FlashList` works under the hood. When an item gets out of the viewport, instead of being destroyed, the component is re-rendered with a different `item` prop. For example, if you make use of `useState` in a reused component, you may see state values that were set for that component when it was associated with a different item in the list, and would then need to reset any previously set state when a new item is rendered:
7
+
One important thing to understand is how `FlashList` works under the hood. When an item gets out of the viewport, instead of being destroyed, the component is re-rendered with a different `item` prop. For example, if you make use of `useState` in a reused component, you may see state values that were set for that component when it was associated with a different item in the list, and would then need to reset any previously set state when a new item is rendered. FlashList now comes with `useRecyclingState` hook that can reet the state automatically without an additional render.
8
8
9
9
```tsx
10
10
const MyItem = ({ item }) => {
11
-
const lastItemId =useRef(item.someId);
12
-
const [liked, setLiked] =useState(item.liked);
13
-
if (item.someId!==lastItemId.current) {
14
-
lastItemId.current=item.someId;
15
-
setLiked(item.liked);
16
-
}
11
+
// value of liked is reset if deps array changes. The hook also accepts a callback to reset anything else if required.
This follows advice in the [React Hooks FAQ on implementing getDerivedStateFromProps](https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops). Ideally your component hierarchy returned from [renderItem](../fundamentals/usage.md#renderitem) should not make use of `useState` for best performance.
27
-
28
24
When optimizing your item component, try to ensure as few things as possible have to be re-rendered and recomputed when recycling.
0 commit comments