none
How can I tell when/if a VML Image is loaded?

    Question

  •  

    I have v:image elements on my page, and I need to know when the images themselves have finished loading. I have tried adding an onload event handler to these elements, hoping it would fire the same way it does on an img tag but this doesn't work.

     

    Does anyone know anyway at all.. even polling a certain property which might change when the v:image has loaded to find out when an image has finished loading?

     

    So far, I have trie:

     

    Adding an onload event to the element - This doesn't fire

     

    Checking for a .complete property - There isn't one

     

    Loading the images into img elements first, and then setting the src property of the v:image to the img.src once the img elements have loaded. My thinking here is that would pre cache the images, so they would load immediatly into the v:image - This doesn't work because setting the src property of the v:image causes it to download the image again rather than using the cached version just downloaded

     

    Thanks in advance

    Saturday, May 03, 2008 7:58 AM

All replies

  •  Martin Booth wrote:

     

    Loading the images into img elements first, and then setting the src property of the v:image to the img.src once the img elements have loaded. My thinking here is that would pre cache the images, so they would load immediatly into the v:image - This doesn't work because setting the src property of the v:image causes it to download the image again rather than using the cached version just downloaded

     

     

    At what point in the page life cycle are you setting the src property of the v:image? 

    How do you know it downloads the image again?

    Are you using Fiddler to confirm the actual behaviour?

     

    Consider using code that executes after the body onload event (by using a setTimeout if necessary).

     

    Sunday, May 04, 2008 9:28 PM
  • Thanks for your reply. I checked with fiddler, and I was mistaken in thinking that it downloads the whole image again, instead it gets a 304 respone (not modified).

    This is certainly better than downloading the whole image a second time, however it still makes contact with the server and it can easily be a couple of seconds later that the v:image has finished loading over when the html image finished.

    This is an issue which has been raised on these forums, but there has been no solution given to it, apart from a comment that it works differently in IE7, and I have been testing with IE6.

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3143403&SiteID=1 is my reference.

    Unfortunatly, I will have to assume that its not possible to do what I'm trying, and hope that most of the websites user's are using IE7 by now.

    Incidently, for anyone else reading this, VML does not always send a request to the server.. It will not send a request if the image has first been loaded into another VML element, but since no VML elements that I can see have a way of reporting that the Image is loaded, this piece of information can't help me.

    To summerise: Loading an image into one VML element.. then later into another, the second VML element will not contact the server; loading the image into an HTML image and then later into another element, the VML element will contact the server a second time.

    Regards

    Martin
    Monday, May 05, 2008 4:42 AM
  •  

    The request for the image that ends up in a 304 response will have carried the pragma: no-cache header.

     

    Typically IE will request using pragma:no-cache any resource it has not in that session (the time the IE process has been active) previously requested.  IE6 has a bug where during the loading of a HTML page the marking additional resources that it needs as requested in the current session does not occur until after the document was full loaded. This 'loading' period extends to include any code that runs during the onload event.

     

    This bug has serious repercutions for performance when an HTML resource uses the same image many times and that image has not been seen before in that session.  It causes excessive requests being sent to the server for the same resource over and over.  The problem is mitigated a little since the most common response is 304 but as you pointed out on a high latency link this is still a big problem.

     

    If this problem is serious enough for you there are some steps you can take but you need to be sure they are worth taking.

     

    In the HTML of the page include a display:none DIV that contains a list of the imgs you need.  Leave the src properties of image elements unspecified.  Create a Javascript function to assign the the appropriate URL to the src properties of the image elements.  In the body onload event attribute place code such as:-

     

    setTimeout(deferedLoading, 100)

     

    where deferedLoading is the name of function that assigns the URLs to src elements.

     

    Since deferedLoading will occur after the document is fully loaded all the imgs in the undisplayed DIV will have been marked as requested in this session.  Hence subsequent uses of their URLs should not result in further requests.  This assumes of course that appropriate headers are attached to the original requests which allows the resources to be cached as fresh content.

     

    Note I haven't actually tested this in the specific case of a VML image but I'd be farily confident it would work.

     

    The added complexity of this solution and its dependancy on Javascript intervention needs to be weighed in the choice to use it.  Also note that in some cases it can be slower since the whole page without its imgs will be layed out and painted and then the layout will be changed multiple times as each img is added.  This will likely be more expensive than multiple 304s on a low latency link.

     

    The solution can be taken even further to eliminate the multiple layout costs at the expense of even further complexity.   Instead of including imgs with undefined src attributes, the original page contains limited or no actual displayed HTML.  Instead the deferedLoading function fetches the HTML to render in separate request (via a XmlHttpRequest) and adds it to the document via a innerHTML assignment.

     

    One further step (which is what I actually do) is separate the data from the presentation.  Bring the data down as XML, perform a transform using XSL and assign the resulting HTML to an innerHTML property.  The data in XML form is often much smaller the resulting HTML and is the only part which actually varies for the request.  All other parts including to the containing HTML resource and the XSL can be cachable.

     

     

     

     

     

     

    Monday, May 05, 2008 3:18 PM