HTTP/2 Prioritization
Patrick Meenan
@PatMeenan
slideshare.net/patrickmeenan
The Browser
Basic Parser Rules
•Process 1 token at a time
•Stylesheets Block Render
•Non-Async Script tags block Parser/DOM until:
•Pending Stylesheets have loaded
•Script has loaded
Late-Discovered Resources
• Fonts
• Background Images
• Script-injected content
• @import
(Simplified) Example
•1 HTML
•1 Stylesheet
•4 Scripts (2 blocking in the head)
•1 Web Font
•13 Images (5 visible)
Optimal Script Loading
Optimal Loading
Start Render
Visually Complete
Worst-Case
Start Render
Visually Complete
HTTP/1.x Prioritization
• 6 Connections per origin
• Pick next-highest for each origin as a connection becomes available
HTTP/2 Prioritization
•All requests sent to server immediately
•Priorities specified in dependency tree
•Any “stream” can depend on another stream
•Peers can be weighted
•Priority changes communicated with a PRIORITY
frame
https://developers.google.com/web/fundamentals/performance/http2/
Browser Differences
Chrome – Linear List
https://github.com/quicwg/wg-materials/raw/master/interim-19-05/priorities.pdf
Firefox - Groups
https://github.com/quicwg/wg-materials/raw/master/interim-19-05/priorities.pdf
Safari - Weighted
https://github.com/quicwg/wg-materials/raw/master/interim-19-05/priorities.pdf
Edge (classic)
¯_(ツ)_/¯
Prioritizing across
connections
Cross-connection prioritization
•3rd-parties
•Domain sharding
•www.example.com
•static1.example.com
•static2.example.com
Prioritizing across connections
HTTP/2 Connection coalescing
•New domain resolution includes IP of active connection
•Active connection cert includes new domain
•Still pay DNS lookup cost
• ORIGIN frame/CERTIFICATE frame
•Multi-CDN
External Fonts (before)
Same-origin fonts (wtf)
Start Render
Same-origin fonts (correct)
Start Render
https://twitter.com/zachleat/status/1055219667894259712
Testing for prioritization
https://www.webpagetest.org/http2priorities.html?image=
<url-encoded-image-URL>
Warm-up Connection
Request 30
below-the-fold
Images
(low priority)
Delay until 2 images complete
Sequentially Request 2
in-viewport images
(high priority)
Interrupts in-flight responses
Ideal response time would
match single-image download
When it goes wrong
Queued behind in-flight
Low-priority requests
Round Robin?
¯_(ツ)_/¯
ishttp2fastyet.com
ishttp2fastyet.com
NO – 9 of 25 pass
The Good ✅
• Akamai
• CDNsun
• Cloudflare
• Fastly
The Bad ❌
• Amazon Cloudfront
• Cachefly
• CDNetworks
• ChinaCache
• Edgecast
• Highwinds
• Incapsula
• Instart Logic
• KeyCDN
• LeaseWeb CDN
• Level 3
• Limelight
• Medianova
• Netlify
• Rocket CDN
• StackPath/NetDNA/MaxCDN
• Jetpack CDN
• Yottaa
• Zenedge
The Ugly (cloud load balancers) ❌
• Amazon AWS
• Google Cloud
• Microsoft Azure
Testing/Throttling
https://calendar.perfplanet.com/2016/testing-with-realistic-networking-conditions/
HTTP Header
Performance Monitoring
• Understand what (if any) traffic-shaping is
used
• Watch out for (avoid):
•Dev Tools
•Lighthouse
•Puppeteer
•Proxy
WHY it Goes Wrong
Edge
• CDN
• HTTP Load Balancer
(HA Proxy, Netscaler, etc)
HTTP/2 Broken
(and fixed) Here
TCP Send Buffers
Over-buffering (TCP)
• Impact on reprioritization
• Server metrics (send time artificially low)
TCP_NOTSENT_LOWAT
• Specify additional buffer above BDP
• Signals socket available only when send buffer drops
below threshold
Buffer Bloat
Loss-based congestion control
BBR starvation
https://blog.apnic.net/2017/05/09/bbr-new-kid-tcp-block/
Upstream Buffers
TLSTCP HTTP/2
HTTP TCP
HTTP TCP
fd
Upstream Limits
• 100+ simultaneous inbound requests
• Back-end request limits?
Server HTTP/2 implementations
• H2o, Apache good
• Nginx – not so much
• https://trac.nginx.org/nginx/ticket/1763
What to do?
• Use a “good” CDN
• Or…
What to do?
• Set reasonable default TCP send buffer sizes
• Enable TCP_NOTSENT_LOWAT
• Enable BBR
• Use a Web Server with good prioritization support
Linux
net.core.wmem_max = 250000000
net.ipv4.tcp_wmem = 10240 102400 250000000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_notsent_lowat = 16384
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Server-initiated prioritization
HTTP/3 (and QUIC)
• UDP-based (port 443)
• Moves TCP logic into application layer
• Less OS-level failure modes
• More application responsibility
• Moves loss recovery from per-connection to per-stream
• Will NEVER reach 100% availability
• Treat it as a progressive enhancement
HTTP/3 Prioritization?
• Originally replicating HTTP/2 tree
• Moving to HTTP header-based
• Priority Level + concurrency
• Server override (response header)
• Join the discussion
• https://httpwg.org/
Thank You
Patrick Meenan
@PatMeenan
slideshare.net/patrickmeenan
https://www.facebook.com/careers/

HTTP/2 Prioritization