73 lines
1.9 KiB
JavaScript
73 lines
1.9 KiB
JavaScript
/**
|
|
* Lazy Loading Images Script
|
|
* Optimizes image loading for better performance
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
// Check for Intersection Observer support
|
|
if (!("IntersectionObserver" in window)) {
|
|
// Fallback: load all images immediately
|
|
document.querySelectorAll('img[loading="lazy"]').forEach((img) => {
|
|
if (img.dataset.src) {
|
|
img.src = img.dataset.src;
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Configure intersection observer
|
|
const imageObserver = new IntersectionObserver(
|
|
(entries, observer) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
const img = entry.target;
|
|
|
|
// Load the image
|
|
if (img.dataset.src) {
|
|
img.src = img.dataset.src;
|
|
img.removeAttribute("data-src");
|
|
}
|
|
|
|
// Optional: load srcset
|
|
if (img.dataset.srcset) {
|
|
img.srcset = img.dataset.srcset;
|
|
img.removeAttribute("data-srcset");
|
|
}
|
|
|
|
// Add loaded class for fade-in effect
|
|
img.classList.add("loaded");
|
|
|
|
// Stop observing this image
|
|
observer.unobserve(img);
|
|
}
|
|
});
|
|
},
|
|
{
|
|
// Start loading when image is 50px from viewport
|
|
rootMargin: "50px 0px",
|
|
threshold: 0.01,
|
|
}
|
|
);
|
|
|
|
// Observe all lazy images
|
|
const lazyImages = document.querySelectorAll('img[loading="lazy"]');
|
|
lazyImages.forEach((img) => imageObserver.observe(img));
|
|
|
|
// Add CSS for fade-in effect if not already present
|
|
if (!document.getElementById("lazy-load-styles")) {
|
|
const style = document.createElement("style");
|
|
style.id = "lazy-load-styles";
|
|
style.textContent = `
|
|
img[loading="lazy"] {
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease-in-out;
|
|
}
|
|
img[loading="lazy"].loaded {
|
|
opacity: 1;
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
}
|
|
})();
|