I've done extensive research but I'm still struggling to solve this issue. It only seems to be happening on Safari (Mac & iOS), while everything works smoothly on Chrome, Firefox, Edge, and other browsers.
UPDATE: The flickering problem also persists in FireFox...
The problem arises when I try to lazy load images using the IntersectionObserver API and the necessary polyfill. This method swaps out a low-resolution image set as the div's background-image
with a high-resolution image stored in a data attribute as soon as it comes into view.
Although the functionality technically 'works' as intended – displaying the low-quality image before switching to the high-quality one – there is an annoying white flicker or flash that occurs during the transition. Could it be the page's white background showing through?
After reading some resources, including this post on Stack Overflow (How to prevent a background image flickering on change), I managed to resolve the jumping issue by preloading the images using the new Image()
constructor.
const setBackgroundImage = (e) => {
let image = new Image();
image.onload = () => e.style.backgroundImage = `url(${e.dataset.bgImage})`;
image.src = e.dataset.bgImage;
};
Here's an example HTML element (PHP):
<div class="my-div"
style="background-image: url('<?= $imagePreload ?? $image; ?>');"
data-bg-image="<?= $image; ?>"
</div>
I've tried tweaking the backface-visibility: hidden
property with no success. I'm not incorporating any animations; simply replacing the src
on the div
with the preloaded, full-sized image.