0% found this document useful (0 votes)
23 views

Javascript - Speed Up Page Load by Deferring Images - Stack Overflow

The document discusses different ways to defer loading images on a page to improve performance. It suggests using JavaScript to initially load small placeholder images and then replace the src attribute with the actual high-resolution image source once the page has loaded.

Uploaded by

nosagih554
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Javascript - Speed Up Page Load by Deferring Images - Stack Overflow

The document discusses different ways to defer loading images on a page to improve performance. It suggests using JavaScript to initially load small placeholder images and then replace the src attribute with the actual high-resolution image source once the page has loaded.

Uploaded by

nosagih554
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Speed up page load by deferring images

Asked 11 years, 8 months ago Modified 7 months ago Viewed 57k times

I am creating a page which will contain a lot of large sized images, so naturally I want to make sure the
page loads without too much trouble. I read this article here http://24ways.org/2010/speed-up-your-site-
40 with-delayed-content
The method of deferring is as follows (pulled from page, don't mind the URL)
<div>
<h4>
<a href="http://allinthehead.com/" data-gravatar-
hash="13734b0cb20708f79e730809c29c3c48">
Drew McLellan
</a>
</h4>
</div>

then later a snippet of js takes care of the image loading


$(window).load(function() {
$('a[data-gravatar-hash]').prepend(function(index){
var hash = $(this).attr('data-gravatar-hash')
return '<img width="100" height="100" alt=""
src="http://www.gravatar.com/avatar.php?size=100&amp;gravatar_id=' + hash + '">'
});
});

I don't plan on doing this for every image but definitely for some image which I don't need it to show up
at page load time.
Is this the best way to go or are there better ways to achieve faster page load by deferring images?
Thanks
javascript jquery deferred-loading

Share Improve this question Follow edited Dec 2, 2013 at 14:01 asked Sep 12, 2012 at 20:54
Huangism
16.3k 7 49 75

For anyone who's looking how to do it with css: background-image, here's the
answer:stackoverflow.com/questions/39664660/… – Mario Nezmah Feb 3, 2021 at 14:17

6 Answers Sorted by: Highest score (default)


¿No encuentras la respuesta? Pregunta en Stack Overflow en español.
A little late, but in case it benefits others, there is a great article on this topic by Patrick Sexton
https://varvy.com/pagespeed/defer-images.html
66 He basically is suggesting the same thing, only by using tiny base 64 encoded images, he can place his
image tags directly in the HTML which has the benefit of being able to control attributes like height,
width, alt, etc individually. It will be a lot easier to maintain your HTML this way as opposed to creating
the entire image tag in a script.
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-
src="image1.jpg" alt="image 1">
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-
src="image2.jpg" alt="image 2">

Then your script is simple and generic for all images


<script>
function init() {
var imgDefer = document.getElementsByTagName('img');
for (var i = 0; i < imgDefer.length; i++) {
if (imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
}
}
}

window.onload = init;
</script>

Share Improve this answer Follow edited Nov 17, 2017 at 9:58 answered May 26, 2015 at 13:33
Sgnl jsolis
1,878 22 30 808 7 9
1 How can this be the accepted answer ? It defeats the purpose of it all : if your image data is already base64-
encoded in the HTML you don't defer image loading and you load all images with the HTML. You will have the
visual effect of the images appearing but no deferred loading and no improvement in loading time. – MindTailor
Dec 14, 2018 at 9:21
21 The base64 encoded image isn't the real image. It's a super small blank dummy image. You'll notice the data is
the same for the 2 example img tags. The script provided will lazy load the real image based on the data attribute.
The article linked to the answer provides a very easy to understand explanation. – jsolis Dec 14, 2018 at 19:09
2 OK, my bad. Thanks for the further explanation :) – MindTailor Dec 17, 2018 at 17:37
6 What advantage does the 1x1 pixel image have over just omitting the src attribute? – David Harkness Feb 13,
2019 at 20:12
3 That is a great question. My best guess is that at the time (4 years ago now) it helped with the browser honoring
height and width. Today when I test with and without the src attribute, I seem to get the same results in Chrome,
FF, and Safari: codepen.io/anon/pen/qgMLyx – jsolis Feb 14, 2019 at 15:47
This seems to be pretty clean way of deferring images. The only potential problem is if images carry
important information as "Data attributes are a new feature in HTML5".
5 Another option could be to put images to end of body and use CSS to position them. Personally I would
stick to javascript.
Share Improve this answer Follow answered Sep 12, 2012 at 21:29
nrodic
3,011 3 35 39

Here's a version showcasing .querySelectorAll :


3 function swapSrcAttributes(source) {
return function(element) {
element.setAttribute('src', element.getAttribute(source));
}
}

function forEach(collection, partial) {


for (var i = 0; i < collection.length; i++) {
partial(collection[i]);
}
}

function initDeferImages() {
// for images
var deferImages = document.querySelectorAll('img[data-src]');

// or you could be less specific and remove the `img`


deferImages = document.querySelectorAll('[data-src]');

forEach(deferImages, swapSrcAttributes('data-src'));
}

window.onload = function() {
initDeferImages();
}

Here is the compatibility table for .querySelector and .querySelectorAll via


https://caniuse.com/#feat=queryselector
Share Improve this answer Follow edited Nov 18, 2017 at 7:58 answered Nov 18, 2017 at 7:19
Sgnl
1,878 22 30

I'd recommand using simply lazy loading (see documentation here)


3 <img src="image.jpg" alt="..." loading="lazy" />

Share Improve this answer Follow answered Oct 5, 2023 at 13:46


Sofien
1,510 14 24
For modern developers, I believe this would be the best answer to the question given how all modern browsers
supports this feature. See caniuse.com/?search=loading%3Dlazy if your target browser is supported however.
– Virus5600 Apr 4 at 17:33

Html
1 <img
width="1024"
src="https://placehold.it/64x48.jpg"
data-src-defer="https://images.unsplash.com/photo-1570280406792-bf58b7c59247?
ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-
1.2.1&auto=format&fit=crop&w=1486&q=80"
alt="image 1"
/>

<img
width="1024"
src="https://placehold.it/64x48.jpg"
data-src-defer="https://images.unsplash.com/photo-1557053964-d42e8e29cb27?
ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-
1.2.1&auto=format&fit=crop&w=1500&q=80"
alt="image 2"
/>

JS
function deferImgs() {
Array
.from(document.querySelectorAll("img[data-src-defer]"))
.forEach((element) => {
element.setAttribute("src", element.dataset.srcDefer);
});
}

window.addEventListener("load", deferImgs());

================================================================
I'm trying to comply with Farrukh's request with this edit.
I try to do my best, but English is unfortunately only the third language I speak. And I am not a language
genius. :D
This js code snippet illustrates a delayed load of some big pictures. This is not a practical
implementation. The size difference between the images is intentionally huge. This is because the test
must be illustrative. You can monitor its operation through a browser development tool page. F12 >
Network tab > Speed settings dropdown The ideal network speed for the test is between 1 - 3MB/s
(Some slow network speed). You may want to run the test several times, so you can see, that the order in
which the images are loaded is not controlled in this case, but depends on the transmission. Because it is
not regulated, it is not possible to predict, which image will arrive first.
We load first a small image into a large placeholder. (image: 64x48.jpg > placeholder width="1024").
The querySelectorAll() method returns a static nodelist. This list of nodes at first glance looks like an
array, but it's not.
This is an array-like object:
document.querySelectorAll("img[data-src-defer]")

The Array.from() method can creates a new array instance from this object. The forEach method can now
be executed on this array. The forEach() method executes a provided function once for each element of
the array.
In this case, each element of the array is passed once to this function:
(element) => {
element.setAttribute("src", element.dataset.srcDefer);
}

and this function sets the value of the src="" attribute of the image tag, to the value of the dataset of the
same image tag.
src="https://placehold.it/64x48.jpg";

data-src-defer="https://images.unsplash.com/photo-1570280406792-bf58b7c59247?
ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-
1.2.1&auto=format&fit=crop&w=1486&q=80";

src = data-src-defer;

So finally:

src="https://images.unsplash.com/photo-1570280406792-bf58b7c59247?
ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-
1.2.1&auto=format&fit=crop&w=1486&q=80";

Share Improve this answer Follow edited Feb 23, 2021 at 0:34 answered Feb 20, 2021 at 20:09
user13884248

1 Please, consider adding some hints to your answer, not only the code ;) – Farrukh Normuradov Feb 20, 2021 at
22:20

You can do it as simple as the example below:


1 All images have data-src attribute where you put the file path. And src attribute with a fake transparent
1x1px png image. You can also add loading attribute setted to lazy , it tells modern browsers to avoid to
load immediately the images that are out of viewport (visible site zone)
<img data-src="path/to/image.jpg" loading="lazy"
src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" />

Add this script to make all images get the src attribute once your site is loaded (you need jQuery to
make it work)
$(function(){
$("img[data-src]").attr("src", function(){ return $(this).data("src"); });
});

Share Improve this answer Follow answered May 27, 2021 at 8:28
Alex Logvin
836 11 13

You might also like