|
2 | 2 |
|
3 | 3 | Some events, such as `scroll` and `resize` have traditionally caused performance issues on web pages, as they are high frequency events, firing many times per second as the user interacts with the page viewport.
|
4 | 4 |
|
5 |
| -## Scroll vs IntersectionObserver |
| 5 | +## Rule Details |
6 | 6 |
|
7 | 7 | Typically `scroll` events are used to determine if an element is intersecting a viewport, which can result in expensive operations such as layout calculations, which has a detrimental affect on UI performance. Recent developments in web standards have introduced the `IntersectionObserver`, which is a more performant mechanism for determining if an element is intersecting the viewport.
|
8 | 8 |
|
| 9 | +Similarly, `resize` events are typically used to determine if the viewport is smaller or larger than a certain size, similar to CSS media break points. Similar to the `IntersectionObserver` the `ResizeObserver` also exists as a more performant mechanism for observing changes to the viewport size. |
| 10 | + |
9 | 11 | ```js
|
10 |
| -// bad, expensive, error-prone code to determine if the element is in the viewport; |
11 |
| -window.addEventListener('scroll', () => { |
12 |
| - const isIntersecting = checkIfElementIntersects(element.getBoundingClientRect(), window.innerHeight, document.clientHeight) |
13 |
| - element.classList.toggle('intersecting', isIntersecting) |
| 12 | +// bad, low-performing code to determine if the element is less than 500px large |
| 13 | +window.addEventListener('resize', () => { |
| 14 | + element.classList.toggle('size-small', element.getBoundingClientRect().width < 500) |
14 | 15 | })
|
15 | 16 |
|
16 |
| -// good - more performant and less error-prone |
17 |
| -const observer = new IntersectionObserver(entries => { |
18 |
| - for(const {target, isIntersecting} of entries) { |
19 |
| - target.classList.toggle(target, isIntersecting) |
| 17 | +// good - more performant, only fires when the actual elements change size |
| 18 | +const observer = new ResizeObserver(entries => { |
| 19 | + for (const {target, contentRect} of entries) { |
| 20 | + target.classList.toggle('size-small', contentRect.width < 500) |
20 | 21 | }
|
21 | 22 | })
|
22 | 23 | observer.observe(element)
|
23 | 24 | ```
|
24 | 25 |
|
25 |
| -## Resize vs ResizeObserver |
| 26 | +https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API |
| 27 | +https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API |
26 | 28 |
|
27 |
| -Similarly, `resize` events are typically used to determine if the viewport is smaller or larger than a certain size, similar to CSS media break points. Similar to the `IntersectionObserver` the `ResizeObserver` also exists as a more performant mechanism for observing changes to the viewport size. |
| 29 | +👎 Examples of **incorrect** code for this rule: |
28 | 30 |
|
29 | 31 | ```js
|
30 |
| -// bad, low-performing code to determine if the element is less than 500px large |
31 |
| -window.addEventListener('resize', () => { |
32 |
| - element.classList.toggle('size-small', element.getBoundingClientRect().width < 500) |
| 32 | +// bad, expensive, error-prone code to determine if the element is in the viewport; |
| 33 | +window.addEventListener('scroll', () => { |
| 34 | + const isIntersecting = checkIfElementIntersects( |
| 35 | + element.getBoundingClientRect(), |
| 36 | + window.innerHeight, |
| 37 | + document.clientHeight |
| 38 | + ) |
| 39 | + element.classList.toggle('intersecting', isIntersecting) |
33 | 40 | })
|
| 41 | +``` |
34 | 42 |
|
35 |
| -// good - more performant, only fires when the actual elements change size |
36 |
| -const observer = new ResizeObserver(entries => { |
37 |
| - for(const {target, contentRect} of entries) { |
38 |
| - target.classList.toggle('size-small', contentRect.width < 500) |
| 43 | +👍 Examples of **correct** code for this rule: |
| 44 | + |
| 45 | +```js |
| 46 | +// good - more performant and less error-prone |
| 47 | +const observer = new IntersectionObserver(entries => { |
| 48 | + for (const {target, isIntersecting} of entries) { |
| 49 | + target.classList.toggle(target, isIntersecting) |
39 | 50 | }
|
40 | 51 | })
|
41 | 52 | observer.observe(element)
|
42 | 53 | ```
|
43 | 54 |
|
44 |
| -## See Also |
| 55 | +## Version |
45 | 56 |
|
46 |
| -https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API |
47 |
| -https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API |
| 57 | +4.3.2 |
0 commit comments