-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathIntersectionObserverBenchmark.js
More file actions
129 lines (113 loc) · 2.97 KB
/
IntersectionObserverBenchmark.js
File metadata and controls
129 lines (113 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import type IntersectionObserverType from 'react-native/src/private/webapis/intersectionobserver/IntersectionObserver';
import {RNTesterThemeContext} from '../../components/RNTesterTheme';
import * as React from 'react';
import {
type ElementRef,
useContext,
useLayoutEffect,
useRef,
useState,
} from 'react';
import {Button, ScrollView, StyleSheet, Text, View} from 'react-native';
declare var IntersectionObserver: Class<IntersectionObserverType>;
export const name = 'IntersectionObserver Benchmark';
export const title = name;
export const description =
'Example of using IntersectionObserver to observe a large amount of UI elements';
export function render(): React.Node {
return <IntersectionObserverBenchark />;
}
const ROWS = 100;
const COLUMNS = 5;
function IntersectionObserverBenchark(): React.Node {
const [isObserving, setObserving] = useState(false);
return (
<>
<View style={styles.buttonContainer}>
<Button
title={isObserving ? 'Stop observing' : 'Start observing'}
onPress={() => setObserving(observing => !observing)}
/>
</View>
<ScrollView>
{Array(ROWS)
.fill(null)
.map((_, row) => (
<View style={styles.row} key={row}>
{Array(COLUMNS)
.fill(null)
.map((_2, column) => (
<Item
index={COLUMNS * row + column}
observe={isObserving}
key={column}
/>
))}
</View>
))}
</ScrollView>
</>
);
}
function Item({index, observe}: {index: number, observe: boolean}): React.Node {
const theme = useContext(RNTesterThemeContext);
const ref = useRef<?ElementRef<typeof View>>();
useLayoutEffect(() => {
const element = ref.current;
if (!observe || !element) {
return;
}
const observer = new IntersectionObserver(
entries => {
// You can inspect the actual entries here.
// We don't log them by default to avoid the logs themselves to degrade
// performance.
},
{
threshold: [0, 1],
},
);
observer.observe(element);
return () => {
observer.disconnect();
};
}, [observe]);
return (
<View
ref={ref}
style={[
styles.item,
{backgroundColor: theme.SecondarySystemBackgroundColor},
]}>
<Text style={[styles.itemText, {color: theme.LabelColor}]}>
{index + 1}
</Text>
</View>
);
}
const styles = StyleSheet.create({
buttonContainer: {
padding: 10,
},
row: {
flexDirection: 'row',
},
item: {
flex: 1,
padding: 12,
margin: 5,
},
itemText: {
fontSize: 22,
textAlign: 'center',
},
});