Using image.complete to find if image is cached on chrome?
Asked Answered
A

1

8

I have been trying to find out if an external image is cached on the browser with js, this is the code I have so far:

<html>
    <head></head>
    <body>

    <script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>

    <script>

        function cached( url ) {
            $("#imgx").attr({"src":url});
            if(document.getElementById("imgx").complete) {
                return true;
            } else {
                if( document.getElementById("imgx").width > 0 ) return true;
            }

            return false;
        }

    </script>

    <img id="imgx" src=""  />

    <script>

        $(document).ready(function(){
            alert(cached("http://www.google.com/images/srpr/nav_logo80.png"));
        });

    </script>

    </body>
</html>

It works perfectly on firefox but it always returns false on chrome.

Does someone has any idea how to make it work with chrome?

Aerostation answered 21/10, 2011 at 4:28 Comment(5)
Why should it matter whether or not an asset is cached? :/Inhospitality
W3C standard doesn't have any such API, so chance are you will be using some browser specific hacks which is not a good thing to doMorea
Also even if the image is cached, loading the image is still most likely asynchronous, and it's unlikely the browser has finished loading and displaying the image before it executes the next JavaScript line.Sclerenchyma
related #1978371Conjuncture
@Matchu, if you know the urls to cached images (use localStorage) they can be painted more early than waiting for it at a later load (at DOMContentLoaded or load event because CSS and other stuff may have priority but some more images would be nice to see if possible)Trigonal
C
15

I've rewritten your code in plain JavaScript, to make it more independent on jQuery. The core functionality hasn't changed. Fiddle: http://jsfiddle.net/EmjQG/2/

function cached(url){
    var test = document.createElement("img");
    test.src = url;
    return test.complete || test.width+test.height > 0;
}
var base_url = "http://www.google.com/images/srpr/nav_logo80.png"
alert("Expected: true or false\n" +
      cached(base_url)
      + "\n\nExpected: false (cache-busting enabled)\n" +
      cached(base_url + "?" + new Date().getTime()));
//false = not cached, true = cached

The first time, I get false and false. After I run the code again, I get true and false.


Using .complete and .height + .width gives the expected results (FF 3.6.23, Chromium 14).

It's very likely that you've disabled the caching at your Chrome browser. If not, check the HTTP headers of your served image (Is Cache-control present?). This header exist at the Google sample

If you want to detect when an image has (not) finished loading, have a look at this question.

Couchman answered 21/10, 2011 at 9:19 Comment(5)
I've cache enabled and Cache-control is not present. What I want to know if to know if the image load instantly (from cache) or it loads progressively. The code I posted works fine on FF but it never works on chrome.Aerostation
@Aerostation I have included a working test case. See jsfiddle.net/EmjQG/2.Couchman
Does that returns "true - false" on chrome too? for me it always returns false - false on chrome, I guess the best cross browser solution will be to setup a counter for timing the image load.Aerostation
@Aerostation It returns false, false, then true, false (Chromium 14). Watch the network feature of the Developer console to confirm that the image is cached.Couchman
Hmm... all that said, for some reason, I can't get this to work in Chromium or Firefox presently. In Firefox it always returns false, and on Chromium it always returns false on the first load in a new tab - even if I can clearly see in the network tab that the response was served from the cache without revalidation - and thereafter returns true. It seems like this answer no longer functions.Conformance

© 2022 - 2024 — McMap. All rights reserved.