Skip to content

Instantly share code, notes, and snippets.

@h1994st
Last active January 8, 2016 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h1994st/f21cdb7125a65c8f7182 to your computer and use it in GitHub Desktop.
Save h1994st/f21cdb7125a65c8f7182 to your computer and use it in GitHub Desktop.
HTTP/2 Dependency & Priority

Environment

Console output

Dependency tree anchor

           +---------------+
           |     id=0      |
           +---------------+
           ^       ^       ^
          /        |        \
    w=201/    w=101|         \w=1
        /          |          \
    +-----+     +-----+     +-----+
    |id=3 |     |id=5 |     |id=7 |
    +-----+     +-----+     +-----+
       ^                       ^
       |                       |
    w=1|                    w=1|
       |                       |
    +-----+                 +-----+
    |id=11|                 |id=9 |
    +-----+                 +-----+

Stream 3, 5, 7, 9, 11 are created by PRIORITY frames (Details):

[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
          (dep_stream_id=0, weight=201, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
          (dep_stream_id=0, weight=101, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
          (dep_stream_id=0, weight=1, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
          (dep_stream_id=7, weight=1, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
          (dep_stream_id=3, weight=1, exclusive=0)
Stream 13: GET /
Stream 15: GET /main.css
Stream 17: GET /jsinhead.js
Stream 19: GET /nginx-logo.png
Stream 21: GET /main.js

Dependency tree

                        +--------------------+
                        |        id=0        |
                        +--------------------+
                       ^              ^       ^
                      /               |        \
                w=201/           w=101|         \w=1
                    /                 |          \
                +-----+            +-----+     +-----+
                |id=3 |            |id=5 |     |id=7 |
                +-----+            +-----+     +-----+
               ^   ^   ^              ^           ^
              /    |    \             |           |
          w=1/  w=2|     \w=2      w=2|        w=1|
            /      |      \           |           |
        +-----+ +-----+ +-----+    +-----+     +-----+
        |id=11| |id=15| |id=17|    |id=21|     |id=9 |
        +-----+ +-----+ +-----+    +-----+     +-----+
          ^ ^
         /   \
    w=16/     \w=12
       /       \
   +-----+  +-----+
   |id=13|  |id=19|
   +-----+  +-----+

Results

Result from "Nginx 1.9.5" server (https://film.h1994st.com):

id  responseEnd requestStart  process code size request path
 13   +165.86ms       +222us 165.64ms  200  823 /
 15      +1.80s    +165.97ms    1.63s  200   23 /main.css
 17      +1.80s    +165.00ms    1.63s  200   27 /jsinhead.js
 19      +1.80s    +166.02ms    1.63s  200  370 /nginx-logo.png
 21      +1.80s    +166.03ms    1.63s  200   43 /main.js

Result from "nghttpd nghttp2/1.3.4" server (https://localhost:8080):

 id  responseEnd requestStart  process code size request path
 13      +818us       +186us    632us  200  823 /
 21     +2.00ms      +1.00ms   1.00ms  200   43 /main.js
 15     +2.06ms       +937us   1.12ms  200   23 /main.css
 17     +2.07ms       +963us   1.10ms  200   27 /jsinhead.js
 19     +2.10ms       +982us   1.12ms  200  370 /nginx-logo.png

I'm just wondering why the response sequences are different.

  • Command: nghttp -nvsa --no-push https://film.h1994st.com
  • Server: Nginx 1.9.5
[  0.258] Connected
[  0.429][NPN] server offers:
          * h2
          * http/1.1
The negotiated protocol: h2
[  2.203] send SETTINGS frame <length=18, flags=0x00, stream_id=0>
          (niv=3)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
          [SETTINGS_ENABLE_PUSH(0x02):0]
[  2.203] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
          (dep_stream_id=0, weight=201, exclusive=0)
[  2.203] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
          (dep_stream_id=0, weight=101, exclusive=0)
[  2.203] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
          (dep_stream_id=0, weight=1, exclusive=0)
[  2.203] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
          (dep_stream_id=7, weight=1, exclusive=0)
[  2.203] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
          (dep_stream_id=3, weight=1, exclusive=0)
[  2.203] send HEADERS frame <length=40, flags=0x25, stream_id=13>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /
          :scheme: https
          :authority: film.h1994st.com
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  2.203] recv SETTINGS frame <length=18, flags=0x00, stream_id=0>
          (niv=3)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):2147483647]
          [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
[  2.203] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
          (window_size_increment=2147418112)
[  2.203] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  2.368] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  2.368] recv (stream_id=13) :status: 200
[  2.368] recv (stream_id=13) server: nginx/1.9.5
[  2.368] recv (stream_id=13) date: Tue, 27 Oct 2015 08:49:57 GMT
[  2.368] recv (stream_id=13) content-type: text/html
[  2.368] recv (stream_id=13) content-length: 823
[  2.368] recv (stream_id=13) last-modified: Tue, 27 Oct 2015 08:36:22 GMT
[  2.368] recv (stream_id=13) etag: "562f3786-337"
[  2.368] recv (stream_id=13) accept-ranges: bytes
[  2.368] recv HEADERS frame <length=134, flags=0x04, stream_id=13>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  2.368] recv DATA frame <length=823, flags=0x01, stream_id=13>
          ; END_STREAM
[  2.369] send HEADERS frame <length=20, flags=0x25, stream_id=15>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=3, weight=2, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /main.css
          :scheme: https
          :authority: film.h1994st.com
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  2.369] send HEADERS frame <length=22, flags=0x25, stream_id=17>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=3, weight=2, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /jsinhead.js
          :scheme: https
          :authority: film.h1994st.com
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  2.369] send HEADERS frame <length=24, flags=0x25, stream_id=19>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=12, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /nginx-logo.png
          :scheme: https
          :authority: film.h1994st.com
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  2.369] send HEADERS frame <length=19, flags=0x25, stream_id=21>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=5, weight=2, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /main.js
          :scheme: https
          :authority: film.h1994st.com
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  4.001] recv (stream_id=15) :status: 200
[  4.001] recv (stream_id=15) server: nginx/1.9.5
[  4.001] recv (stream_id=15) date: Tue, 27 Oct 2015 08:49:59 GMT
[  4.001] recv (stream_id=15) content-type: text/css
[  4.001] recv (stream_id=15) content-length: 23
[  4.001] recv (stream_id=15) last-modified: Mon, 26 Oct 2015 13:48:32 GMT
[  4.001] recv (stream_id=15) etag: "562e2f30-17"
[  4.001] recv (stream_id=15) accept-ranges: bytes
[  4.001] recv HEADERS frame <length=131, flags=0x04, stream_id=15>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  4.001] recv DATA frame <length=23, flags=0x01, stream_id=15>
          ; END_STREAM
[  4.001] recv (stream_id=17) :status: 200
[  4.001] recv (stream_id=17) server: nginx/1.9.5
[  4.001] recv (stream_id=17) date: Tue, 27 Oct 2015 08:49:59 GMT
[  4.001] recv (stream_id=17) content-type: application/javascript
[  4.001] recv (stream_id=17) content-length: 27
[  4.001] recv (stream_id=17) last-modified: Tue, 27 Oct 2015 08:36:39 GMT
[  4.001] recv (stream_id=17) etag: "562f3797-1b"
[  4.001] recv (stream_id=17) accept-ranges: bytes
[  4.001] recv HEADERS frame <length=145, flags=0x04, stream_id=17>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  4.001] recv DATA frame <length=27, flags=0x01, stream_id=17>
          ; END_STREAM
[  4.003] recv (stream_id=19) :status: 200
[  4.003] recv (stream_id=19) server: nginx/1.9.5
[  4.003] recv (stream_id=19) date: Tue, 27 Oct 2015 08:49:59 GMT
[  4.003] recv (stream_id=19) content-type: image/png
[  4.003] recv (stream_id=19) content-length: 370
[  4.003] recv (stream_id=19) last-modified: Fri, 26 Apr 2013 20:36:51 GMT
[  4.003] recv (stream_id=19) etag: "517ae563-172"
[  4.003] recv (stream_id=19) accept-ranges: bytes
[  4.003] recv HEADERS frame <length=134, flags=0x04, stream_id=19>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  4.003] recv DATA frame <length=370, flags=0x01, stream_id=19>
          ; END_STREAM
[  4.003] recv (stream_id=21) :status: 200
[  4.003] recv (stream_id=21) server: nginx/1.9.5
[  4.003] recv (stream_id=21) date: Tue, 27 Oct 2015 08:49:59 GMT
[  4.003] recv (stream_id=21) content-type: application/javascript
[  4.003] recv (stream_id=21) content-length: 43
[  4.003] recv (stream_id=21) last-modified: Mon, 26 Oct 2015 13:52:48 GMT
[  4.003] recv (stream_id=21) etag: "562e3030-2b"
[  4.003] recv (stream_id=21) accept-ranges: bytes
[  4.003] recv HEADERS frame <length=145, flags=0x04, stream_id=21>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  4.003] recv DATA frame <length=43, flags=0x01, stream_id=21>
          ; END_STREAM
[  4.003] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
***** Statistics *****

Request timing:
  responseEnd: the  time  when  last  byte of  response  was  received
               relative to connectEnd
 requestStart: the time  just before  first byte  of request  was sent
               relative  to connectEnd.   If  '*' is  shown, this  was
               pushed by server.
      process: responseEnd - requestStart
         code: HTTP status code
         size: number  of  bytes  received as  response  body  without
               inflation.
          URI: request URI

see http://www.w3.org/TR/resource-timing/#processing-model

sorted by 'complete'

id  responseEnd requestStart  process code size request path
 13   +165.86ms       +222us 165.64ms  200  823 /
 15      +1.80s    +165.97ms    1.63s  200   23 /main.css
 17      +1.80s    +165.00ms    1.63s  200   27 /jsinhead.js
 19      +1.80s    +166.02ms    1.63s  200  370 /nginx-logo.png
 21      +1.80s    +166.03ms    1.63s  200   43 /main.js
  • Command: nghttp -nvsa --no-push https://localhost:8080
  • Server: nghttpd nghttp2/1.3.4
[  0.002] Connected
The negotiated protocol: h2
[  0.004] recv SETTINGS frame <length=6, flags=0x00, stream_id=0>
          (niv=1)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[  0.004] send SETTINGS frame <length=18, flags=0x00, stream_id=0>
          (niv=3)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
          [SETTINGS_ENABLE_PUSH(0x02):0]
[  0.004] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
          (dep_stream_id=0, weight=201, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
          (dep_stream_id=0, weight=101, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
          (dep_stream_id=0, weight=1, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
          (dep_stream_id=7, weight=1, exclusive=0)
[  0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
          (dep_stream_id=3, weight=1, exclusive=0)
[  0.005] send HEADERS frame <length=38, flags=0x25, stream_id=13>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /
          :scheme: https
          :authority: localhost:8080
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  0.005] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.005] recv (stream_id=13) :status: 200
[  0.005] recv (stream_id=13) server: nghttpd nghttp2/1.3.4
[  0.005] recv (stream_id=13) content-length: 823
[  0.005] recv (stream_id=13) cache-control: max-age=3600
[  0.005] recv (stream_id=13) date: Tue, 27 Oct 2015 08:49:56 GMT
[  0.005] recv (stream_id=13) last-modified: Tue, 27 Oct 2015 08:48:13 GMT
[  0.005] recv HEADERS frame <length=83, flags=0x04, stream_id=13>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.005] recv DATA frame <length=823, flags=0x01, stream_id=13>
          ; END_STREAM
[  0.005] send HEADERS frame <length=20, flags=0x25, stream_id=15>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=3, weight=2, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /main.css
          :scheme: https
          :authority: localhost:8080
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  0.005] send HEADERS frame <length=22, flags=0x25, stream_id=17>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=3, weight=2, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /jsinhead.js
          :scheme: https
          :authority: localhost:8080
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  0.005] send HEADERS frame <length=24, flags=0x25, stream_id=19>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=12, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /nginx-logo.png
          :scheme: https
          :authority: localhost:8080
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  0.005] send HEADERS frame <length=19, flags=0x25, stream_id=21>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=5, weight=2, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /main.js
          :scheme: https
          :authority: localhost:8080
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.3.4
[  0.006] recv (stream_id=21) :status: 200
[  0.006] recv (stream_id=21) server: nghttpd nghttp2/1.3.4
[  0.006] recv (stream_id=21) content-length: 43
[  0.006] recv (stream_id=21) cache-control: max-age=3600
[  0.006] recv (stream_id=21) date: Tue, 27 Oct 2015 08:49:56 GMT
[  0.006] recv (stream_id=21) last-modified: Tue, 27 Oct 2015 08:48:09 GMT
[  0.006] recv HEADERS frame <length=33, flags=0x04, stream_id=21>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.006] recv DATA frame <length=43, flags=0x01, stream_id=21>
          ; END_STREAM
[  0.006] recv (stream_id=15) :status: 200
[  0.006] recv (stream_id=15) server: nghttpd nghttp2/1.3.4
[  0.006] recv (stream_id=15) content-length: 23
[  0.006] recv (stream_id=15) cache-control: max-age=3600
[  0.006] recv (stream_id=15) date: Tue, 27 Oct 2015 08:49:56 GMT
[  0.006] recv (stream_id=15) last-modified: Tue, 27 Oct 2015 08:48:14 GMT
[  0.006] recv HEADERS frame <length=33, flags=0x04, stream_id=15>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.006] recv (stream_id=17) :status: 200
[  0.006] recv (stream_id=17) server: nghttpd nghttp2/1.3.4
[  0.006] recv (stream_id=17) content-length: 27
[  0.006] recv (stream_id=17) cache-control: max-age=3600
[  0.006] recv (stream_id=17) date: Tue, 27 Oct 2015 08:49:56 GMT
[  0.006] recv (stream_id=17) last-modified: Tue, 27 Oct 2015 08:48:06 GMT
[  0.006] recv HEADERS frame <length=33, flags=0x04, stream_id=17>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.006] recv DATA frame <length=23, flags=0x01, stream_id=15>
          ; END_STREAM
[  0.006] recv DATA frame <length=27, flags=0x01, stream_id=17>
          ; END_STREAM
[  0.006] recv (stream_id=19) :status: 200
[  0.006] recv (stream_id=19) server: nghttpd nghttp2/1.3.4
[  0.006] recv (stream_id=19) content-length: 370
[  0.006] recv (stream_id=19) cache-control: max-age=3600
[  0.006] recv (stream_id=19) date: Tue, 27 Oct 2015 08:49:56 GMT
[  0.006] recv (stream_id=19) last-modified: Tue, 27 Oct 2015 08:48:24 GMT
[  0.006] recv HEADERS frame <length=34, flags=0x04, stream_id=19>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.006] recv DATA frame <length=370, flags=0x01, stream_id=19>
          ; END_STREAM
[  0.006] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
***** Statistics *****

Request timing:
  responseEnd: the  time  when  last  byte of  response  was  received
               relative to connectEnd
 requestStart: the time  just before  first byte  of request  was sent
               relative  to connectEnd.   If  '*' is  shown, this  was
               pushed by server.
      process: responseEnd - requestStart
         code: HTTP status code
         size: number  of  bytes  received as  response  body  without
               inflation.
          URI: request URI

see http://www.w3.org/TR/resource-timing/#processing-model

sorted by 'complete'

id  responseEnd requestStart  process code size request path
 13      +818us       +186us    632us  200  823 /
 21     +2.00ms      +1.00ms   1.00ms  200   43 /main.js
 15     +2.06ms       +937us   1.12ms  200   23 /main.css
 17     +2.07ms       +963us   1.10ms  200   27 /jsinhead.js
 19     +2.10ms       +982us   1.12ms  200  370 /nginx-logo.png
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
<link href="./main.css" rel="stylesheet">
<script src="./jsinhead.js" type="text/javascript"></script>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<div><img src="./nginx-logo.png" alt="test"></div>
<script src="./main.js" type="text/javascript"></script>
</body>
</html>
console.log("js in head");
h1 {
color: red;
}
console.log("test");
console.log("test2");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment