User:Brahmana/Netwerk Docs/Image Loading v2

From MozillaWiki
Jump to: navigation, search

This is what I could understand looking at the code. I use the terms channel, HttpChannel and nsHttpChannel interchangeably here. They all basically mean the channel used to load the image.

It would be great if someone more knowledgeable (like biesi or bz) can validate what I have written here and also add anything that I am missing.

  • A nsHTMLImageElement object is created for every image that needs to be loaded. Setting the "src" attribute of this object triggers the image loading. -- This is only true for images loaded via <img> tags.
  • nsImageLoadingContent (which is a parent class of nsHTMLImageElement) and nsContentUtils aid in the loading process.
  • Other images like the ones referenced in CSS style definitions, background images, etc do not go through nsImageLoadingContent-nsHTMLImageElement combination. They however come to nsContentUtils (via its LoadImage function) and what is described below holds good for all image loads.

  • A single image, if referenced by multiple documents in different tabs, will still be downloaded, decoded and stored only once. imgLoader takes care of this grouping/multiplexing.
  • This means that for all the image references there is only one underlying HttpChannel which is fetching the image - either from the network or the http cache.
  • The nsHttpChannel is wrapped inside a imgRequest. For every image (not every image reference) there is a imgRequest.
  • For this grouping to work every individual image reference (like a <img> tag or a reference in CSS) is served by a imgRequestProxy which is an observer on the imgRequest.
  • imgRequest gets the notifications from the channel via a wrapper named ProxyListener and it in turn notifies the imgRequestProxy
  • The image data received is stored in the "mImage" member of imgRequest, also referenced with the same name by imgRequestProxy. This mImage is a mozilla::imageLib::Image
  • This imgRequestProxy bubbles back to nsImageLoadingContent which hands it off to the containing document. The document then tracks the image via this imgRequestProxy
  • Apart from the network cache there is another imgCache, which is just an in-memory HashTable. Every entry inside it is known as imgCacheEntry
  • imgCacheEntry holds a reference to the imgRequest which in turn holds a reference to the mImage. We do not hold a reference to the channel. It is freed in OnStopRequest as it is no longer usable after all the data has been read.
  • When imgLoader is asked to load an image, it first looks up the imgCache to see if an imgCacheEntry exists for the given URL.
  • If yes and if it is usable, the same imgRequest and subsequently the same mImage are used. A new imgRequestProxy is created for this use but no channel is created. A channel might be created to check the validity of the cache entry however.
  • Else, a new nsHttpChannel is created, which is wrapped around by a imgRequest (along with a corresponding imgRequestProxy) and this imgRequest is dumped in the imgCache as an imgCacheEntry.
  • When fetching an image, which is not in the imgCache, via the new channel the http cache might kick in and we might not hit the network at all - like for any other http request.

Differences in the creation of this HttpChannel compared to other non-image loads:

Here is the code : http://mxr.mozilla.org/mozilla-central/source/image/src/imgLoader.cpp#524

  1. No loadGroup - null is explicitly passed. A new loadGroup is assigned later and this has nothing to do with the document's loadGroup
  2. notificationCallbacks are those of the document's loadGroup - which should still refer to the docShell of the document
    • However in imgRequest::Init this callback is replaced with imgRequest. The old callback is cached in mPrevChannelSink. Except for nsIChannelEventSink all other GetInterface() requests to imgRequest (via channel->notificationCallbacks->GetInterface()) are passed to the old callback.