lazyload

Z6su3ยท2022๋…„ 4์›” 19์ผ
1

JavaScript

๋ชฉ๋ก ๋ณด๊ธฐ
6/7

๐Ÿ‡ What is lazyloadโ“

์‹ค์ œ ์ด๋ฏธ์ง€๊ฐ€ ํ™”๋ฉด์— ๋ณด์—ฌ์งˆ ํ•„์š”๊ฐ€ ์žˆ์„ ๋•Œ, ๋กœ๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์ˆ 

์ฆ‰, ์›น ํŽ˜์ด์ง€ ๋‚ด ๋ฐ”๋กœ ๋กœ๋”ฉ์„ ํ•˜์ง€ ์•Š๊ณ  ๋กœ๋”ฉ ์‹œ์ ์„ ๋’ค๋กœ ๋ฏธ๋ฃจ๋Š” ๊ฒƒ

Image๋ฟ ์•„๋‹ˆ๋ผ SPA๋‚ด JSํŒŒ์ผ ๋กœ๋“œ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

๐Ÿ‡ Why useing?

๐Ÿฅ• Improved Performance

์„ฑ๋Šฅํ–ฅ์ƒ์€ ์›น ์‚ฌ์ดํŠธ ๋กœ๋”ฉ ์‹œ๊ฐ„, ์„ฑ๋Šฅ ๊ด€๋ฆฌ ์ธก๋ฉด์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

lazy loading์„ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค ์š”์ฒญ์„ ์ค„์ด๊ณ , ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋ฅผ ๋” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด, ์œ ์ €๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•  ๋•Œ ๋” ๋นจ๋ฆฌ ํ™•์ธํ•˜๊ณ  ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿฅ• Cost Reduction

ํ†ต์‹  ๋น„์šฉ ๊ด€์ ์— ์žˆ์–ด ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ด๋ฏธ์ง€ ์ „๋‹ฌ ๊ด€๋ จ์€ ์ „์†ก ๋ฐ”์ดํŠธ ์ˆ˜์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ์ฒญ๊ตฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๊ฐ€ ๋ณด์—ฌ์ง€์ง€ ์•Š์œผ๋ฉด ์ ˆ๋Œ€ ๋กœ๋”ฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ํŽ˜์ด์ง€ ๋‚ด ์ „๋‹ฌํ•  ์šฉ๋Ÿ‰์ด ์ค„์–ด๋“ค์–ด ์ „์†ก๋น„์šฉ์ด ๊ฐ์†Œ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ‡ How to use?

Image tag

์ด๋ฏธ์ง€๋Š” ํƒœ๊ทธ๋‚ด src์†์„ฑ์„ ํ†ตํ•ด ์ด๋ฏธ์ง€๋Š” ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰ ๋ธŒ๋ผ์šฐ์ € ๋‚ด ์ด๋ฏธ์ง€๊ฐ€ src์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ์ด๋ฏธ์ง€๋Š” ๋ฌด์กฐ๊ฑด ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ ์ž ์ด๋ฏธ์ง€์˜ url์„ ๋‹ค๋ฅธ ์†์„ฑ์— ํ• ๋‹นํ•˜์—ฌ ์ด๋ฏธ์ง€์˜ ๋กœ๋”ฉ์„ ์ง€์—ฐ์‹œํ‚ต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<img src="https://sampleImage.jpg">
โ†“
<img data-src="https://sampleImage.jpg">

์ดํ›„ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด๋ฏธ์ง€๊ฐ€ ๋ทฐํฌํŠธ์— ๋“ค์–ด์™”์„ ๋•Œ ๋กœ๋”ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ™•์ธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฅ• JavaScript Event

scroll, resize, orientationChange ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

  • lazy loading์„ ์œ„ํ•ด์„œ resize, orientationChange ์ด๋ฒคํŠธ๋Š” ๊ฐ™์ด ์‚ฌ์šฉ
  • resize๋Š” ์œˆ๋„์šฐ ๋ธŒ๋ผ์šฐ์ € ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€” ๋•Œ ๋ฐœ์ƒ
  • orientationChange๋Š” ๋””๋ฐ”์ด์Šค์˜ ๊ฐ€๋กœ/์„ธ๋กœ๊ฐ€ ๋ณ€ํ™˜๋  ๋•Œ ๋ฐœ์ƒ

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ Image lazy loading์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค

  • ๋กœ๋”ฉ์ด ์ง€์—ฐ๋˜๊ฑฐ๋‚˜ ๋˜์ง€ ์•Š์€ ์ด๋ฏธ์ง€๋ฅผ ๋ชจ๋‘ ์ฐพ์Œ
  • ์œˆ๋„์šฐ ๋†’์ด, ํ˜„์žฌ ์Šคํฌ๋กค ์œ„์น˜, ์ด๋ฏธ์ง€ ์œ„์น˜๋ฅผ ์ด์šฉํ•ด ๋ทฐํฌํŠธ๋กœ ๋“ค์–ด์˜จ ์ด๋ฏธ์ง€ ํŒ๋ณ„
  • ๋ทฐํฌํŠธ ์•ˆ์— ๋“ค์–ด์˜ค๋ฉด data-src์†์„ฑ์„ src์†์„ฑ์— ๋„ฃ์–ด ์ด๋ฏธ์ง€ ๋กœ๋“œ
  • ๋กœ๋”ฉ ์ง€์—ฐ์„ ํŒ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์„ ์–ธํ•œ lazyํด๋ž˜์Šค ์ œ๊ฑฐ
  • ๋ชจ๋“  ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋”ฉ๋˜๋ฉด ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ํŠธ๋ฆฌ๊ฑฐ ์ œ๊ฑฐ
document.addEventListener("DOMContentLoaded", function() {
	//์ด๋ฏธ์ง€๋ฅผ ๋ชจ๋‘ ์ฐพ์Œ
  var lazyloadImages = document.querySelectorAll("img.lazy");    
  var lazyloadThrottleTimeout;
  
  function lazyload () {
    if(lazyloadThrottleTimeout) {
      clearTimeout(lazyloadThrottleTimeout);
    }    
    
    lazyloadThrottleTimeout = setTimeout(function() {
				//ํ˜„์žฌ ๋ทฐ ํฌํŠธ
        var scrollTop = window.pageYOffset;
				//๋ทฐ ํฌํŠธ๋กœ ๋“ค์–ด์˜จ ์ด๋ฏธ์ง€ ํŒ๋ณ„
        lazyloadImages.forEach(function(img) {
            if(img.offsetTop < (window.innerHeight + scrollTop)) {
							//src์†์„ฑ์— data-src์†์„ฑ ๊ฐ’ ๋„ฃ์–ด ์ด๋ฏธ์ง€ ๋กœ๋“œ
              img.src = img.dataset.src;
							//lazyํด๋ž˜์Šค ์ œ๊ฑฐ
              img.classList.remove('lazy');
            }
        });
				//์ด๋ฏธ์ง€๊ฐ€ ์ „๋ถ€ ๋กœ๋”ฉ๋˜๋ฉด ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์ œ๊ฑฐ
        if(lazyloadImages.length == 0) { 
          document.removeEventListener("scroll", lazyload);
          window.removeEventListener("resize", lazyload);
          window.removeEventListener("orientationChange", lazyload);
        }
    }, 20);
  }
  
	//์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์ ์šฉ
  document.addEventListener("scroll", lazyload);
  window.addEventListener("resize", lazyload);
  window.addEventListener("orientationChange", lazyload);
});

๐Ÿฅ• Intersection Observer API

์š”์†Œ๊ฐ€ ๋ทฐํฌํŠธ์— ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์„ API๊ฐ€ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ˆœ์„œ์— ๋”ฐ๋ผ Image lazy loading์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • ์š”์†Œ์— ์˜ต์ €๋ฒ„ ๋ถ€์ฐฉ
  • ๋ทฐํฌํŠธ์— ์š”์†Œ๊ฐ€ ๋“ค์–ด์™”์Œ์„ API๊ฐ€ ๊ฐ์ง€
  • isIntersecting์†์„ฑ์œผ๋กœ data-src์˜ url์„ src์†์„ฑ์œผ๋กœ ๋ณ€๊ฒฝ
  • ์ „๋ถ€ ๋กœ๋“œ๋˜๋ฉด lazyํด๋ž˜์Šค๋ช… ์‚ญ์ œ
  • ๋ถ€์ฐฉํ–ˆ๋˜ ์˜ต์ €๋ฒ„ ์ œ๊ฑฐ
document.addEventListener("DOMContentLoaded", function() {
  var lazyloadImages;    

  if ("IntersectionObserver" in window) {
    lazyloadImages = document.querySelectorAll(".lazy");
    var imageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          var image = entry.target;
          image.src = image.dataset.src;
          image.classList.remove("lazy");
          imageObserver.unobserve(image);
        }
      });
    });

    lazyloadImages.forEach(function(image) {
      imageObserver.observe(image);
    });
  } 
})

Intersection Observer๋ฅผ ํ™œ์šฉํ•˜์˜€์„ ๋•Œ, ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กค ์‹œ ์ด๋ฏธ์ง€๊ฐ€ ๋Š๋ฆฌ๊ฒŒ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ™œ์šฉํ•œ ๋ฐฉ์‹์—์„œ timeout์„ ํ™œ์šฉํ•˜์—ฌ ์•ฝ๊ฐ„์˜ ๋”œ๋ ˆ์ด๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๐Ÿฅ• Native lazy loading

์ด๋ฏธ์ง€์— loading์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ฉด lazy loading์ด ์‰ฝ๊ฒŒ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” loading์†์„ฑ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค.

  • lazy : ๋ทฐ ํฌํŠธ์—์„œ ์ผ์ • ๊ฑฐ๋ฆฌ์— ๋‹ฟ์„ ๋•Œ๊ฐ€์ง€ ๋กœ๋”ฉ์„ ์ง€์—ฐ์‹œํ‚ต๋‹ˆ๋‹ค.
  • eager : ํ˜„์žฌ ํŽ˜์ด์ง€ ์œ„์น˜๊ฐ€ ์œ„/์•„๋ž˜ ์–ด๋””์— ์žˆ๋“  ์ƒ๊ด€์—†์ด, ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋”ฉ๋˜์ž๋งˆ์ž ํ•ด๋‹น ์š”์†Œ๋ฅผ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.
  • auto : ๋กœ๋”ฉ์„ ์ง€์—ฐํ•˜๋Š” ๊ฒƒ์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ loading์†์„ฑ์„ ์“ฐ์ง€ ์•Š๋Š”๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๋กœ๋”ฉ์ด ์ง€์—ฐ๋œ ์ด๋ฏธ์ง€๊ฐ€ ๋ถˆ๋Ÿฌ์™€์งˆ ๋•Œ, ๋‹ค๋ฅธ ์ฝ˜ํ…์ธ  ๋‚ด์šฉ์ด ๋ฐ€๋ ค๋‚˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ, ๋ฐ˜๋“œ์‹œ width/height ์†์„ฑ์„ imgํƒœ๊ทธ ๋˜๋Š” inline style๋กœ ์ง์ ‘ ๊ฐ’์„ ์ง€์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

profile
๊ธฐ์–ต์€ ๊ธฐ๋ก์„ ์ด๊ธธ์ˆ˜ ์—†๋‹ค

0๊ฐœ์˜ ๋Œ“๊ธ€