지연 로딩 이미지 - [2/2]
요약
이전 게시물에서 이미지의 저해상도 버전과 고해상도 버전에 대한 두 가지 소스를 받는 React 구성 요소 이미지를 빌드했습니다. 다운로드가 완료되는 즉시 후자로 대체되는 전자를 표시합니다.
Repo 📑
추상적인
추가 성능 향상은 구성 요소가 표시될 때만 고해상도 이미지 다운로드를 시작하는 것입니다.
여전히 최신 React에 대한 관점에서 HTML 요소와 연결된 ref를 받은 후 IntersectionObserver API를 사용하여 요소가 보기에 있는지 평가하는 사용자 지정 후크를 빌드합니다.
프로세스
이전에 만든 해당 폴더에 후크를 추가합니다.
touch src/hooks/useIntersectionObserver.js
IntersectionObserver는 후크가 인수로 받는
useEffect
에 따라 실행이 달라지는 elementRef
에서 인스턴스화되어야 합니다. 이것은 사용 중에 다른 참조가 조건부로 제공되는 경우 후크의 기능이 응답하는 데 필요합니다.진행하는 한 가지 방법은 후크 자체에서 선언된
ref
에 IntersectionObserver를 바인딩하는 것입니다. 이런 식으로 후크를 사용하여 구성 요소를 마운트 해제할 때 React는 앞서 언급한 항목을 정리합니다ref
.IntersectionObserver 콜백에서 관찰되는 항목을 설정하는 것으로 충분합니다. 이렇게 하면 외부에서 쉽게 찾을 수 있습니다
useEffect
.useIntersectionObserver.js
import { useRef, useEffect, useState } from 'react'
const useIntersectionObserver = elementRef => {
const observer = useRef()
const [entry, setEntry] = useState()
const options = {
threshold: 0.1,
root: null,
rootMargin: '0%',
}
const updateEntry = entries => {
setEntry(entries[0])
}
useEffect(() => {
const node = elementRef?.current
if (!node) return
if (observer.current) observer.current.disconnect()
observer.current = new IntersectionObserver(updateEntry, options)
const { current: currentObserver } = observer
currentObserver.observe(node)
return () => currentObserver.disconnect()
}, [elementRef])
return { isVisible: !!entry?.isIntersecting, entry }
}
export default useIntersectionObserver
뷰에 구성 요소가 있는지 여부를 나타내는 부울이 반환됩니다.
There are two
observer.current.disconnect()
. The first is executed only if the observer was already active but under observation on a differentelementRef
. In the second case, the disconnection occurs in the cleanup phase of theuseEffect
which, by extension, uniquely corresponds to the moment in which the component that makes use of the hook is removed from the DOM
For the purposes of this demo the hook always refers to the whole view. However, it is not difficult to take a second
options
argument and pass it into the IntersectionObserver instance (remember to add it to theuseEffect
dependencies)
The use in the <Image>
component (the same as in the previous post) is immediate. I declare a ref ( imageRef
) and bind it to the root element of the component ( div.wrapper
). The same ref is supplied to the useIntersectionObserver
hook which returns isVisible
Conditionally showing the second <img>
tag, that is the one associated with the high-resolution image, you will get that the feature implemented in the previous post is used only when the element enters view. In the meantime, the user is shown the low-resolution image
Image.js(*는 이전 항목의 변경 사항을 나타냄)
import { useRef } from 'react'
import useImageOnLoad from '../hooks/useImageOnLoad'
import useIntersectionObserver from '../hooks/useIntersectionObserver'
const Image = ({ width = '100%', height = '100%', lowResSrc, highResSrc }) => {
const { handleImageOnLoad, transitionStyles } = useImageOnLoad()
const imageRef = useRef() // *
const { isVisible } = useIntersectionObserver(imageRef) // *
const styles = {
wrapper: {
position: 'relative',
width,
height,
},
image: {
position: 'absolute',
width: '100%',
height: '100%',
objectPosition: 'center center',
objectFit: 'cover',
},
}
const lowResStyle = {
...styles.image,
...transitionStyles.lowRes,
}
const hightResStyle = {
...styles.image,
...transitionStyles.highRes,
}
return (
<div style={styles.wrapper} ref={imageRef}>
<img src={lowResSrc} style={lowResStyle} />
{isVisible && ( // *
<img
src={highResSrc}
style={hightResStyle}
onLoad={handleImageOnLoad}
/>
)}
</div>
)
}
export default Image
원하는 효과가 있는지 확인하는 가장 간단한 방법은 이미지를 화면 밖으로 이동하는 것입니다.
App.js(세부정보)
<div style={{ position: 'relative', height: '200vh' }}>
<div style={{ position: 'absolute', bottom: 0 }}>
<ImageIO
width={600}
height={400}
lowResSrc={srcTuple[0]}
highResSrc={srcTuple[1]}
/>
</div>
</div>
개발자 도구의 네트워크 탭에서 저해상도 이미지 다운로드가 가능한 한 빨리 수행되는 방법을 확인할 수 있습니다. 반면에 고해상도 이미지의 경우 컴포넌트가 시야에 있을 때만 시작됩니다.
읽어 주셔서 감사합니다. 다음 게시물에서 계속 진행 중입니다.
Repo 📑
당신이 그것을 좋아한다면, 연락하자
🐙 및
Reference
이 문제에 관하여(지연 로딩 이미지 - [2/2]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/didof/lazy-loading-image-2-2-36f1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)