Why is image preloading ineffective? - javascript

My CMS project has a stylish web 2.0 login screen that fades over the screen using javascript. How come that even though I have made 120% sure that images are preloaded (I used the resource monitor in development tools) they still take a second to show up when my login screen appears. It completely destroys the fanciness! Take a look:
http://www.dahwan.info/Melior (link broken)
When you click login, the screen is supposed to fade to dark using a 75% alpha 1px png image. Even though the image is preloaded, it doesn't show up until after the animation is done. However, if you click cancel and log in again, the animation flows smoothly and perfectly.
Can anyone think of a solution to this problem? I'm having it with the rest of my CMS' GUI as well. It's like there was no image preloading what so ever.
Thanks for answers
EDIT: Ah yes, I'm currently developing this CMS for Google Chrome 5.0.375.99, adding multi browser compatibility later. Sorry for leaving that out

I have come up with a workaround to my problem. I have now tested this in three browsers on two different computers with perfect results. In short, in my image preloading function in javascript, i added each of the images into the DOM in an invisible Div tag.
$('#img_preload').append($('<img />').attr('src', img.src));
The images now being added to the Dom at page load, and according to my theory resting in the memory of my low-end computers, they appears instantly when my CMS needs them.
Thanks for your comments :)

A useful information about this problem:
The Codemonkey solution works because, by putting the images in a hidden div, the browser have to keep those images in memory and ready for a possible change of div's visibility. If the user needs to change de visibility of div from hidden to block, it has to be done instantly. This is why just load all images into an array doesn't work properly.

You could also just preload them into an array. Your problem might be caused by what is known as "garbage collection". This is where the browser looks for objects that are consuming memory which no longer have an instance on the screen and are not being referenced by anything else in memory.
If you preload images into your web age, they should be loaded into the cache, though. So, they should still re-appear when referenced again. However, images can also disappear if the cache expiration is not set for a long enough length of time for these types of files.
Your problem could also be browser-specific.... I have found that it is always best to create an "anchor" for pre-loaded content by placing them into an image array and then using the array to call up the images when needed instead of the image URL(URI).
Here is a quick-and-dirty article that covers this topic.
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5214317.html

The UI thread can only manage one task at a time -- it will either execute javascript or update the UI. If there is a lot of javascript parsing/executing before the code that preloads the image, that might be causing the delay.
Another suggestion is to disable clickability on the login link until after the image has been detected on the page.
To do so is fairly straightforward:
function disableBtn(el){
var btn = document.getElementById(el);
var btnId = btn.id;
btn.disabled = true;
}
To re-enable, set btn.disabled = false (after detecting that your image has been added to the DOM).

Related

How web browser find out when user reached to custom image in web page?

I am developing a web site for selling handy crafts so users expect high quality images for per product. because of SEO related problems, I think about loading image asynchronous and just when user reach to per product thumbnail.I don't know how find out that when each user reach to per prouct thumbnail when scrolling page to load main and hight quality image for it; are there any event in javascript for detect that? or I have to calculate by pixels or some way like that?
What you are looking for is called "lazy loading". Lazy Loading means that the required resources are only loaded once the user actually needs it. In this example, the user only needs the image once the image is actually in the viewport (the elements visible on the screen)
The easiest way for Chromium-based browsers and Firefox is using the "loading" attribute of the img-tag and setting the value to "lazy". Example: img loading=lazy src="link"
This will work for most cases. However, if you want to be in control of the functionality behind it what you are searching for is called a "Intersection Observer". With this you can do alot of stuff related to elements and the viewport. E.g. how far is an element away from the viewport, or how much percent of the element is actually in the viewport.
If you want a really short 15 minute video that explains the Intersection Observer basis I can recommend this YouTube video:
https://www.youtube.com/watch?v=2IbRtjez6ag
I hope that this will be enough to help you with your problem!

Complex loading page animation

Before you read the rest this might be considered a broad question.
I'm sorry if it is, but I have no other way to ask it than this.
So, I thought about a loading page animation, which I consider to be complex, but it may not be.
What I want to achive is this:
When the page loads (let's say the index page), what you would see would be the point of view of a person looking at his/her smartphone (or desktop monitor, depending on the media query). So you would basically see what you see right now. If you're on a chair or a sofa you see maybe your legs, your hands, the environment and of course the device. On that device you would see a miniature of your index page, like that person is looking at your website.
Ok, now when the page is loading you would see a zoom on the smartphone/desktop monitor like you are going "into the content" that's displayed on the screen of that person's smartphone/desktop monitor, and when it's completely loaded you see the actual website fully displayed on your device.
In other words, in the animation, that person's device becomes your device. Hope I was clear enough.
POSSIBLE SOLUTIONS I THOUGHT ABOUT
Putting a screenshot of the index page on the animation's device and then using transform: scale(); for the zoom, but how could I get rid of the animation's content once the page is fully loaded, and then have the actual website displayed?
Having the entire <body> element zoomed out using transform: scale(); and positioned on the person's device, and when the page id loaded using transform: scale(); again to zoom in to the full viewport's size.
Note that I listed only CSS solutions, because I just started learning JS.
IMPORTANT: I don't want nobody to write that code for me. I only want to know if there's a solution, and if the solutions I thought about could work. Or, if I should use JS or other stuff I'm not aware about, in order to achive this animation.
POSSIBLE SOLUTIONS I THOUGHT ABOUT
Putting a screenshot of the index page on the animation's device and
then using transform: scale(); for the zoom, but how could I get rid
of the animation's content once the page is fully loaded, and then
have the actual website displayed?
you can get rid of the animation's content once the page is fully loaded with the help of javascript:
window.addEventListener("load", function () {
var AnimationContent= document.querySelector("#ID OF YOUR ANIMATION CONTENT");
AnimationContent.remove();
// or
AnimationContent.style.display = "none";
});

Only load size of images / attributes but not the actual content

I am trying to write a chrome plugin so I can use some websites that includes a lot of images I dont care about that are problematic to load seeing as my internet connection is poor.
As such, is it possible to stop loading images but just load white boxes instead, with the exact same size, attributed links etc.? I am a bit unsure where to even start on this, as I tried to just .display = None, but that does not help me loading the website when my connection is bad.
Reason why I want to load something is because if all the images etc just disappear the website layout basically goes down the drain and I can't scroll around on it.

Slow scrolling when images load

I have an image manager that shows a fixed sized grid of images. The thumbnails are relatively small already so I can't really make them smaller. I implemented lazy loading and using a debounce function to check if the images on in the visible region. This increased the speed of launching my image manager. However, if I scroll while the new batch of images are being loaded, the scrolling becomes very slow. Is there anyway around this or to further optimize loading images?
EDIT:
Is there a way to prevent scrolling while a new batch of images are coming in? Kind of like how Youtube just keeps bouncing when we try to scroll to see more comments while they are still being loaded?
Try not to load all the images at once (which I guess you've implemented with Lazy loading), I'm aware that the users online have a high tendency to scroll fast.
I would suggest, few things here:
First
Implementing the Lazy loading in a correct way is essential. here is a list of few best techniques, make sure which works best for you.
You've mentioned, that the thumbnails are relatively small, however I assume only specifying smaller dimensions is not sufficient, I hope you have covered this ground, Else maintain two folder one for Actual images and another for Thumbnails on your hosting server.
Even though we take utmost care, users upload tons of heavy images on our server, if that is the case, you need to resize the images on client end and then upload on the server, one copy in Actual images and another for Thumbnails
If you are talking about product images, keep the PNGs, Why, because they are far better then BMPs and JPGs. Also you can compress them with online tools like https://tinypng.com/ OR with softwares like https://pngquant.org/
Hope this helps resolve your issue, coz it did to resolve mine.
--N Baua
It turns out the slow scrolling was due to me calling getBoundingClientRect() to find new visible images while there were some images still being loaded. That caused a reflow which bogged everything down.
I changed it to load images in batches so that getBoundingClientRect() isnt called when there are images being loaded.

jQuery Cycle - squishing images?

The issue discussed in this question happened to me with a production site, but in addition to Firefox, we saw it in IE.
This is how it should look, with all three fading to different pictures intermittently:
We got these screenshots from clients:
Abmormally small images:
Weird sized images:
We were able to reproduce it reliably with Firefox with a hard refresh (ctrl-f5), but the only one in our office that could reproduce it in IE was running IE8 on Windows 7, and then not reliably. The client was using IE7, I believe on XP.
I fixed it by setting up the slideshow in $(window).load() instead of $(document).ready(), but I never figured out why it was so hard to reproduce in IE. Management is unsettled by the fact that we could not reliably reproduce it in IE or explain why it happened, and I've been asked to investigate.
Does anyone have an idea? Does the same issue discussed in the linked question apply to IE in certain circumstances? All I can say at this point is "we can't always pin down things like this."
UPDATE: I was able to make it happen reliably in IE by not setting the src attributes in the slideshows until after I set up the slideshow in Javascript. I think this proves it was indeed the same timing issue, just happening more rarely because IE is a different rendering engine. Management is still curious what other circumstances intervened, but I'm confident now that it was indeed a timing issue in all browsers, and our production site is safe from further issues.
Also, I asked the same question on jQuery forums here and was told to explicitly set image sizes in the img elements. This also fixed the issue.
It's explained in the link you posted. It's a timing issue. Sometime the cycle starts early, sometimes not. And 'sometimes' may just be 'almost never' in some browsers.
Starting the cycle in document.ready ensures that all images have been loaded before the cycle starts so the dimensions are properly detected.
It can very well depend on CPU speed, network latency, browser, OS and whatnot.
The reason it's so hard to reproduce consistently is because the environment is very complex, and the results depend on things you don't see right away.
I know this is late in the game, but I, too very recently experienced this problem. It drove me nuts. The solution is, in fact to use the $(window).load event method to start the cycle plugin--it guarantees that all associated page-load activity (including any downloads associated with ANY child elements) is complete before it fires. It works in all of the 'big five' browsers.
In my case, I am displaying images of different sizes and aspect ratios, and populating the image list automatically by using a server-side script to populate a variable containing dynamically created tags for all the image types in a designated directory that I tell it to include. Consequently, I can't include the image width and height in the tags, because I don't know what they are. In order to get around this, at the client side I use cycle's onbefore: to fire a script that dynamically looks at the image being processed and then sets the slideshow container to a width and height matching the photo's native width and height. I display a "Loading xx photos..." message with an animated GIF loader graphic so that the user knows something is going on while the images are downloaded.
The slideshow(s) in question reside in an area on the hangmanhills.org website that is restricted to Hangman Hills Residents' Association members only, so I can't show you the end product.

Categories