lazy loading은 페이지 내에서 실제로 필요로 할 때까지 리소스의 로딩을 미루는 것입니다. 페이지를 로드하자마자 리소스를 로딩하는 일반적인 방식 대신, 실제로 사용자 화면에 보여질 필요가 있을 때까지 이러한 로딩을 지연하는 것 입니다.
lazy loading을 다루는 방식은 페이지 내의 거의 모든 리소스에서 적용할 수 있습니다. 예를 들어, SPA내에서 JS 파일이 나중에까지 필요로 하지 않으면 초기에 로드하지 않는 것이 가장 좋습니다. 또한, 이미지가 미리 보여질 필요가 없는 경우 나중에 로드하는 방식으로도 적용할 수 있습니다.
웹 페이지 내에서 이미지는 <img>
태그와 css 속성 중 background를 이용해서 로드할 수 있습니다.
먼저 <img>
태그를 사용하는 방법을 알아보겠습니다.
<img>
태그를 이용하는 방법lazy loading 이미지는 두 단계의 과정을 통해 이뤄집니다.
첫째로, 이미지 로딩을 사전에 막는 것 입니다.
일반적으로 <img>
태그의 src
속성을 이용해서 이미지를 로드합니다. 그러므로 이 src
속성 대신 다른 속성에다가 이미지 URL을 넣게 되면 src
속성이 비워져 있기 때문에 브라우저가 트리거하지 않습니다. 예를들어 다음과 같이 이미지 URL을 지정했다고 가정해봅시다.
<img data-src="http://기본_이미지_소스.jpg" />
src
가 아니라 data-src
로 이미지로드를 사전에 막았으니 이제 브라우저에게 해당 이미지를 언제 로딩할 것인지를 알려주어야 합니다. 이를 위해서는 해당 이미지가 뷰포트에 들어오자마자 로딩할 수 있도록 확인해야 합니다. 확인할 수 있는 방법은 또 두가지가 있습니다.
브라우저 내의 scroll
, resize
, orientationChage
이벤트 리스너를 이용해서 image load를 실행시킬 수 있습니다.
이 이벤트들 중 하나가 발생할 때 로딩이 지연되었거나 아직 로딩되지 않은 이미지들을 모두 찾습니다. 윈도우 높이, 현재 스크롤의 위치, 이미지의 위치 등을 이용해서 어떤 이미지가 뷰포트 안으로 들어왔는지를 확인합니다. 뷰포트 안으로 들어가면 data-src
의 속성에 지정된 URL을 src
속성에 넣어서 이미지를 로드합니다.
Intersection Observer API는 엘리먼트 요소가 뷰포트에 들어가는 것을 감지하고 액션을 취하는 것을 간단하게 만들어줍니다. 이미지 로드를 지연시키기 위해 모든 이미지에 옵저버를 부착시킵니다. 엘리먼트가 뷰포트에 들어간 것은 API가 감지했을 때, isIntersecting 속성을 이용해서 URL을 data-src 속성에서 src 속성으로 이동시켜서 브라우저가 이미지를 로드하도록 트리거를 일으킵니다.
하지만 아직 Intersection Observer API는 모든 브라우저에 지원되고 있지 않습니다. 해당 브라우저가 지원되지 않는 브라우저에서는 자바스크립트 이벤트를 이용해야 합니다.
background image는 <img>
태그 다음으로 웹 페이지에서 가장 많이 쓰이는 이미지 로딩 방식입니다. 간단하게 말하면 엘리먼트가 뷰포트에 들어올 때까지 css background image 속성을 적용하지 않도록 하면 됩니다.
브라우저는 초기의 엘리먼트에게 background-image: none;
속성을 적용하고 뷰포트에 이미지가 들어왔을 때 엘리먼트가 background image를 로드하도록 속성을 적용합니다.