여러장의 이미지를 빠르게 전환하여 우리 눈에 잔상을 남기고 이를 움직이는 것처럼 느끼게 하는 것
Q. 만약 한 장의 이미지가 빠지게 된다면?
A. 끊어지는 것처럼 보임(== jank 효과)
jank효과가 나타나는 원인은 브라우저가 정상적인 프레임으로 화면을 그리지 못했기 때문이다!
position, display, width, float, height, font-family, top, left,
font-size, font-weight, lint-height, min-height, margin, padding, border 등
background, background-image, background-position, border-radius, border-style,
bod-shadow, color, line-style, outline 등
앞서 보았듯이 리플로우와 리페인트가 일어나게 되면 렌더링 과정을 한번 더 거치기 때문에 성능 저하가 발생할 수 있다. 즉, 브라우저 리소스를 많이 사용하게 된다!
transform
, opacity
와 같은 속성을 사용한다.
=> GPU에 위임하여 처리하여 레이아웃 단계와 페인트 단계를 건너뛸 수 있다.(===하드웨어 가속)
GPU는 애초에 그래픽 작업을 위해 만들어진 것이므로 화면을 그릴 때 활용하면 굉장히 빠르다.
transform 참고 문서를 숙지하도록 하자!
단일 컴포넌트를 분할하여 컴포넌트가 쓰이는 순간에 불러오는 기법
const LazyImageModal = lazy(() => import('./components/ImageModal'));
...
<Suspense fallback={null}>
{showModal ? (
<LazyImageModal
closeModal={() => {
setShowModal(false);
}}
/>
) : null}
</Suspense>
ImageModal과 종속되어 있는 라이브러리도 분리가 된다.
즉, 참조하는 모든 라이브러리가 함께 묶여 분할되기 때문에 속도를 줄일 수 있다.
필요한 시점보다 먼저 다운로드해 두고, 필요 시 바로 보여줄 수 있도록 하는 기법
지연 로딩은 최초 페이지 로드 시 효율적이라는 장점이 있다. 하지만, 사용자의 시점에 결정되는 요소들이라면 효율적이지 않을 수 있다. => 사전 로딩으로 해결해보자!
const handleMouseEnter = () => {
const component = import('./components/ImageModal');
};
...
<ButtonModal
onClick={() => { setShowModal(true); }}
onMouseEnter={ handleMouseEnter }
>
...
useEffect(() => {
const component = import('./components/ImageModal');
}, []);
로딩 시 중요한 점은 어느 타이밍에서 사전 로드하는 것이 가장 합리적인지 판단하는 일이다.
이미지가 화면에 제때 뜰 수 있도록 미리 다운로드하는 기법
이미지는 화면에 그려지는 시점, 즉 HTML/CSS에서 이미지를 사용하는 시점에 로드된다.
js에선 Image 객체를 사용하는 방법이 있다.
모든 이미지가 아닌, 모달의 첫 페이지에 쓰이는 이미지를 사전 로딩 해보자.
// 모달 사전 로드 이후 진행
useEffect(() => {
const component = import('./components/ImageModal');
const img = new Image();
img.src = 'https://stillmed.olympic.org/media/Photos/2016/08/20/part-1/20-08-2016-Football-Men-01.jpg?interpolation=lanczos-none&resize=*:800';
}, []);
여기서, 몇 장의 이미지까지 사전 로드해 둘 것인지 의문이 들었다.
이미지 사전 로딩 기법은 정말 사전 로딩이 필요한지 아닌지 스스로 고민해야 한다!