لود تنبل (Lazy Loading) چیست؟ قسمت دوم: روش های پیاده سازی

12 آبان 1397
lazy-loading-ways

انواع مختلف تکنیک های پیاده سازی Lazy Loading

با سلام و احترام خدمت شما خوانندگان فرهیخته؛ با قسمت دوم از مبحث Lazy Loading در خدمت شما هستم. می توانید قسمت اول را در این لینک بخوانید. در این قسمت از مقاله شما را با 5 روش مختلف از لود تنبل آشنا می کنیم. این 5 روش پرطرفدار ترین روش های حال حاضر برای پیاده سازی لود تنبل می باشند.

روش اول: روش ساده ی دیوید والش (David Walsh)

آقای والش اسکریپت اختصاصی خودشان را برای لود تنبل (Lazy Loading) پیشنهاد داده اند. این روش به این شکل است که ویژگی src مربوط به یک عکس در متن HTML با ویژگی data-src جایگزین می شود:

<img data-src="image.jpg" alt="test image">

در فایل های CSS عنصر مورد نظر با ویژگی data-src مخفی است و زمانی که بارگذاری شد توسط افکت انتقال نرم CSS نمایان می شود.

img {
  opacity: 1;
  transition: opacity 0.3s;
}

img[data-src] {
  opacity: 0;
}

حالا جاوا اسکریپت ویژگی src را به هر کدام از عناصر دارای تگ img اضافه می کند و مقدار آن را برابر با مقدار data-src قرار می دهد. سپس زمانی که تصویر بارگذاری شد، جاوا اسکریپت ویژگی data-src را از تمامی تصاویر حذف می کند.

[].forEach.call(document.querySelectorAll('img[data-src]'),    function(img) {
  img.setAttribute('src', img.getAttribute('data-src'));
  img.onload = function() {
    img.removeAttribute('data-src');
  };
});

آقای والش روش دیگری را برای زمانی که جاوا اسکریپت از کار می افتد نیز پیشنهاد داده اند؛ می توانید در مورد این روش بیشتر در وبلاگ دیوید والش بخوانید.

نکته ی مثبت این روش: اجرای آن بسیار ساده است.

نکته ی منفی این روش: از قابلیت بارگذاری در هنگام اسکرول پشتیبانی نمی کند؛ به عبارت دیگر مرورگر تمامی تصاویر را، فارغ از اینکه کاربر به قسمت خاصی از صفحه اسکرول کرده باشد یا خیر، بارگذاری می کند.

فرق این روش با حالت عادی چیست؟
 فرق این روش با حالت عادی چیست؟

تفاوت آنجا است که وب سایت تا بارگذاری تمام تصاویر منتظر نمی ماند و چشم انداز اولیه سریع تر به کاربر نمایش داده می شود (چشم انداز اولیه چیست؟) اما دیگر شاهد کاهش پنهای باند مصرفی نخواهیم بود چرا که تمامی تصاویر، مستقل از اسکرول کردن کاربر، بارگذاری خواهند شد.

روش دوم: روش رابین آزبورن (Robin Osborne)

پایه ی روش خانم آزبورن بر اساس پیشرفت تدریجی است.

دلیل نام گذاری این روش به چه صورت بوده است؟ چرا "پیشرفت"؟

به این دلیل که در این روش استفاده از جاوا اسکریپت برای بارگذاری تصاویر به جای حالت عادی (HTML و CSS)، یک پیشرفت محسوب می شود.

چرا "تدریجی" و مرحله ای؟

به این دلیل که اگر از روشی برای بارگذاری تصاویر استفاده کنیم که وابسته به جاوا اسکریپت باشد، با از کار افتادن جاوا اسکریپت یا نقص اسکریپت به هر دلیل ممکن است هیچ تصویری در سایت شما بارگذاری نشود!

اما این روش طوری عمل میکند تا در صورت از کار افتادن جاوا اسکریپت، باز هم تصاویر به مخاطب نمایش داده شود. ساختار ساده از پیاده سازی این روش را می توانید در این لینک ببینید و برای نگاه به ساختار پیچیده تر این روش به این لینک سر بزنید.

اسکریپت خالصِ این روش در حالت ساده به این شرح است (پروژه ی کامل در لینک بالا):

<script>
registerListener('load', setLazy);
registerListener('load', lazyLoad);
registerListener('scroll', lazyLoad);

var lazy = [];

function setLazy(){
    lazy = document.getElementsByClassName('lazy');
    console.log('Found ' + lazy.length + ' lazy images');
} 

function lazyLoad(){
    for(var i=0; i<lazy.length; i++){
        if(isInViewport(lazy[i])){
            if (lazy[i].getAttribute('data-src')){
                lazy[i].src = lazy[i].getAttribute('data-src');
                lazy[i].removeAttribute('data-src');
            }
        }
    }
    
    cleanLazy();
}

function cleanLazy(){
    lazy = Array.prototype.filter.call(lazy, function(l){ return l.getAttribute('data-src');});
}

function isInViewport(el){
    var rect = el.getBoundingClientRect();
    
    return (
        rect.bottom >= 0 && 
        rect.right >= 0 && 
        rect.top <= (window.innerHeight || document.documentElement.clientHeight) && 
        rect.left <= (window.innerWidth || document.documentElement.clientWidth)
     );
}

function registerListener(event, func) {
    if (window.addEventListener) {
        window.addEventListener(event, func)
    } else {
        window.attachEvent('on' + event, func)
    }
}
</script>

نکات مثبت این روش:

  •  کاربران در همه حال به محتوای کامل سایت شما دسترسی خواهند داشت.
  • نه تنها ملاحظاتی برای مواقعی دارد که جاوا اسکریپت غیر فعال است (مثلا در مرورگر)، بلکه فکر مواقعی که جاوا اسکریپت از کار می افتد و یا اسکریپت ما به خطایی بر میخورد را نیز کرده است.
  • تصاویر را بر اساس اسکرول کردن کاربر بارگذاری می کند بنابراین اگر کاربر به قسمت پایین صفحه اسکرول نکند تصاویر آن قسمت بیهوده بارگذاری نمی شود.
  • به هیچ منبع خارجی نیاز و وابستگی ندارد؛ بنابراین نه صحبتی از پلاگین ها به میان آمده و نه فریم ورک ها.

روش سوم: استفاده از پلاگین lazyloadxt (در جی کوئری)

برای استفاده ی سریع و بدون دردسر از این تکنیک می توانید این پلاگین را بعد از لود کردن جی کوئری در سورس کد خود، لود کنید.

این پلاگین دو نسخه دارد؛ نسخه ی اول یا jquery.lazyloadxt.js که مخصوص اجرای تکنیک لود تنبل یا Lazy Loading برای تصاویر است و نسخه ی دوم یا jquery.lazyloadxt.extra.js که مخصوص لود تنبل برای فیلم ها، iframe ها و تمام عناصری است که ویژگی src دارند. نمونه ی بارگذاری در سورس کد:

<script src="jquery.js"></script>
<script src="jquery.lazyloadxt.js"></script>

اگر پلاگین را به حال خود رها کنید به صورت اتوماتیک شروع به کار می کند اما اگر نیاز دارید در قسمتی از کد خود آن را به صورت دستی اجرا کنید می توانید مانند کد زیر عمل کنید:

$(elements).lazyLoadXT();

اگر از جی کوئری استفاده نمی کنید باید بدانید این پلاگین یک نسخه ی سبک تر با نام jqlight.lazyloadxt.min.js نیز ارائه می کند که نیازی به جی کوئری ندارد. نمونه ی بارگذاری:

<script src="jqlight.lazyloadxt.js"></script>
<script src="jquery.lazyloadxt.js"></script>

پس از لود این پلاگین، باید تمامی تصاویر در سورس کد خود را با ویژگی data-src (به جای src) وارد کنید.

این پلاگین ویژگی های بسیار زیادی را ارائه می دهد که توضیح تمامی آن ها در یک مقاله ممکن نیست؛ به طور مثال:

  • قابلیت پشتیبانی از Bootstrap و jQueryMobile و انواع افزونه های دیگر که روی پلاگین اصلی سوار می شوند.
  • نمایش علامت loading (دایره مانند) تا بارگذاری کامل تصویر با لود کردن jquery.lazyloadxt.spinner.css در صفحه ی خود.
  • اضافه کردن انواع و اقسام افکت های انتقال و غیره با لود کتابخانه ی Animate.css در صفحه ی خود. مثال استفاده در اسکریپت:
$.lazyLoadXT.onload.addClass = 'animated bounceOutLeft';
  • استفاده از CDN به جای بارگذاری روی سرور خودتان.
  • پشتیبانی از مرورگر هایی مثل IE6 تا IE11 و Opera mini
  • افکت های انتقال و انیمیشن های بسیار دیگر با استفاده از افزونه ها
  • و امکانات بسیار دیگر ...

قانون کلی در مورد کار با پلاگین ها، فریم وورک ها و هر نوع منابع اینترنتی

اکثر آنها قسمتی به نام documentation یا usage یا installation و ... دارند. قبل از استفاده حتما آن ها را بخوانید تا با روش کار و استفاده از آن ها آشنا شوید. اکثر این منابع به صورت متن باز نوشته شده اند و متعلق به کمپانی خاصی نیستند؛ بنابراین ممکن است از استاندارد های رایج وب پیروی نکنند و شما را سر در گم کنند.

روش چهارم: استفاده از پلاگین bLazy.js

پیاده سازی Lazy Loading با استفاده از beLazy.js

پلاگین bLazy.js یک پلاگین لود تنبل سبک (حجم حدود 1.2 کیلوبایت پس از Gzip و minify شدن) و مستقل برای جاوا اسکریپت است. به نقل از وبسایت رسمی bLazy :

bLazy is a lightweight lazy loading image script (less than 1.2KB minified and gzipped). It lets you lazy load and multi-serve your images so you can save bandwidth and server requests. The user will have faster load times and save data loaded if he/she doesn’t browse the whole page.

 

 نکات زیر از ویژگی های مثبت آن به شمار می روند:

  • اجرای تکنیک لود تنبل روی تصاویرِ متن و تصاویر پس زمینه
  • بارگذاری تصاویر متفاوت بر اساس سایز صفحه ی دستگاه کاربر
  • اجرای تکنیک لود تنبل بر روی هر عنصری با ویژگی src
  • پشتیبانی از مرورگر های قدیمی مثل IE7 و IE8
  • استفاده از CDN

مثال ساده از بارگذاری:

<img class="b-lazy" src="placeholder.gif" data-src="image.jpg" alt="test image">

حالا باید تگ img را به شکل زیر تغییر دهید:

- کلاس .b-lazy را اضافه کنید.

- از یک عکس دلخواه به عنوان placeholder برای ویژگی src استفاده کنید.

سپس می توانید در جاوااسکریپت blazy را صدا بزنید و تغییرات خود را اعمال کنید:

var bLazy = new Blazy({
  //options here
});

برای اطلاعات بیشتر:

وب سایت blazy

مثال هایی از blazy

صفحه ی blazy در گیت هاب

روش پنجم: اثر بلوری در لود تنبل (Lazy Loading)

اگر به مثالی که در قسمت قبل از وب سایت Medium ذکر کردیم توجه کرده باشید متوجه این مورد خواهید شد. تصاویر در وب سایت Medium قبل از بارگذاریِ کامل، به صورت تار و بلوری دیده می شوند؛ مثال تصویری:

 

Blur بودن تصاویر در Lazy Loading وب سایت Medium

روش های مختلفی برای پیاده سازی این تکنیک وجود دارد اما از نظر من روش بهتر، روش Craig Buckler است. مزیت های این روش:

  • تنها 463 بایت CSS و 1007 بایت جاوا اسکریپت (در حالت minify شده)
  • پشتیبانی از صفحات retina (رزولوشن بسیار بالا)
  • بدون پیش نیاز و وابستگی به پلاگین خاص
  • بر اساس تکنیک پیشرفت تدریجی

می توانید سورس کد این پروژه را در صفحه ی گیت هاب (GitHub) آن دانلود کنید.

امیدوارم از این مقاله استفاده ی کافی را برده باشید، در پناه حق.

نویسنده شوید
دیدگاه‌های شما (5 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ُجاد
17 شهریور 1400
با سلام بابت مطلب مفید متشکرم آیا امکان این هستش که دیو ها یا سکشن ها رو به صورت لیزی لود با اسکرول صفحه لود بشن؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

کیوان
16 مهر 1399
سلام سوالی دارم.ممنون میشم پاسخ بدین آیا من حتما باید از اتریبیوت data-src برای رزرو ادرس استفاده کنم یا میتونم آدرس را از محتوای جی سونی که قبلا ذخیره ولود کردم استفاده کنم؟ و آیا با این روش گوگل تصویر یا ویدیو را ایندکس میکنه؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

پاشا
20 فروردین 1399
سلام خدمت مجموعه خوب روکسو، کد آزبورن رو اجرا کردم ولی موقع اسکرول کردن عکسی که میاد تو viewport لود نمیشه. یعنی انگار eventListener اسکرول کار نمیکنه لطفا راهنمایی کنید

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

علیرضا کرمی
05 آبان 1398
به نظر شما موتور های جستجو به خصوص گوگل میتونن عکس های واقعی را پیدا کنن به جای عکس پری لود یا ........... یا بهتر بگم خزنده ها میتونن عکس های اصلی را پیدا کنن

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
09 آبان 1398
سلام دوست عزیز، بله گوگل یک سند در اواخر سال 2018 منتشر کرد و در اون توضیح داد که چطور lazy loading رو اجرا کنید تا گوگل بتونه صفحات شما رو به شکل صحیح index کنه. این مطلب رو می تونید از اینجا مطالعه کنید: https://developers.google.com/search/docs/guides/lazy-loading

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

hossein
19 اردیبهشت 1398
شما از کدوم روش استفاده میکنید ؟در سایتتون...

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
20 اردیبهشت 1398
اگر دقت کنید در روکسو تصاویر اصلا بارگزاری نمیشن (حتی نسخه ی بلوری و تار ندارن) تا زمانی که اسکرول کنید به اون قسمت... در آخر انتخاب روش با شماست و روش برتری تقریبا وجود نداره (مهم حفظ منابع سیستمی سرور هست).

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.