@@ -25,29 +25,44 @@ build it according to your needs.
2525- Either hide the ` <img /> ` with CSS, or skip rendering it until it's inside the
2626 viewport.
2727
28+ > 🔥 The example has been expanded to include support for the new native
29+ > ` loading ` attribute on images. If it's supported, we can skip the ` useInView `
30+ > hook and render the ` <img> ` .
31+ >
32+ > See https://web.dev/native-lazy-loading for details about using the ` loading `
33+ > attribute.
34+ >
35+ > [ @charlietango/use-native-lazy-loading ] ( https://www.npmjs.com/package/@charlietango/use-native-lazy-loading )
36+ > is a small hook that detects support for ` loading ` as a side effect.
37+
2838``` jsx
2939import React from ' react'
40+ import useNativeLazyLoading from ' @charlietango/use-native-lazy-loading'
3041import { useInView } from ' react-intersection-observer'
3142
3243const LazyImage = ({ width, height, src, ... rest }) => {
44+ const supportsNativeLoading = useNativeLazyLoading ()
3345 const [ref , inView ] = useInView ({
3446 triggerOnce: true ,
35- threshold : 0 ,
47+ margin : ' 200px 0px ' ,
3648 })
3749
3850 return (
3951 < div
40- ref= {ref}
52+ ref= {supportsLazyLoading === false ? ref : undefined }
4153 style= {{
4254 position: ' relative' ,
4355 paddingBottom: ` ${ (height / width) * 100 } %` ,
4456 background: ' #2a4b7a' ,
4557 }}
4658 >
47- {inView ? (
59+ {inView || supportsNativeLoading ? (
4860 < img
4961 {... rest}
5062 src= {src}
63+ width= {width}
64+ height= {height}
65+ loading= " lazy"
5166 style= {{ position: ' absolute' , width: ' 100%' , height: ' 100%' }}
5267 / >
5368 ) : null }
@@ -64,7 +79,8 @@ Triggering animations once they enter the viewport is also a perfect use case
6479for an IntersectionObserver.
6580
6681- Set ` triggerOnce ` , to only trigger the animation the first time.
67- - Use ` threshold ` to control when the animations triggers.
82+ - Use ` margin ` to offset the trigger points. It ensures that a fixed fixed
83+ amount is visible, regardless of the element size.
6884
6985``` jsx
7086import React from ' react'
@@ -73,7 +89,7 @@ import { useSpring, animated } from 'react-spring'
7389
7490const LazyAnimation = () => {
7591 const [ref , inView ] = useInView (ref, {
76- threshold : 0.5 ,
92+ margin : ' -100px 0 ' ,
7793 })
7894 const props = useSpring ({ opacity: inView ? 1 : 0 })
7995
@@ -92,16 +108,17 @@ export default LazyAnimation
92108You can use ` IntersectionObserver ` to track when a user views your element, and
93109fire an event on your tracking service.
94110
95- - Set ` triggerOnce ` , to only trigger an event the first time the element enters the viewport.
96- - Set ` threshold ` , to control how much of the element should visible before
97- firing the event.
111+ - Set ` triggerOnce ` , to only trigger an event the first time the element enters
112+ the viewport.
113+ - Use ` margin ` to offset the trigger points. It ensures that a fixed fixed
114+ amount is visible, regardless of the element size.
98115
99116``` jsx
100117import React , { useEffect } from ' react'
101118import { useInView } from ' react-intersection-observer'
102119
103120const TrackImpression = () => {
104- const [ref , inView ] = useInView ({triggerOnce: true , threshold : 0.2 })
121+ const [ref , inView ] = useInView ({ triggerOnce: true , margin : ' -100px 0 ' })
105122 useEffect (() => {
106123 if (inView) {
107124 // Fire a tracking event to your tracking service of choice.
0 commit comments