Found this technique of using ajax to preload things at: /
window.onload = function() {
setTimeout(function() {
// XHR to request a JS and a CSS
var xhr = new XMLHttpRequest();
xhr.open('GET', '/preload.js');
xhr.send('');
xhr = new XMLHttpRequest();
xhr.open('GET', '/preload.css');
xhr.send('');
// preload image
new Image().src = "/preload.png";
}, 1000);
};
I noticed that the 'ajax' preloading for this image isn't really ajax at all. It is the same as what I have been using for years already, just setting the url in a new image object's source and letting the browser load it into the cache.
Now imagine that there was an application where, I needed to actually cancel the preloading of the image if it took over a certain amount of time. There really is no good way to do this with just setting the image to src, unlike the xhr.abort() method which stops the loading of an actual xhr request.
Is there any reason that doing some thing like the below wouldn't preload the image just as well and allow the cancellation of the preload request?
function preload(url, timeout){
this.canceltimeout = function(){
clearTimeout(this.timeout);
this.loaded = true;
return false;
}
this.abort = function(){
this.xhr.abort();
this.aborted = true;
}
//creates a closure to bind the functions to the right execution scope
this.$_bind = function(method){
var obj = this;
return function (e){ obj[method](e);};
}
//set a default of 10 second timeout
if(timeout == null){
timeout = 10000;
}
this.aborted = false;
this.loaded = false;
this.xhr = new XMLHttpRequest();
this.xhr.onreadystatechange = this.$_bind('canceltimeout');
this.xhr.open('GET', url);
this.xhr.send('');
this.timeout = setTimeout(this.$_bind('abort'), timeout);
}
var llama = new preload('/image.gif');
show_image();
function show_image(){
if(llama.loaded){
var l = new Image();
l.src = '/image.gif';
application.appendChild(l);
}else if(llama.aborted){
var l = document.createElement('p');
l.innerHTML = 'image.gif got cancelled';
application.appendChild(l);
}else{
setTimeout(show_image, 10);
}
return false;
}
Found this technique of using ajax to preload things at: http://perishablepress./3-ways-preload-images-css-javascript-ajax/
window.onload = function() {
setTimeout(function() {
// XHR to request a JS and a CSS
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://domain.tld/preload.js');
xhr.send('');
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://domain.tld/preload.css');
xhr.send('');
// preload image
new Image().src = "http://domain.tld/preload.png";
}, 1000);
};
I noticed that the 'ajax' preloading for this image isn't really ajax at all. It is the same as what I have been using for years already, just setting the url in a new image object's source and letting the browser load it into the cache.
Now imagine that there was an application where, I needed to actually cancel the preloading of the image if it took over a certain amount of time. There really is no good way to do this with just setting the image to src, unlike the xhr.abort() method which stops the loading of an actual xhr request.
Is there any reason that doing some thing like the below wouldn't preload the image just as well and allow the cancellation of the preload request?
function preload(url, timeout){
this.canceltimeout = function(){
clearTimeout(this.timeout);
this.loaded = true;
return false;
}
this.abort = function(){
this.xhr.abort();
this.aborted = true;
}
//creates a closure to bind the functions to the right execution scope
this.$_bind = function(method){
var obj = this;
return function (e){ obj[method](e);};
}
//set a default of 10 second timeout
if(timeout == null){
timeout = 10000;
}
this.aborted = false;
this.loaded = false;
this.xhr = new XMLHttpRequest();
this.xhr.onreadystatechange = this.$_bind('canceltimeout');
this.xhr.open('GET', url);
this.xhr.send('');
this.timeout = setTimeout(this.$_bind('abort'), timeout);
}
var llama = new preload('/image.gif');
show_image();
function show_image(){
if(llama.loaded){
var l = new Image();
l.src = '/image.gif';
application.appendChild(l);
}else if(llama.aborted){
var l = document.createElement('p');
l.innerHTML = 'image.gif got cancelled';
application.appendChild(l);
}else{
setTimeout(show_image, 10);
}
return false;
}
Share
Improve this question
asked Jun 1, 2012 at 3:25
Reid JohnsonReid Johnson
1,39414 silver badges20 bronze badges
5
- use jquery man. api.jquery./jQuery.ajax – Patrick Lorio Commented Jun 1, 2012 at 3:30
- 3 could use jquery, but that really doesn't have any bearing as to if using the xhr object to request an image is sufficent to get it loaded into the cache. Jquery is rather bulky and really doesn't help when you only need a tiny portion of it. – Reid Johnson Commented Jun 1, 2012 at 3:37
- I see that the show_image function I posted is kinda jibberish. application is a global variable from some other javascript that I had this code tacked into to try it out. It seemed to work to, but I don't have a lot of different browsers or knowledge about their caches to pull from to see if this would work in a cross browser fashion. – Reid Johnson Commented Jun 1, 2012 at 3:39
- a reason it might not work is due to cross domain policies, besides that it looks good. – Patrick Lorio Commented Jun 1, 2012 at 3:54
- Not worried about cross domain policies as all images on the site where this has been considered are provided directly from our server, but even if not, you could easily get around that with a little server side scripting magic to retrieve the image and hand it back if the call was made to the server side script rather than an image. – Reid Johnson Commented Jun 1, 2012 at 13:38
1 Answer
Reset to default 6The main drawback is that unless you have configured your webserver to provide future freshness info(an Expires
, or Cache-control: max-age
http header that is in the future), the web browser may make a second http request to the server when you set the image.src, or just plain actually use the image in the document. If your web server had sent freshness validation headers(last-modified
, or e-tag
) then the image won't be redownloaded, but the request asking the server for freshness validation will stil be made, which is wasteful and adds latency to the process.
I don't know why, but browsers really like to cache the images when you hold a reference to an Image() object.
If you watch the net panel in a web browsers debug tools, you'll most browsers make the first 2 requests, but not the 3rd. Commenting out the code in the ajax callback, ands you'll see the request made for #3
<script src="http://ajax.googleapis./ajax/libs/jquery/1/jquery.js"></script>
<script>
var f = "0.png?" + (new Date); // 0.png should not have future freshness info headers
$.get(f, function() {
var i = new Image();
i.src = f;
});
setTimeout(function(){
//#3
var i = new Image();
i.src = f;
}, 5000);
</script>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744398992a4572290.html
评论列表(0条)