-
-
Notifications
You must be signed in to change notification settings - Fork 139
Description
Currently, i am performing measurements with pages that use HTTP/2 Server push.
However, i found that the "_was_pushed" key in the har of browsertime is inaccurate or misleading.
Note for all Websites presented here i am not affiliated with any of them. They are just examples and came up in a scan.
I stumbled upon a multitude of anomalies here are some examples:
- ) Example Website: https://erisrenee.com/
This website pushes 3 resources:
nghttp https://erisrenee.com -v | grep -C4 PUSH
[ 0.601] recv (stream_id=13) :path: /assets/css/screen.css?v=84ca1c7d60
[ 0.601] recv (stream_id=13) :scheme: https
[ 0.601] recv (stream_id=13, sensitive) accept-encoding: gzip, deflate
[ 0.601] recv (stream_id=13, sensitive) user-agent: nghttp2/1.14.0-DEV
[ 0.601] recv PUSH_PROMISE frame <length=74, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0, promised_stream_id=2)
[ 0.601] recv (stream_id=13) :authority: erisrenee.com
[ 0.601] recv (stream_id=13) :method: GET
[ 0.601] recv (stream_id=13) :path: /assets/css/github.css?v=84ca1c7d60
[ 0.601] recv (stream_id=13) :scheme: https
[ 0.601] recv (stream_id=13, sensitive) accept-encoding: gzip, deflate
[ 0.601] recv (stream_id=13, sensitive) user-agent: nghttp2/1.14.0-DEV
[ 0.601] recv PUSH_PROMISE frame <length=74, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0, promised_stream_id=4)
[ 0.601] recv (stream_id=13) :authority: erisrenee.com
[ 0.601] recv (stream_id=13) :method: GET
[ 0.601] recv (stream_id=13) :path: /assets/js/index.js?v=84ca1c7d60
[ 0.601] recv (stream_id=13) :scheme: https
[ 0.601] recv (stream_id=13, sensitive) accept-encoding: gzip, deflate
[ 0.601] recv (stream_id=13, sensitive) user-agent: nghttp2/1.14.0-DEV
[ 0.601] recv PUSH_PROMISE frame <length=73, flags=0x04, stream_id=13>
/assets/css/screen.css?v=84ca1c7d60
,
/assets/css/github.css?v=84ca1c7d60
, and
/assets/js/index.js?v=84ca1c7d60
.
Now lets open the page manually in chrome and see whether these resources appear in the network view.
Screenshot: https://www.dropbox.com/s/kj9aesotzxb7na3/Selection_006.png?dl=0
In this scenario it is a cloudflare-hosted website so cloudflare even tells us what has been pushed:
cf-h2-pushed:</assets/css/screen.css?v=84ca1c7d60>,</assets/css/github.css?v=84ca1c7d60>,</assets/js/index.js?v=84ca1c7d60>
As expected we discover the .css files, but where is the index.js?
A look into the source shows
<script data-rocketsrc="/assets/js/index.js?v=84ca1c7d60" type="text/rocketscript"></script>
So it is loaded using cloudflares rocket loader.
After a long search for the resource we find it is included in some XHR call.
Screenshot: https://www.dropbox.com/s/82qmlq3r1u6t214/Screenshot%20at%202017-02-07%2017%3A38%3A22.png?dl=0
Since the resource was pushed and is now requested again using javascript does that mean the push was useless? I don't know. But let's now request the page with browsertime.
➜ browsertime git:(master) ✗ mkdir enisrenee && cd enisrenee
➜ enisrenee git:(master) ✗ ../bin/browsertime.js https://erisrenee.com/
[2017-02-07 17:41:41] Running chrome for url: https://erisrenee.com/
[2017-02-07 17:41:41] Testing url https://erisrenee.com/ run 1
[2017-02-07 17:41:45] Testing url https://erisrenee.com/ run 2
[2017-02-07 17:41:49] Testing url https://erisrenee.com/ run 3
[2017-02-07 17:41:53] 24 requests, 308.33 kb, firstPaint: 1.15s (±36.03ms), DOMContentLoaded: 984ms (±44.63ms), Load: 1.21s (±35.43ms), rumSpeedIndex: 1145 (±36.03) (3 runs)
[2017-02-07 17:41:53] Wrote data to browsertime-results/erisrenee.com/2017-02-07T174141+0100
Now lets see whether any pushes were recorded in the har:
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.har | jq . | grep was_push | wc -l
0
Well weird that is weird. We know that resources are pushed from our previous exploration.
Lets see if we find the pushed resources.
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.har | jq -cr '.log.entries[] | .request.url' | grep github.css | wc -l
0
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.har | jq -cr '.log.entries[] | .request.url' | grep screen.css | wc -l
0
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.har | jq -cr '.log.entries[] | .request.url' | grep index.js
https://erisrenee.com/cdn-cgi/pe/bag2?r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjquery%2F1.12.2%2Fjquery.min.js&r[]=https%3A%2F%2Ferisrenee.com%2Fassets%2Fjs%2Findex.js%3Fv%3D84ca1c7d60&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsmooth-scroll%2F9.1.2%2Fjs%2Fsmooth-scroll.min.js&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.2.0%2Fhighlight.min.js
https://erisrenee.com/cdn-cgi/pe/bag2?r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjquery%2F1.12.2%2Fjquery.min.js&r[]=https%3A%2F%2Ferisrenee.com%2Fassets%2Fjs%2Findex.js%3Fv%3D84ca1c7d60&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsmooth-scroll%2F9.1.2%2Fjs%2Fsmooth-scroll.min.js&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.2.0%2Fhighlight.min.js
https://erisrenee.com/cdn-cgi/pe/bag2?r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjquery%2F1.12.2%2Fjquery.min.js&r[]=https%3A%2F%2Ferisrenee.com%2Fassets%2Fjs%2Findex.js%3Fv%3D84ca1c7d60&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsmooth-scroll%2F9.1.2%2Fjs%2Fsmooth-scroll.min.js&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.2.0%2Fhighlight.min.js
So we do not find the css files in the .har and only the rocket-loader request for the index.js
.
Now lets look at the browsertime.json
, maybe there are some clues what is going on.
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.json | jq . | grep screen.css
"name": "https://erisrenee.com/assets/css/screen.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/screen.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/screen.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/screen.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/screen.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/screen.css?v=84ca1c7d60",
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.json | jq . | grep github.css
"name": "https://erisrenee.com/assets/css/github.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/github.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/github.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/github.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/github.css?v=84ca1c7d60",
"name": "https://erisrenee.com/assets/css/github.css?v=84ca1c7d60",
➜ enisrenee git:(master) ✗ cat browsertime-results/erisrenee.com/2017-02-07T174141+0100/browsertime.json | jq . | grep index.js
"name": "https://erisrenee.com/cdn-cgi/pe/bag2?r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjquery%2F1.12.2%2Fjquery.min.js&r[]=https%3A%2F%2Ferisrenee.com%2Fassets%2Fjs%2Findex.js%3Fv%3D84ca1c7d60&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsmooth-scroll%2F9.1.2%2Fjs%2Fsmooth-scroll.min.js&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.2.0%2Fhighlight.min.js",
"name": "https://erisrenee.com/assets/js/index.js?v=84ca1c7d60",
"name": "https://erisrenee.com/cdn-cgi/pe/bag2?r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjquery%2F1.12.2%2Fjquery.min.js&r[]=https%3A%2F%2Ferisrenee.com%2Fassets%2Fjs%2Findex.js%3Fv%3D84ca1c7d60&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsmooth-scroll%2F9.1.2%2Fjs%2Fsmooth-scroll.min.js&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.2.0%2Fhighlight.min.js",
"name": "https://erisrenee.com/assets/js/index.js?v=84ca1c7d60",
"name": "https://erisrenee.com/cdn-cgi/pe/bag2?r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjquery%2F1.12.2%2Fjquery.min.js&r[]=https%3A%2F%2Ferisrenee.com%2Fassets%2Fjs%2Findex.js%3Fv%3D84ca1c7d60&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsmooth-scroll%2F9.1.2%2Fjs%2Fsmooth-scroll.min.js&r[]=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.2.0%2Fhighlight.min.js",
"name": "https://erisrenee.com/assets/js/index.js?v=84ca1c7d60",
So the css appears twice each run with different timings and the index.js
appears once for the push and once for the rocket loader. This is very weird.
HAR: https://gist.github.com/worenga/cfd6cfaefe606f27b37153f4e1d6bef2
JSON: https://gist.github.com/worenga/c3e6d6c2069c750e2dbf67efec3bbc76
- ) Example
Example Website: https://www.thecopycamp.com
Again, not affiliated in any kind.
Note that this website pushes 13 resources.
➜ ~ nghttp https://www.photographerstechsupport.com -v | grep PUSH
[ 0.691] recv PUSH_PROMISE frame <length=91, flags=0x04, stream_id=13>
[ 0.691] recv PUSH_PROMISE frame <length=104, flags=0x04, stream_id=13>
[ 0.691] recv PUSH_PROMISE frame <length=90, flags=0x04, stream_id=13>
[ 0.691] recv PUSH_PROMISE frame <length=96, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=88, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=96, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=94, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=93, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=110, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=103, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=103, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=104, flags=0x04, stream_id=13>
[ 0.692] recv PUSH_PROMISE frame <length=86, flags=0x04, stream_id=13>
➜ ~ nghttp https://www.photographerstechsupport.com -v | grep PUSH | wc -l
13
Also in chrome we see 13 pushes:
https://www.dropbox.com/s/mt4q1tqe8ddgji3/Selection_009.png?dl=0
Now lets fetch this page using browsertime:
➜ browsertime git:(master) ✗ ./bin/browsertime.js https://www.photographerstechsupport.com
[2017-02-07 18:29:41] Running chrome for url: https://www.photographerstechsupport.com
[2017-02-07 18:29:41] Testing url https://www.photographerstechsupport.com run 1
[2017-02-07 18:29:45] Testing url https://www.photographerstechsupport.com run 2
[2017-02-07 18:29:49] Testing url https://www.photographerstechsupport.com run 3
[2017-02-07 18:29:52] 9 requests, 110.11 kb, firstPaint: 807ms (±121.39ms), DOMContentLoaded: 820ms (±121.76ms), Load: 872ms (±123.10ms), rumSpeedIndex: 807 (±121.39) (3 runs)
[2017-02-07 18:29:52] Wrote data to browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100
lets scan the HAR file
➜ browsertime git:(master) ✗ cat browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100/browsertime.har| jq . | grep -i push
"name": "cf-h2-pushed",
"name": "cf-h2-pushed",
"_was_pushed": 1,
"name": "cf-h2-pushed",
"_was_pushed": 1,
"_was_pushed": 1,
These are clearly not 13*3 resources...,
➜ browsertime git:(master) ✗ cat browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100/browsertime.har| jq -r '.log.entries[] | select(contains({'_was_pushed'})) | "\(.pageref): \(.request.url)"'
page_1-1: https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js
page_1-1-1: https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js
page_1-1-1: https://www.photographerstechsupport.com/wp-content/themes/interface/js/jquery.cycle.all.min.js
So according to the har, in the 1st run nothing was pushed, in the 2nd run jquery.js
was pushed and in the 3rd run jquery.js
and jquery.cycle.all.min.js
were pushed.
Now we know that for example jquery.js
and style.css
were pushed, but are they contained in the har?
➜ browsertime git:(master) ✗ cat browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100/browsertime.har| jq -r '.log.entries[] | select(.request.url | contains("jquery.js")) | "\(.pageref): \(.request.url)"'
page_1-1: https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js
page_1-1-1: https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js
➜ browsertime git:(master) ✗ cat browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100/browsertime.har| jq -r '.log.entries[] | select(.request.url | contains("style.css")) | "\(.pageref): \(.request.url)"' | wc -l
0
Now what about browsertime.json
?
➜ browsertime git:(master) ✗ cat browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100/browsertime.json | jq . | grep style.css
"name": "https://www.photographerstechsupport.com/wp-content/themes/interface/style.css",
"name": "https://www.photographerstechsupport.com/wp-content/themes/interface/style.css",
"name": "https://www.photographerstechsupport.com/wp-content/themes/interface/style.css",
➜ browsertime git:(master) ✗ cat browsertime-results/www.photographerstechsupport.com/2017-02-07T182941+0100/browsertime.json | jq . | grep jquery.js
"name": "https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js",
"name": "https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js",
"name": "https://www.photographerstechsupport.com/wp-includes/js/jquery/jquery.js",
This is weird as well.
HAR: https://gist.github.com/worenga/eae418783fde60278787806404775584
JSON: https://gist.github.com/worenga/371766ad2379f5b660c9f71e72dd7408
Is there a reliable way to tell which and whether resources have been pushed?