이미지를 로딩후 삽입하기.
img 태그의 load 이벤트리스너를 이용해서 로딩을 시킨 후 이미지를 삽입하는 코드.
const loadImg = function (url, callback) { const img = document.createElement('img'); img.src = url; img.addEventListener('load', function () { callback(img); }); } const containerEl = document.querySelector('.container'); loadImg('https://picsum.photos/200/300', function (img) { containerEl.innerHTML = ''; containerEl.appendChild(img); });
이미지태그를 생성해서 이미지를 로드 후 이미지를 삽입하는 형식!
이러면 이미지태그가 새로 생성되기 때문에 이미지를 2번 로드하는것이 아니냐는
의문이 들 수 있는데,
브라우저는 이미지 url을 캐싱하기때문에
2번 패칭하는 일은 일어나지 않는다.
lazy load 예제
interception observer api 를 사용해서 이미지를 로딩하는예제.
뷰포트에 들어오기전까지 이미지를 로딩하지 않는다

img 출처: ‣
<!-- src를 비워두고 data-src에 값 전달 --> <img data-src="image.jpg" alt="Lazy Loaded Image" class="lazy-image">
const images = document.querySelectorAll('.lazy-image'); const options = { root: null, // 뷰포트가 기준 rootMargin: '0px', threshold: 0.1 }; const callback = (entries, observer) => { entries.forEach(entry => { // 교차되면 src 삽입 if (entry.isIntersecting) { const img = entry.target; img.src = img.getAttribute('data-src'); observer.unobserve(img); // 관찰 중지 } }); }; const observer = new IntersectionObserver(callback, options); images.forEach(image => { observer.observe(image); });
react 에서 응용
import React, { useEffect, useRef, useState } from 'react'; function LazyImage({ src, alt }) { const imgRef = useRef(null); const [isLoaded, setIsLoaded] = useState(false); useEffect(() => { const options = { root: null, threshold: 0.1, }; const callback = (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { setIsLoaded(true); observer.unobserve(entry.target); } }); }; const observer = new IntersectionObserver(callback, options); if (imgRef.current) { observer.observe(imgRef.current); } return () => { if (imgRef.current) { observer.unobserve(imgRef.current); } }; }, []); return ( <img ref={imgRef} src={isLoaded ? src : ''} alt={alt} style={{ minHeight: '200px', backgroundColor: '#f0f0f0' }} /> ); } export default LazyImage;
use inview 라이브러리 활용
훅으로 만들어져있어 편하게 활용가능
import React from 'react'; import { useInView } from 'react-intersection-observer'; function LazyImage({ src, alt }) { const { ref, inView } = useInView({ threshold: 0.1, triggerOnce: true, }); return ( <img ref={ref} src={inView ? src : ''} alt={alt} style={{ minHeight: '200px', backgroundColor: '#f0f0f0' }} /> ); } export default LazyImage;
