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
)
```