[JS] - BUG: `Can't' find variable: IntersectionObserver`

NoowaH·2023년 5월 12일
0

프론트엔드 개발자이며 페이지 성능에 관심이 있다면 화면에 보이지 않는 이미지를 레이지 로딩하기 위해 IntersectionObserver을 사용해본 사람이 많을 것이다.

IntersectionObserver?

  • IntersectionObserver는 브라우저의 빌트인 자바스크립트 API이며 상대적으로 최신 브라우저들에서만 지원
  • 뷰포트 내에 특정 엘리먼트가 보이는지에 대한 여부를 비동기적으로 확인할 수 있다
  • 이를 사용하여 뷰포트 내에 보이는 요소를 추적하고 이를 기반으로 동영상, 이미지, 헤비한 컴포넌트의 다이나믹 임포팅을 통해 페이지 로딩시간 최적화, 빌드 파일 사이즈 축소 등 다양하게 성능을 향상 시킬 수 있다.

Intersection을 이용한 이미지 레이지로더 커스텀 훅 예시 (이를 제공하는 외부 라이브러리가 있지만 직접 만들어서 사용해보는 것을 추천)

import { useEffect, useRef, useState } from 'react'

interface Params {
	src: string
}

const useLazyImageObserver = ({ src }: Params) => {
	const [imageSrc, setImageSrc] = useState<string | null>(null)
	const imageRef = useRef<HTMLImageElement>(null)
	
	useEffect(() => {
		let observer: IntersectionObserver | null = null
		if (imageRef && !imageSrc) {
		observer = new IntersectionObserver(
			([entry]) => {
				if (entry.isIntersecting) {
					setImageSrc(src)
					observer!.unobserve(imageRef.current!)
				}
			},
			{ threshold: [0.25] }
		)
		observer.observe(imageRef.current!)
		}

	}, [imageRef, imageSrc, src])
	
	return { imageSrc, imageRef }

}

export default useLazyImageObserver

❗️Error : Can't find variable: IntersectionObserver

해당 에러가 일어나는 경우는 드물지만 배포 후 서비스를 운영할 때 경험을 했던 문제이다.
이 문제가 일어날 수 있는 경우:

  • 특정 브라우저 혹은 브라우저 버젼에서 IntersectionObserver을 지원하지 않음
  • IntrersectionObserver은 브라우저 빌트인 API이기 때문에 Node환경에서 코드가 실행이 되었다면 지원이 되지 않음 (window가 없는 경우)

Fix:

import { useEffect, useRef, useState } from 'react'

interface Params {
	src: string
}

const useLazyImageObserver = ({ src }: Params) => {
	const [imageSrc, setImageSrc] = useState<string | null>(null)
	const imageRef = useRef<HTMLImageElement>(null)
	
	useEffect(() => {
		let observer: IntersectionObserver | null = null
		if (imageRef && !imageSrc && 'IntersectionObserver' in window) {
		observer = new IntersectionObserver(
			([entry]) => {
				if (entry.isIntersecting) {
					setImageSrc(src)
					observer!.unobserve(imageRef.current!)
				}
			},
			{ threshold: [0.25] }
		)
		observer.observe(imageRef.current!)
		}

	}, [imageRef, imageSrc, src])
	
	return { imageSrc, imageRef }

}

export default useLazyImageObserver
  • 'IntersectinObserver' in window 조건을 통해 IntersectionObserver의 여부를 확인하고 있을 때 만 실행하는 방법으로 간단한 수정이 가능
  • Can I use: IntersectionObserver
profile
조하운

0개의 댓글