I have a site that uses lazy loading for images, but it doesn’t work without JS (the images are not shown) which has been bothering me.
I had a brainwave to fix this. Currently my images have a data-src but no src attribute. It occurred to me that if I gave them both and then set the src to the empty string I could have the best of both worlds.
This is my original JS (which I think came from @m3g4p0p)
var images = document.querySelectorAll("[data-src]");
var imgArray = Array.from(images);
var checkImage = function checkImage(image) {
if (image.getBoundingClientRect().top < window.innerHeight) {
image.src = image.dataset.src;
return false;
}
return true;
};
var scrollHandler = function scrollHandler() {
imgArray = imgArray.filter(checkImage);
if (!imgArray.length) {
window.removeEventListener("scroll", scrollHandler);
}
};
window.addEventListener("scroll", scrollHandler);
imgArray = imgArray.filter(checkImage);
and I have added
var nullImage = function nullImage(image) {
image.src = "";
};
images.forEach(nullImage);
but I’m not sure how to test it. I can see that the images are displayed whether or not JS is enabled, but I can’t see whether the images are being lazy loaded if JS is enabled.
Any ideas how to check, and thoughts as to whether this is a brainwave or a brain fart?
Hey @Gandalf, you can check the network panel of the browser dev tools to see when an image is getting loaded; as for clearing the src properties, you will see that the download will get initiated for all images on the page but cancelled right away. The thing is though that you have to load your JS after the images in order to query for the images, so I don’t think there’s a way to prevent the initial requests.
Yes sorry, I meant the image elements. Thinking about it, I suppose your best bet would be to put the JS in the document head and wrap it in a DOMContentLoaded event listener so that it kicks in immediately after the HTML got parsed; this still won’t prevent the initial requests but probably cancel them as early as possible.
Oh yes, that would indeed make the JS solution obsolete. :-) Or you might still use it as a fallback if it’s not supported:
if ('loading' in HTMLImageElement.prototype) {
// supported in browser
} else {
// initiate JS lazy loading
}
Further thinking about it, an actual polyfill would have to do exactly as @Gandalf suggests – remove the original src attribute and replace it with a data-src attribute (or otherwise store the source internally)… either way, there’s no need to also maintain the data-src in the markup then:
Gandalf mentioned that no images were displayed when the “Lazy Loading” JavaScript routine was disabled. AmpProject uses JavaScript and also the following to cater for when JavaScript is not loaded:
I think that due to browser updates JavaScript is remarkably fragile and frequently fails which no doubt caters for the majority topics on this forum.
The AmpProject Team ensure that when JavaScript is not loaded the page “fails gracefully” otherwise the following large clients would raise complaints:
The Washington Post, BBC, Vox, and The New York Times
<noscript>
Allowed. Can be used anywhere in the document. If specified, the content inside the <noscript> element displays if JavaScript is disabled by the user.
So I modified the following PHP script and added <noscript>
if(0):
// OLD SCRIPT THAT FAILS WHEN JavaScript DISABLED
$result = <<< ____EOT
<div class="fll tac">
<a href="$url" title="$title">
<amp-img
src="$thumb"
{$dims[3]}
alt="$title"
/>
</a>
<br>
$title
</div>
____EOT;
else:
// NOW WORKS OK EVEN IF JavasScript IS DISABLED
$result = <<< ____EOT
<div class="fll tac">
<a href="$url" title="$title">
<amp-img
src="$thumb"
{$dims[3]}
alt="$title"
/>
<noscript>
<img src="$thumb" {$dims[3]} alt="AMP">
</noscript>
</a>
<br>
$title
</div>
____EOT;
endif;
To test I disabled FireFox’s JavaScript:
In Firefox, type “about:config” in the address bar, then press “Enter“.
Select the “I accept the risk!” button.
Type “javascript” in the “Search” box.
Double-click the “javascript. enabled” line to toggle the setting between “true” and “false” as desired.
Online Test
Try the following where the trailing numeric parameter is the number of thumbnails to display - there is a couple of thousand and takes an extra ten seconds to display with JavaScript disabled
I use plugin, JS enabled function and it solve my issues that is website speed is down and after using the plugin my speed increases in both desktop and mobile devices.
Hello John, Yes in that manner you are right, PHP just generates the page regardless. because if Javascript is disabled then images can’t be shown and Plugins are also not able to track that images.