بارگذاری تنبل تصاویر

با بارگذاری تنبل تصاویر در صفحات وب می‌توان افزایش چشمگیری در سرعت سایت به خصوص بارگذاری اولیه صفحات مشاهده کرد. در image lazy loading بارگذاری تصاویری که در دید کاربر به نزدیک شدن اسکرول کاربر به آن موکول می‌شود.

استفاده از بارگذاری تنبل یا lazy-loading در تصاویر

در یک صفحه وب می‌توان تصاویر را به شیوه‌های مختلفی نمایش داد، تصاویر در HTML به‌صورت عناصر یا تصاویر پس‌زمینه CSS قرار دارند. در این مقاله می‌آموزیم که چگونه هر دو نوع تصویر را به‌صورت lazy loading بارگذاری کنیم.

تصاویر درون خطی(Inline)

رایج‌ترین گزینه‌های بارگذاری تنبل، تصاویری هستند که در عناصر <img> استفاده می‌شوند. برای تصاویر درون خطی(Inline) سه گزینه برای بارگذاری تنبل داریم که گاهی ممکن است به صورت ترکیبی برای سازگاری در بین مرورگرها مختلف استفاده شود:

استفاده از بارگذاری تنبل تصاویر در سطح مرورگر

کروم و فایرفاکس هر دو از بارگذاری تنبل تصاویر با ویژگی loading پشتیبانی می‌کنند. این ویژگی را می توان به عناصر <img> و همچنین به عناصر <iframe> اضافه کرد. خاصیت  lazy به مرورگر می‌گوید که اگر تصویر در پنجره دید کاربر(viewport) است، فوراً آن را بارگیری کند و برای سایر تصاویر تا زمانی که کاربر به نزدیک آنها نرسیده است آنها را بارگیری نکند.

مقاله : بارگذاری تنبل تصاویر در سطح مرورگر

توجه: <iframe loading="lazy"> در حال حاضر استاندارد نیست، در حالی که در Chromium پیاده‌سازی شده‌است، هنوز توسط ارگان‌های مهم استاندارد سازی تثبیت نشده است. پیشنهاد می‌کنیم تا زمان تثبیت و استاندارد شدن از بارگذاری تنبل iframes ها اجتناب کنید.

برای دیدن جزئیات پشتیبانی مرورگرها از بارگذاری تنبل تصاویر، به قسمت browser compatibility  مرجع MDN مراجعه کنید. اگر مرورگر از بارگذاری تنبل پشتیبانی نکند، این ویژگی نادیده گرفته می‌شود و طبق معمول، تصاویر بلافاصله بارگیری می‌شوند.

برای اکثر وب‌سایت‌ها، افزودن این ویژگی به تصاویر درون خطی باعث بهبود سرعت و عملکرد سایت می‌شود و کاربران را از هزینه و زمان بارگذاری تصاویری که ممکن است هرگز روی آن‌ها اسکرول نکنند، نجات می‌دهد. اگر تعداد زیادی عکس دارید و می‌خواهید مطمئن شوید که همه کاربران (حتی آنهایی که مرورگرشان از image lazy loading پشتیبانی نمی‌کند) به خوبی از تصاویر بهره ببرند باید از ترکیب این روشها استفاده کنید.

بارگذاری تنبل تصاویر با استفاده از Intersection Observer

برای تکمیل بارگذاری تنبل عناصر <img> ، از جاوا اسکریپت استفاده می کنیم تا بررسی کنیم که آیا آنها در viewport هستند یا خیر. در صورت وجود، ویژگی‌های src  (و گاهی اوقات srcset) آنها با URLهای محتوای تصویر مورد نظر پر می‌شوند.

اگر قبلاً کدهایی با بارگذاری تنبل نوشته‌اید، ممکن است کار خود را با استفاده از کنترل‌کننده‌های رویداد مانند scroll یا تغییر اندازه (resize) انجام داده باشید. در حالی که این رویکرد در بین مرورگرها سازگارترین است، مرورگرهای مدرن روشی کارآمدتر و کارآمدتر برای انجام کار بررسی قابلیت مشاهده عناصر از طریق the Intersection Observer API. ارائه می‌دهند.

Intersection Observer در همه مرورگرها، به ویژه IE11 و پایین‌تر، پشتیبانی نمی‌شود. اگر سازگاری در بین مرورگرها بسیار مهم است، حتماً بخش بعدی را بخوانید، که به شما نشان می‌دهد چگونه با استفاده از کنترل‌کننده‌های رویداد با سرعت کمتر (اما سازگارتر!) تصاویر را بارگذاری کنید.

پشتیبانی از Intersection Observer

دسکتاپ

کرومفایرفاکسIEEdgeSafari
5855No1612.1

موبایل و تبلت

کروم اندرویدفایرفاکس اندرویدمرورگر اندرویدسافاری ای او اس
98969812.2-12.5

استفاده و خواندن از Intersection Observer نسبت به نوشتن کد سفارشی با تکیه بر کنترل‌کننده‌های مختلف رویداد آسان‌تر است، زیرا شما فقط باید یک ناظر را برای تماشای عناصر به جای نوشتن کد تشخیص دید عنصر خسته‌کننده ثبت کنید. تنها کاری که باید انجام دهید این است که تصمیم بگیرید وقتی یک عنصر قابل مشاهده است چه کاری انجام دهید. بیایید این الگوی نشانه گذاری اولیه را برای عناصر <img> شما که با تنبلی بارگذاری شده‌اند امتحان کنیم.

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

در مورد کد html بالا سه نکته مهم وجود دارد که باید به آنها توجه کنیم:

  • ویژگی class، همان چیزی است که عنصر را با آن در جاوا اسکریپت انتخاب می کنید.
  • ویژگی src، که به یک تصویر مکان نگهدار اشاره می کند که هنگام بارگیری صفحه برای اولین بار ظاهر می شود.
  • ویژگی‌های data-src و data-srcset، که ویژگی‌های نگهدارنده مکان حاوی URL برای تصویری هستند که پس از قرار گرفتن عنصر در viewport بارگیری می‌کنید.

حال با استفاده از Intersection Observer در جاوا اسکریپت تصویر html بالا را به صورت تنبل بارگذاری می‌کنیم:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });
    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

در رویداد DOMContentLoaded صفحه ، برای تمامی تصاویری که کلاس آنها lazy است، یک ناظر جدید ایجاد می‌کنیم تا زمانی که عناصر img.lazy وارد viewport کاربر می شوند، تصویر اصلی جایگزین تصویر مکان نگه دار شود.

Intersection Observer در تمام مرورگرهای مدرن پشتیبانی می‌شود. بنابراین استفاده از آن تضمین می‌کند که بارگذاری تنبل برای اکثر بازدیدکنندگان در دسترس خواهد بود.البته این امکان در اینترنت اکسپلورر موجود نیست و اگر پشتیبانی از اینترنت اکسپلورر برای شما مهم است از این روش صرف نظر کنید.

استفاده از کنترل کننده رویداد(event handlers) برای بارگذاری تنبل تصاویر

اگر تعدادی از کاربران شما از Intersection Observer پشتیبانی نمی‌کنند می‌توانید در کنار استفاده از Intersection Observer برای مرورگرهای مدرن، از کنترل‌کننده‌های رویداد برای مرورگرهای قدیمی استفاده کنید. می‌توانید با استفاده از رویدادهای اسکرول، تغییر اندازه و … تعیین کنید که آیا یک عنصر در viewport است یا خیر و بعد از آن اقدام به لود تصویر اصلی کنید.

document.addEventListener("DOMContentLoaded", function() {
  let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
  let active = false;

  const lazyLoad = function() {
    if (active === false) {
      active = true;

      setTimeout(function() {
        lazyImages.forEach(function(lazyImage) {
          if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") {
            lazyImage.src = lazyImage.dataset.src;
            lazyImage.srcset = lazyImage.dataset.srcset;
            lazyImage.classList.remove("lazy");

            lazyImages = lazyImages.filter(function(image) {
              return image !== lazyImage;
            });

            if (lazyImages.length === 0) {
              document.removeEventListener("scroll", lazyLoad);
              window.removeEventListener("resize", lazyLoad);
              window.removeEventListener("orientationchange", lazyLoad);
            }
          }
        });

        active = false;
      }, 200);
    }
  };

  document.addEventListener("scroll", lazyLoad);
  window.addEventListener("resize", lazyLoad);
  window.addEventListener("orientationchange", lazyLoad);
});

کد بالا تقریباً در هر مرورگری کار می‌کند امابه دلیل فراخوانی مکرر setTimeout باعث مشکلاتی برای سرعت صفحه خواهد، اگر هدف ما از بارگذاری تنبل افزایش سرعت لود اولیه صفحه باشد در صفحات با تصاویر زیاد استفاده از این متد نتیجه عکس خواهد داد و فراخوانی مکرر کدها باعث کند شدن صفحه خواهد شد.

به بیان ساده: تا جایی که ممکن است از بارگذاری تنبل با Intersection Observer استفاده کنید و تنها در صورتی از کنترل کننده رویداد استفاده کنید که نیاز به سازگاری با مرورگرهای قدمی بسیار ضروری باشد.

کتابخانه هایی برای بارگذاری تنبل تصاویر

از کتابخانه های زیر می‌توان برای بارگذاری تنبل تصاویر استفاده کرد.

  • lazysizes یک کتابخانه با امکانات کامل برای تصاویر lazy-loading است که می‌تواند علاوه بر تصاویر، iframe ها را نیز با تنبلی بارگذاری کند. الگویی که این کتابخانه از آن استفاده می‌کند کاملاً شبیه به نمونه‌ کدهای بالا است، زیرا به‌طور خودکار به یک کلاس lazyload در عناصر <img> متصل می‌شود و از شما می‌خواهد URLهای تصویر را در ویژگی‌های data-src و/یا data-srcset مشخص کنید، محتویات که به ترتیب با ویژگی های src و/یا srcset مبادله می شوند.
  • vanilla-lazyload یک گزینه سبک وزن برای بارگذاری تنبل تصاویر، تصاویر پس زمینه، فیلم ها، iframe ها و اسکریپت ها است. vanilla-lazyload نیز از Intersection Observer استفاده می‌کند، از تصاویر واکنش‌گرا پشتیبانی می‌کند و بارگذاری تنبل در سطح مرورگر را فعال می‌کند.
  •  lozad.js یک گزینه سبک وزن دیگر است که فقط از Intersection Observer استفاده می کند. به این ترتیب، کارایی بالایی دارد.
  •  yall.js کتابخانه ای است که از Intersection Observer استفاده می کند و به کنترل کننده رویداد باز می گردد. این کتابخانه با IE11 و مرورگرهای اصلی سازگار است.
  •  اگر به یک کتابخانه Lazy-loading خاص React نیاز دارید، react-lazyload می‌تواند به شما کمک کند. این ابزار از Intersection Observer استفاده نمی کند بلکه روشی آشنا برای image lazy loading برای کسانی که به توسعه برنامه ها با React عادت دارند ارائه می دهد.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.