W3C home > Mailing lists > Public > public-web-perf@w3.org > March 2011

Re: Resource Timing - What's included

From: Kyle Simpson <getify@gmail.com>
Date: Wed, 23 Mar 2011 10:58:08 -0500
Message-ID: <3AE466764EF246A6AE3CC4AD193617C5@spartacus>
To: "Nic Jansma" <Nic.Jansma@microsoft.com>, <public-web-perf@w3.org>
I'm a little concerned about this spec not including "resources pulled from 
cache" in the reporting. Well, let me be even clearer: "duplicate requests 
for the same resource, subsequent ones of which come from cache".

This operation, while not nearly as "costly" as if it's loaded over the 
network, does in fact still affect the timing of things on the page. For 
instance, a <script> tag will block, even for the few dozen ms of pulling 
from cache, other rendering, and in some cases, resource loading.

To have the most accurate picture of timing (and what caused certain 
delays), I think all resource loading should be included, and just marked 
with a type that indicates if it came from browser cache, or was a 
duplicate-from-cache request, or from the network, etc.

Moreover, resources that result in something other than 200/301 still affect 
the performance/timing of the page, so should they (with the respective 
response code) also be included, again for completeness sake? A request for 
a script that results in a 404 or 500 still has a timing cost associated 
with it.

--Kyle







From: Nic Jansma
Sent: Tuesday, March 22, 2011 6:55 PM
To: public-web-perf@w3.org
Subject: Resource Timing - What's included


We have recently been discussing what resources should be included in the 
Resource Timing arrays.  This email is intended to explain our current 
thoughts and solicit feedback and concerns.

Here's a summary of the thoughts and constraints we face when considering 
what resources to include in Resource Timing:
         Take inspiration from, and expose the same information to the web 
developer as in the Net panels in Firebug/Chrome/IE
         Provide a complete list of resources that were download, including 
same-origin and cross-origin
         Respect the privacy of the user by not explicitly exposing 
additional information about what sites they've previously visited (via 
timing attacks targeting content that might be in their cache)
         Protect the security of cross-origin servers and their resources

Below is a small example enumerating the resources that would be included in 
Resource Timing, starting from a sample HTML page.  Our proposal is to 
capture all of the "download-able" resources (from the browser's 
perspective), as opposed to the actual "download-ed" resources.  If we only 
exposed the download-ed resources, and not items that are already in the 
cache, the absence of the resource in Resource Timing gives definitive 
knowledge that the resource is already in the user's cache, which wouldn't 
be respecting their privacy (especially for content on other domains).

Note: This email also exposes some of our thoughts regarding what to do 
about resources from non-same-origin domains, but does not go into details. 
Jatinder will follow up with our thoughts on how we can address resources 
loaded from non-same-origin domains.

Here's a sample HTML page to explain our thoughts.  I've highlighted the 
resources that would be included in Resource Timing, and go into details 
below:

<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <img src="1.jpg" id="1a" />
        <img src="1.jpg" id="1b" />
        <img src="1.jpg" id="1c" />
        <img src="2.jpg" id="2" />
        <img src="http://otherdomain.com/3.jpg" id="3" />
        <img src="4.jpg" id="4" /> <!-- already in cache -->
        <img src="http://otherdomain.com/5.jpg" id="5" /> <!-- already in 
cache -->
        <img src="6.jpg" id="6" /> <!-- redirects to 6b.jpg -->
        <script>
            xmlHttp = new XMLHttpRequest();
            xmlHttp.open("GET", "xhr-get-cacheable.xml");
            xmlHttp.send(null); // resource is cacheable

            xmlHttp = new XMLHttpRequest();
            xmlHttp.open("GET", "xhr-get-cacheable.xml");
            xmlHttp.send(null);

            xmlHttp = new XMLHttpRequest();
            xmlHttp.open("GET", "xhr-get-no-cache.xml");
            xmlHttp.send(null); // resource is not cacheable

            xmlHttp = new XMLHttpRequest();
            xmlHttp.open("GET", "xhr-get-no-cache.xml");
            xmlHttp.send(null);

            var rt = performance.getResourceTimings();
        </script>
    </body>
</html>

With these assumptions:
         The page is loading from mydomain.com.  Two resources (id="3" and 
id="5") are loading from otherdomain.com
         The browser cache is empty except for 4.jpg on mydomain.com, and 
5.jpg on otherdomain.com.  Neither of these cached resources require network 
revalidation.
         All responses are HTTP 200, except 6.jpg which 301 redirects to 
6b.jpg

Notes about each specific resource from the sample HTML page:
         id="1a": Included, because this is the browser's first request for 
1.jpg.  All timestamps filled out as normal.  We associate id="1a" because 
it was the first initiator of the request for 1.jpg.
         id="1b": Not included, because the browser already initiated a 
download via id="1a" and won't initiate a second download.
         id="1c": Not included, because the browser already initiated a 
download via id="1a" and won't initiate a second download.
         id="2": Included, because this was the browser's first request for 
2.jpg.  All timestamps filled out as normal.  This re-uses an existing 
connection so its domainLookup and connectStart times are the same as 
fetchStart (as an example).
         id="3": Included, because this was the browser's first request for 
3.jpg.  On a second domain, so the only timestamps available are fetchStart, 
loadEventStart and loadEventEnd.  All others are zero'd.
         id="4": Included, because this was the browser's first request for 
4.jpg.  Was in the cache, so its times from fetchStart through 
loadEventStart are all 41 (no elapsed time).  This exposes the same 
precision as attaching a load handler to the img and timing the elapsed 
time.
         id="5": Included, because this was the browser's first request for 
5.jpg.  On a second domain, so the only timestamps available are fetchStart, 
loadEventStart and loadEventEnd.  All others are zero'd.  Was in the cache, 
so the time between fetchStart and loadEventStart are very close but exposes 
the same precision as attaching a load handler.
         id="6": Included, because this was the browser's first request for 
6.jpg.  All timestamps filled out as normal.  Was redirected to 6b.jpg, but 
its "url" attribute is the original URL as the developer specified.
         1st xhr-get-cacheable.xml (XHR is cacheable): Included
         2nd xhr-get-cacheable.xml (XHR is cacheable): Not included as the 
browser re-uses the resource
         1st and 2nd xhr-get-no-cache.xml (XHR is set to Cache-Control: 
no-cache): Both are included as the browser gets the resource twice.

This is an example of getResourceTiming() after this page load.  UTC 
timestamps are simplified on a timeline from 0 to 110.  For reference, 
resourceType 4 = RESOURCE_IMAGE and 8 = RESOURCE_XMLHTTPREQUEST:

[{
    "url":"http://mydomain.com/1.jpg",
    "resourceType": 4,
    "id": "1a",
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 10,
    "domainLookupStart": 10,
    "domainLookupEnd": 11,
    "connectStart": 12,
    "connectEnd": 13,
    "requestStart": 13,
    "requestEnd": 14,
    "responseStart": 14,
    "responseEnd": 15,
    "loadEventStart": 16,
    "loadEventEnd": 17
},{
    "url":"http://mydomain.com/2.jpg",
    "resourceType": 4,
    "id": "2"
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 20,
    "domainLookupStart": 21,
    "domainLookupEnd": 21,
    "connectStart": 21,
    "connectEnd": 21,
    "requestStart": 23,
    "requestEnd": 24,
    "responseStart": 24,
    "responseEnd": 25,
    "loadEventStart": 26,
    "loadEventEnd": 27
},{
    "url":"http://otherdomain.com/3.jpg",
    "resourceType": 4,
    "id": "3"
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 31,
    "domainLookupStart": 0,
    "domainLookupEnd": 0,
    "connectStart": 0,
    "connectEnd": 0,
    "requestStart": 0,
    "requestEnd": 0,
    "responseStart": 0,
    "responseEnd": 0,
    "loadEventStart": 36,
    "loadEventEnd": 37
},{
    "url":"http://mydomain.com/4.jpg",
    "resourceType": 4,
    "id": "4"
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 41,
    "domainLookupStart": 41,
    "domainLookupEnd": 41,
    "connectStart": 41,
    "connectEnd": 41,
    "requestStart": 41,
    "requestEnd": 41,
    "responseStart": 41,
    "responseEnd": 41,
    "loadEventStart": 42,
    "loadEventEnd": 42
},{
    "url":"http://otherdomain.com/5.jpg",
    "resourceType": 4,
    "id": "5"
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 51,
    "domainLookupStart": 0,
    "domainLookupEnd": 0,
    "connectStart": 0,
    "connectEnd": 0,
    "requestStart": 0,
    "requestEnd": 0,
    "responseStart": 0,
    "responseEnd": 0,
    "loadEventStart": 52,
    "loadEventEnd": 52
},{
    "url":"http://mydomain.com/6.jpg",
    "resourceType": 4,
    "id": "6",
    "redirectStart": 61,
    "redirectEnd": 70,
    "fetchStart": 70,
    "domainLookupStart": 71,
    "domainLookupEnd": 71,
    "connectStart": 72,
    "connectEnd": 73,
    "requestStart": 73,
    "requestEnd": 74,
    "responseStart": 74,
    "responseEnd": 75,
    "loadEventStart": 76,
    "loadEventEnd": 77
},{
    "url":"http://mydomain.com/xhr-get-cacheable.xml",
    "resourceType": 8,
    "id": ""
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 81,
    "domainLookupStart": 81,
    "domainLookupEnd": 81,
    "connectStart": 82,
    "connectEnd": 83,
    "requestStart": 83,
    "requestEnd": 84,
    "responseStart": 84,
    "responseEnd": 85,
    "loadEventStart": 86,
    "loadEventEnd": 87
},{
    "url":"http://mydomain.com/xhr-get-no-cache.xml",
    "resourceType": 8,
    "id": ""
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 91,
    "domainLookupStart": 91,
    "domainLookupEnd": 91,
    "connectStart": 92,
    "connectEnd": 93,
    "requestStart": 93,
    "requestEnd": 94,
    "responseStart": 94,
    "responseEnd": 95,
    "loadEventStart": 96,
    "loadEventEnd": 97
},{
    "url":"http://mydomain.com/xhr-get-no-cache.xml",
    "resourceType": 8,
    "id": ""
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 100,
    "domainLookupStart": 101,
    "domainLookupEnd": 101,
    "connectStart": 102,
    "connectEnd": 103,
    "requestStart": 103,
    "requestEnd": 104,
    "responseStart": 104,
    "responseEnd": 105,
    "loadEventStart": 106,
    "loadEventEnd": 107
}]

- Nic 
Received on Wednesday, 23 March 2011 15:59:14 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:04:30 UTC