I'm using this JavaScript to preload few images on my website.
var images = new Array()
function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image()
images[i].src = preload.arguments[i]
}
}
preload(
"img/1.png",
"img/hover.png",
"img/image.png",
"img/work1.png"
)
This code is linked in HEAD of the site.
But when someone is visiting my website he waits for few second's while images are loaded and in that time he sees blank (white) website until JS files are loaded. I want to make that when someone visit my website he see a "Loading progess bar" or message that say "Wati until page is loaded" etc. Without a blank index page where JavaScript is linked
Unless an accurate progress bar is actually helpful to your users you are probably better off simply use an animated gif that gets hidden after your loading functions finish. Something like this:
Put the gif on the top of your index.html file. Something like
<div id="loading-gif"><img src="/path/to/gif"></div>
Then when your content loads, simply execute something like
document.getElementById("loading-gif").style.display = 'none';
Note, license information for the above image is located here.
Related
I have a simple carousel on my home page. It changes pictures automatically after a couple of seconds. The html looks like this:
<div>
<div id="img-1" class="carousel-image" style="display: block;"></div>
<div id="img-2" class="carousel-image" style="display: none;"></div>
<div id="img-3" class="carousel-image" style="display: none;"></div>
</div>
I use a javascript function to add the images as background-image. To make sure the carousel images are all loaded before the carousel starts changing automatically I use new Image() and count the number of loaded images. Once all three images are loaded I can do startCarousel().
var numberOfLoadedImages = 0;
function setImage(imgUrl, imgId){
var homeImage = document.getElementById(imgId);
homeImage.style.backgroundImage = 'url(' + imgUrl + ")";
var img = new Image();
img.onload = function() {
if(numberOfLoadedImages === 2){
startCarousel();
}
numberOfLoadedImages++;
}
img.src = imgUrl;
if (img.complete) {
img.onload();
}
}
I can then simple call this function like this:
setImage('img-1', 'img-1');
setImage('img-2', 'img-2');
setImage('img-3', 'img-3');
What I would like to achieve is to lazy-load the second and third image. These two are not necessary at first page load; only the first image is important. Google Page Speed Insights mentions the second and third under the heading "Serve images in next-gen formats", whereas, if you ask me, they should not be considered part of the page. They should be loading in the background and they are really not essential for the first display and UX.
How can I tell the browser (or Google Page Speed Insights) that these images are completely non-essential for UX purposes and should not be considered part of the first paint and UX?
I tried putting the second and third call in a timeout with a short interval, but that didn't do the trick.
NB: I am using vanilla javascript; no plugins at all.
You can wait for everything to load and once the page is fully loaded (including images, etc.) you can run setImage for your second and third image.
document.addEventListener('DOMContentLoaded', function() {
setImage('img-2', 'img-2');
setImage('img-3', 'img-3');
}, false);
In case Google Page Speed Insights still registers this and prolong the initial page load time you can use async function to call setImage.
I am trying to import photos from a local file on my computer to my HTML file. I have managed to do this but I need to speed up the time it takes to load in on the page, 2.4mins. My idea was to load a smaller file size of the image, 200px by 200px and then load the full-sized image in the background. The problem that I am encountering is that I am not able to integrate my code of loading the images from a local file with the lazy loading code. can anyone help?
const $spans = $("span");
const {
length
} = $spans;
$spans.each(function(i) {
$(this).append("<img src='Images/With Out Logo/Insta Photo-" + (length - i) + ".JPG' />");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<span class="Images"></span>
I'd look into using intersection observerAPI for lazy loading images, there's an excellent Google Developer Guide on this whole subject.
A basic example of this is:
Alter your <img> tags to add:
data-src
data-srcset
These point to the image to load once the element is being looked at in the "viewport".
Example:
<img class="lazy" src="placeholder.jpg" data-src="lazy-img-1x.jpg" data-srcset="lazy-img-1x.jpg 1x">
Then in a <script> tag or wherever you run your page's code just have a function that listens for the DOMContentLoaded event:
document.addEventListener("DOMContentLoaded", function() {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
if ("IntersectionObserver" in window) {
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Possibly fall back to a more compatible method here
}
});
Here's a CodePen from the guide with a better example.
Before you upload images for use on a website, you should optimize them first to prevent slow load time/your current issue.
As your images are seemingly stored in a local folder, I would suggest to first, make a back-up of the folder containing the images [to an external hard drive or another area of your hard drive].
Then, visit an image compression site (such as tinypng, - I use this but there are others, e.g CompressJpeg) Compressing images will greatly reduce the file size but the images will appear the same. You can upload multiple images at a time, and download bundles of compressed images as a zip. Ensure that when you extract the images, that they are named as you would like (and that they don't have a '1' at the end [as usually added, to indicate that the file is a copy/2nd version])
When you run your code using the smaller images, you should find that your processing time is reduced substantially.
Hope this helps
A sidenote - Both the afore-mentioned websites handle both jpgs and png formats - the website names can be misleading! :)
<!--WunderGroundRadar-->
<script type = "text/javascript">
setInterval(function refreshRadar() {
document.getElementById("content14").src = "http://api.wunderground.com/api/MyAPIkey/animatedradar/q/autoip.gif?&radius=90&num=15&delay=20&width=430&height=500&smooth=1&newmaps=1&interval=15&rainsnow=1"
}, 900000);
</script>
I use the code above to refresh a weather radar .gif image on my website about every 15 minutes. This normally works great, but sometimes when the refresh takes place the image is broken from it's source and my site has a broken image icon until the next refresh takes place approx. 15 minutes later. I would like to set this up so that if the requested image is broken or not available at the time that the refresh function runs, I keep the image that is already loaded instead of replacing it with a broken image icon. I am willing to use any javascript or Jquery that might achieve this, but I am a novice programmer, so if you could break down any intricate code that would be much appreciated. Thanks!
You can try something like this
<script type = "text/javascript">
setInterval(function refreshRadar() {
img = new Image();
img.onload = function(){
document.getElementById("content14").src = img.src;
};
img.src = "http://api.wunderground.com/api/MyAPIkey/animatedradar/q/autoip.gif?&radius=90&num=15&delay=20&width=430&height=500&smooth=1&newmaps=1&interval=15&rainsnow=1"
}, 900000);
</script>
it attempts to load source to a temporary image and only on successful load assings source to "content14"
I'm using document.images to load images when a visitor first visits the website. The reason is because I have a few different areas which have rollover images. Before I switch over to using CSS sprites (modifying a lot of work), I'm going to ask here.
So I'm preloading images with this:
images = new Array();
if (document.images) {
images.push(preloadImage("http://website.com/images/myimg.png", 300, 200));
}
function preloadImage(src, x, y) {
var img = new Image(x, y);
img.src = src;
return img;
}
And according to Chrome's "resource" panel, this is working just fine. Even after pressing CTRL+F5, the images listed in the JS are downloaded.
HOWEVER, they are not used. If I hover over an element in one of my three scripts, the image is downloaded a second time. Derp?
I assume that when preloading images this way, you're supposed to put that image array to use. I thought the browser would be smart enough to say "Hey, this is the same image, let's use it twice" but apparently not.
So is this correct? Do I need to rewrite my programs to preload images individually? I know it doesn't sound hard, but it's really not designed for that.
This is not really an answer to your question, but I proprose a different solution. Put all the images you need to preload inside a div that is hidden from the user. I know, I know, this i not as elegant, but it should work just fine. :)
<div style="display: none;">
<img src="http://website.com/images/myimg.png" alt=""/>
...
</div>
This works fine for me:
function imgPreload() {
var imageList = [
"my/firstimage.png",
"my/secondimage.jpg",
"my/thirdimage.png"
];
for (var i = 0; i < imageList.length; i++ ) {
var imageObject = new Image();
imageObject.src = imageList[i];
}
}
imgPreload();
Cheers. Frank
Is there any way without AJAX of changing the loading order of images on a page? Or even a way to completely halt or pause loading of images already present?
The use case is simple - I have a long list of images down a page, and visitors will be landing on different spots of the page using URL anchors (/images#middle-of-page) that refer to actual containers for those images.
I'd like in the least to load the images inside the requested container FIRST, then continue loading the rest of the images.
The challenge is that there is no way to know the image paths of the requested container image before loading the page DOM.
I've tried getting the container img contents on load, then using the Javascript new Image() technique, but it doesn't change the fact that that image on the page will still be waiting for all previous images to load.
I've also tried immediately prepending a div in the body with a background image (CSS) of said img path, but this also does not prioritize the image load.
Any other ideas?
You need to have a DOM with empty img placeholders, i.e.
<img src="" mysrc="[real image url here]" />
Or you can make images to display "Loading..." image by default. You can even cache real image url in some custom tag, mysrc for example. Then once you know what exactly images you want to show (and in what order) you need to build a sequence of image loading
var images = [];//array of images to show from start and in proper order
function step(i){
var img = images[i++];
img.onload = function(){
step(i);
}
img.src = "[some url here]"
}
Hope this helps.
For interest, this is the function I ended up implementing based on the answers here (I made it an on-demand loading function for optimum speed):
function loadImage(img) { // NEED ALTERNATE METHOD FOR USERS w/o JAVASCRIPT! Otherwise, they won't see any images.
//var img = new Image(); // Use only if constructing new <img> element
var src = img.attr('alt'); // Find stored img path in 'alt' element
if(src != 'loaded') {
img
.load(function() {
$(this).css('visibility','visible').hide().fadeIn(200); // Hide image until loaded, then fade in
$(this).parents('div:first').css('background','none'); // Remove background ajax spinner
$(this).attr('alt', 'loaded'); // Skip this function next time
// alert('Done loading!');
})
.error(function() {
alert("Couldn't load image! Please contact an administrator.");
$(this).parents('div:first').find("a").prepend("<p>We couldn't find the image, but you can try clicking here to view the image(s).</p>");
$(this).parents('div:first').css('background','none');
})
.attr('src', src);
}
}
The img loading="lazy" attribute now provides a great way to implement this.
With it, images load automatically only when on the viewport. But you can also force them to load by setting in the JavaScript:
document.getElementById('myimg').loading = 'eager';
I have provided a full runnable example at: How do you make images load lazily only when they are in the viewport?
One really cool thing about this method is that it is fully SEO friendly, since the src= attribute contains the image source as usual, see also: Lazy image loading with semantic markup