بهترین شیوه های بارگذاری تنبل

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

حواستون به جمع باشه

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

بارگذاری تنبل بارگذاری منابع را تا زمانی که DOM تعاملی شود، زمانی که اسکریپت ها بارگیری به پایان رسیده و شروع به اجرا می شوند، به تاخیر می اندازد. برای تصاویر زیر تاشو، این خوب است، اما منابع حیاتی بالای تاشو باید با عنصر استاندارد <img> بارگذاری شوند تا در اسرع وقت نمایش داده شوند.

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

علاوه بر این، ممکن است نخواهید در مورد خط تا شدگی به عنوان آستانه برای شروع بارگذاری تنبل سختگیر باشید. ممکن است برای اهداف شما ایده‌آل‌تر باشد که یک منطقه بافر در فاصله‌ای زیر تاشو ایجاد کنید تا تصاویر قبل از اینکه کاربر آن‌ها را در نما اسکرول کند، بارگذاری شوند. به عنوان مثال، Intersection Observer API به شما این امکان را می دهد که در هنگام ایجاد یک نمونه IntersectionObserver ، یک ویژگی rootMargin در یک شی گزینه مشخص کنید. این به طور موثر به عناصر یک بافر می دهد، که رفتار بارگذاری تنبل را قبل از اینکه عنصر در نمای دید باشد، تحریک می کند:

let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
  // lazy-loading image code goes here
}, {
  rootMargin: "0px 0px 256px 0px"
});

اگر مقدار rootMargin شبیه مقادیری است که برای یک ویژگی margin CSS مشخص می‌کنید، به این دلیل است که اینطور است! در این مورد، حاشیه پایین عنصر مشاهده شده (نمای مرورگر به طور پیش فرض، اما می توان آن را با استفاده از ویژگی root به یک عنصر خاص تغییر داد) 256 پیکسل گسترش می یابد. این بدان معناست که عملکرد برگشت تماس زمانی اجرا می‌شود که یک عنصر تصویر در 256 پیکسل از نمای درگاه باشد و تصویر قبل از اینکه کاربر واقعاً آن را ببیند شروع به بارگیری می‌کند.

برای دستیابی به همین اثر در مرورگرهایی که از Intersection Observe پشتیبانی نمی‌کنند، از کد مدیریت رویداد اسکرول استفاده کنید و تیک getBoundingClientRect خود را طوری تنظیم کنید که دارای بافر باشد.

تغییر چیدمان و جایگیرها

اگر از متغیرهایی استفاده نشود، رسانه بارگذاری تنبل می‌تواند باعث تغییر در چیدمان شود. این تغییرات می‌تواند برای کاربران گمراه‌کننده باشد و عملیات‌های گران‌قیمت طرح‌بندی DOM را آغاز کند که منابع سیستم را مصرف می‌کند و به jank کمک می‌کند. حداقل، استفاده از یک مکان نگهدار رنگ ثابت با ابعاد مشابه تصویر مورد نظر، یا تکنیک هایی مانند LQIP یا SQIP که به محتوای یک آیتم رسانه قبل از بارگیری اشاره می کند، در نظر بگیرید.

برای تگ های <img> ، src در ابتدا باید به یک مکان نگهدار اشاره کند تا زمانی که آن ویژگی با URL تصویر نهایی به روز شود. از ویژگی poster در عنصر <video> برای اشاره به یک تصویر نگهدارنده استفاده کنید. علاوه بر این، از ویژگی های width و height در هر دو تگ <img> و <video> استفاده کنید. این تضمین می‌کند که انتقال از مکان‌نماها به تصاویر نهایی، اندازه رندر شده عنصر را با بارگذاری رسانه تغییر نمی‌دهد.

تاخیر در رمزگشایی تصویر

بارگذاری تصاویر بزرگ در جاوا اسکریپت و انداختن آنها در DOM می تواند رشته اصلی را به هم متصل کند و باعث شود رابط کاربری برای مدت کوتاهی در حین انجام رمزگشایی پاسخگو نباشد. رمزگشایی ناهمزمان تصاویر با استفاده از روش decode قبل از قرار دادن آنها در DOM می‌تواند این نوع جک را کاهش دهد، اما مراقب باشید: هنوز در همه جا در دسترس نیست، و به منطق بارگذاری تنبل پیچیدگی می‌دهد. اگر می خواهید از آن استفاده کنید، باید آن را بررسی کنید. در زیر نشان می‌دهد که چگونه می‌توانید Image.decode() با یک بازگشت به عقب استفاده کنید:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

if ("decode" in newImage) {
  // Fancy decoding logic
  newImage.decode().then(function() {
    imageContainer.appendChild(newImage);
  });
} else {
  // Regular image load
  imageContainer.appendChild(newImage);
}

این پیوند CodePen را بررسی کنید تا کد مشابه این مثال را در عمل ببینید. اگر بیشتر تصاویر شما نسبتاً کوچک هستند، ممکن است کار چندانی برای شما نداشته باشد، اما مطمئناً می‌تواند در هنگام بارگیری تصاویر بزرگ و درج آن‌ها در DOM به کاهش jank کمک کند.

وقتی چیزها بارگذاری نمی شوند

گاهی اوقات منابع رسانه ای به دلایلی بارگذاری نمی شوند و خطاهایی رخ می دهد. چه زمانی ممکن است این اتفاق بیفتد؟ بستگی دارد، اما در اینجا یک سناریوی فرضی برای شما وجود دارد: شما یک خط مشی کش HTML برای مدت زمان کوتاهی دارید (مثلاً پنج دقیقه)، و کاربر از سایت بازدید می کند یا یک کاربر یک برگه قدیمی را برای مدت طولانی باز گذاشته است. زمان (به عنوان مثال، چندین ساعت) و برای خواندن مطالب شما برمی گردد. در نقطه ای از این فرآیند، یک جابجایی مجدد رخ می دهد. در طول این استقرار، نام یک منبع تصویر به دلیل نسخه‌سازی مبتنی بر هش تغییر می‌کند یا به طور کلی حذف می‌شود. زمانی که کاربر تصویر را با تنبلی بارگذاری می کند، منبع در دسترس نیست و در نتیجه از کار می افتد.

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

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

newImage.onerror = function(){
  // Decide what to do on error
};
newImage.onload = function(){
  // Load the image
};

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

سناریوهای دیگری نیز ممکن است رخ دهد. هر کاری که انجام می دهید، هرگز ایده بدی نیست که هنگام بروز خطا به کاربر علامت دهید و احتمالاً اگر مشکلی پیش آمد به او کاری بدهید که انجام دهد.

در دسترس بودن جاوا اسکریپت

نباید تصور کرد که جاوا اسکریپت همیشه در دسترس است. اگر می خواهید تصاویر را با تنبلی بارگذاری کنید، نشانه گذاری <noscript> را در نظر بگیرید که در صورت در دسترس نبودن جاوا اسکریپت، تصاویر را نشان دهد. ساده ترین مثال بازگشتی ممکن شامل استفاده از عناصر <noscript> برای ارائه تصاویر در صورت خاموش بودن جاوا اسکریپت است:

من یک تصویر هستم!

اگر جاوا اسکریپت خاموش باشد، کاربران هم تصویر مکان‌نما و هم تصویر موجود با عناصر <noscript> را خواهند دید. برای دور زدن این موضوع، یک کلاس از no-js روی تگ <html> قرار دهید مانند:

<html class="no-js">

سپس یک خط از اسکریپت درون خطی را در <head> قرار دهید، قبل از درخواست هر گونه شیوه نامه از طریق تگ های <link> که کلاس no-js را از عنصر <html> حذف می کند، اگر جاوا اسکریپت روشن است:

<script>document.documentElement.classList.remove("no-js");</script>

در نهایت، زمانی که جاوا اسکریپت در دسترس نیست، از مقداری CSS برای پنهان کردن عناصر با کلاس lazy استفاده کنید:

.no-js .lazy {
  display: none;
}

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