Scripts & Stylesheets before Start Render (Mobile)

How many scripts and stylesheets are downloaded before rendering starts?

SELECT numJsCss, count(*) as numPages 
FROM (
  SELECT p.pageid, count(*) as numJsCss
  FROM httparchive:runs.latest_requests_mobile as r 
    JOIN (
      SELECT pageid, (1000*startedDateTime)+renderStart as startRender 
      FROM httparchive:runs.latest_pages_mobile 
      WHERE renderStart > 0 
    ) as p
  ON r.pageid=p.pageid
  WHERE status=200 and ((1000*r.startedDateTime)+time) < p.startRender and (lower(mimeType) contains "script" OR lower(mimeType) contains "css")
  GROUP BY p.pageid
)
WHERE numJsCss <= 30
GROUP BY numJsCss order by numJsCss asc;

Note that I cut off the tail at 30 scripts & stylesheets. The median is 7.

The determination of “before rendering starts” is an approximation based on the following:

  • For the page we know:
  • startedDateTime - The epoch time (in seconds) that the main page request started, eg 1375347601 seconds.
  • renderStart - The offset (in milliseconds) at which rendering started, eg, 700 ms.
  • We determine “startRender” by adding these two values, eg, 1375347601 + 0.700 = 1375347601.7.
  • For each subresource we know:
  • startedDateTime - same as above (in seconds), eg 1375347601 seconds.
  • time - How long (in milliseconds) it took the request to finish, eg 300 ms.
  • We determine “doneFetching” by adding these two values, eg, 1375347601 + 0.300 = 1375347601.3.

In this example doneFetching < startRender and so the subresource is counted in the result set (assuming it’s a script or stylesheet). However, this could be incorrect because startedDateTime doesn’t have the granularity of milliseconds. Suppose the page’s startedDateTime was 1375347601.1 and the subresource’s startedDateTime was 1375347601.9. This would result in startRender = 1375347601.8 and doneFetching = 1375347602.2 in which case the subresource should NOT be included in the result set.

The error can occur in the other direction as well. If the main page’s startedDateTime = 1375347601 and renderStart = 1500, and the subresource’s startedDateTime = 1375347602 and time = 600 we get startRender = 1375347602.5 and doneFetching = 1375347602.6, so the the subresource is not included in the result set. However, if the actual page startedDateTime was 1375347601.9 and the subresource’s startedDateTime was 1375347602.1 we get startRender = 1375347601.9 + 1.5 = 1375347603.4 and doneFetching = 1375347602.1 + 0.6 = 1375347602.7, in which case the subresource SHOULD be included in the result set.

The results above are the best approximation for scripts & stylesheets downloaded before rendering stats. But we can also determine a lower bound and upper bound by respectively subtracting and adding 1 second to the page’s doneRender time. The lower bound is:

((1000*r.startedDateTime)+time) < (p.startRender-1000)

and the upper bound is:

((1000*r.startedDateTime)+time) < (p.startRender+1000)

Here are the resulting charts for lower bound (median = 6):

and upper bound (median = 9):

Another factor is that just because a script or stylesheet is loaded before rendering starts does not mean it blocks rendering. For example, a script might be loaded asynchronously and thus wouldn’t block rendering.

For completeness, here’s the SQL for computing the median. Remember to subtract and add 1000 ms to startRender to find the medians for the lower and upper bounds.

SELECT NTH(50, quantiles(numJsCss))  
FROM (  
  SELECT p.pageid, count(*) as numJsCss
  FROM httparchive:runs.latest_requests_mobile as r 
    JOIN (
      SELECT pageid, (1000*startedDateTime)+renderStart as startRender 
      FROM httparchive:runs.latest_pages_mobile 
      WHERE renderStart > 0 
    ) as p
  ON r.pageid=p.pageid
  WHERE status=200 and ((1000*r.startedDateTime)+time) < p.startRender and (lower(mimeType) contains "script" OR lower(mimeType) contains "css")
  GROUP BY p.pageid
)
3 Likes