promise of push (http/2 web performance)

70
©2016 AKAMAI | FASTER FORWARD™ HTTP/2 Web Performance Promise of Push @ColinBendell Director, CTO Office

Upload: colin-bendell

Post on 19-Jan-2017

832 views

Category:

Software


4 download

TRANSCRIPT

Page 1: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 Web Performance

Promise of Push

@ColinBendellDirector, CTO Office

Page 2: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Desktop

90th50thBudget

Mobile

Page 3: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Improving Perf:

Blame the content

Page 4: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

WebPageTest

Looking for culprits

Page 5: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Time-To-First-Byte

25% of Perf. Budget is waiting

Many causes: User (Network, Device, CPU), App Server, etc

Page 6: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Introducing

Network Waste1.48s (full throughput)

87.6% WASTE

Page 7: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Network Waste

An opportunity to PUSH content

Move the experience

87.6% WASTE

Page 8: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Chapter 1: PUSH on the Web

Page 9: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Direct TCPPoll/Long PollPushletsSSE

Hasn't Push been solved?

Page 10: Promise of Push (HTTP/2 Web Performance)

How to PUSH

TCP/IP Socket (eg: XMPP)<stream:stream

to='example.com'xmlns='jabber:client'version='1.0'>

<stream:streamfrom='example.com'id='someid'xmlns='jabber:client'version='1.0'>

<message from='[email protected]'to='[email protected]'>

<body>Art thou not Romeo, and a Montague?</body>

</message> <message from='[email protected]'to='[email protected]'>

<body>Neither, fair saint, if either thee dislike.</body>

</message><message from='[email protected]'

to='[email protected]'><body>How camest thou hither,

tell me, and wherefore? </body></message>

Page 11: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

TCP/IP Socket (eg: XMPP)• Proprietary & efficient

• Any content could be sent

• But requires app logic to encode/decode

• Likely ports blocked by firewall rules

Page 12: Promise of Push (HTTP/2 Web Performance)

How to PUSH

Polling / Long PollingGET /messages HTTP/1.1Host: queue.example.comAuthorization: ...

HTTP/1.1 200 OKContent-Length: 100{ "from": "[email protected]","to": "[email protected]","message: "Do you bite your

thumb at us, sir?}

Page 13: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

Polling / Long Polling• Ports 80/443

• Polling is chatty; has battery impacts

• Custom protocol: requires app logic

• Connection timeouts

• Must manually handle disconnect & resume

Page 14: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

PushletGET /messages HTTP/1.1Host: queue.example.comAuthorization: ... HTTP/1.1 200 OK

Transfer-Encoding: ChunkedConnection: keep-aliveContent-Type: text/html<html><head/><body><h1>Messages</h1><p>From: [email protected]</p><p>To: [email protected]</p><p>I do bite my thumb, sir.</p>

<p>From: [email protected]</p><p>To: [email protected]</p><p>No, sir, I do not bite my thumb at you, sir, but I bite my thumb, sir.<p>

Page 15: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

Pushlet• No app logic required

• Continuously "loading" UX

• CPU/Network/Battery impacts?

• Text only

• Client must must detect connection loss

Page 16: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

Server-Side-EventsGET /messages HTTP/1.1Host: api.example.comAccept: text/event-streamAuthorization: ...Last-Event-ID: 41

HTTP/1.1 200 OKConnection: keep-aliveContent-Type: text/event-streamTransfer-Encoding: chunked

id: 42event: receiveMessagedata: { "from": "[email protected]","to": "[email protected]","message: "Do you bite your

thumb at us, sir?}id: 43event: stageActiondata: { "from": "[email protected]","to": "[email protected]","message: "Do you bite your

thumb at us, sir?}

Page 17: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

Server-Side-EventsHTTP/1.1 200 OKConnection: keep-aliveContent-Type: text/event-streamTransfer-Encoding: chunked

id: 42event: recieveMessagedata: { "from": "[email protected]",

"to": "[email protected]","message: "Do you bite your

thumb at us, sir?}id: 43event: stageActiondata: { "from": "[email protected]","to": "[email protected]","message: "Do you bite your

thumb at us, sir?}

<script type="text/javascript">

var evtSource = new EventSource("//api.example.com/messages", { withCredentials: true } );

evtSource.addEventListener("receiveMessage", function(e) {var newElement = document.createElement("p");

var obj = JSON.parse(e.data);newElement.innerHTML = "Message: " + obj.message;eventList.appendChild(newElement);

}, false);

</script>

Page 18: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

How to PUSH

Server-Side-Events• HTML5 browsers or Polyfill

• Standard APIs

• Text only messages

• Intermediates must support flushing

Page 19: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/1.1

State of Push• Build it yourself

• Requires app logic to be loaded

• (generally) Text only

• Messaging focused, not performance

Page 20: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

WebRTCWebSocketHTTP/2 Push(Do we need yet

another technology?)

Wait! What about:

Page 21: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Peer-to-Peer with

WebRTC• Peer to Peer• UDP (+FlowControl)• Web APIs• BYOA (bring your own app)• Usually: Audio/Video

Flexibility: HighRealTime: HighComplexity: High

Page 22: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

One-to-One with

WebSockets• One-to-One (User to Server)• Bidirectional socket• Web APIs• BYOA (bring your own app)• Can by binary or text• Not cacheable

Flexibility: MediumRealTime: HighComplexity: Medium-High

var ws = new WebSocket('wss://example.com/socket');

ws.onerror = function (error) { }ws.onclose = function () { }ws.onopen = function () { }

ws.onmessage = function(msg) {if(msg.data instanceof Blob) {processBlob(msg.data);

} else {processText(msg.data);

}}

Function sendMessage(msgText) {ws.send(msgText);

}

Page 23: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

One-to-Many with

HTTP/2 Push• Many-to-One (Users to Server)• H2 standard• Cacheable• Transparent to app

Flexibility: MediumRealTime: LowComplexity: Low

[ 0.270] recv (stream_id=13) :method: GET[ 0.270] recv (stream_id=13) :path: /demo/h2/push.css[ 0.271] recv (stream_id=13) accept: */*[ 0.271] recv PUSH_PROMISE frame <length=72, flags=0x04, stream_id=13>

; END_HEADERS(padlen=0, promised_stream_id=2)

Page 24: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

9 (8+)6+ (4.4)

Page 25: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Overview

HTTP/2 BasicsFix HTTP/1.1 Performance Other?├ Head of Line Blocking├ Parallelism├ Header compression└ Backward Compatible

├ Prioritization├ Flow Control└ Binary Protocol

└ Server Push

Page 26: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Chapter 2: PUSH_PROMISE

Page 27: Promise of Push (HTTP/2 Web Performance)

HTTP/2 PUSH_PROMISE

Frame BasicsPUSH_PROMISE:url: /push.cssuser-agent: chrome

RST_STREAM

DATA

promised-stream-id: 2

a:hover {color: blue}…

2

2

… or ...

13

Page 28: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2

Reading the Matrix$ nghttp https://www.colinbendell.com/demo/h2/pushtest.html -vv

[ 0.135] ConnectedThe negotiated protocol: h2[ 0.230] send SETTINGS frame <length=12, flags=0x00, stream_id=0>

(niv=2)[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100][SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]

[ 0.230] send PRIORITY frame <length=5, flags=0x00, stream_id=3>(dep_stream_id=0, weight=201, exclusive=0)

[ 0.230] send PRIORITY frame <length=5, flags=0x00, stream_id=5>(dep_stream_id=0, weight=101, exclusive=0)

[ 0.230] send PRIORITY frame <length=5, flags=0x00, stream_id=7>(dep_stream_id=0, weight=1, exclusive=0)

Frame Name Bytes

Odd = Client Initiated

Page 29: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

[ 0.230] send HEADERS frame <length=60, 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: /demo/h2/pushtest.html:scheme: https:authority: www.colinbendell.comaccept: */*accept-encoding: gzip, deflateuser-agent: nghttp2/1.6.0

Familiar HTTP Request

PseudoHeaders

Page 30: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

[ 0.267] recv SETTINGS frame <length=30, flags=0x00, stream_id=0>(niv=5)[SETTINGS_HEADER_TABLE_SIZE(0x01):4096][SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100][SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535][SETTINGS_MAX_FRAME_SIZE(0x05):16384][SETTINGS_MAX_HEADER_LIST_SIZE(0x06):16384]

[ 0.267] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>; ACK(niv=0)

[ 0.267] send SETTINGS frame <length=0, flags=0x01, stream_id=0>; ACK(niv=0)

Flow Control

Page 31: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2

PUSH_PROMISE[ 0.270] recv (stream_id=13) :method: GET[ 0.270] recv (stream_id=13) :path: /demo/h2/push.css[ 0.270] recv (stream_id=13) :authority: www.colinbendell.com[ 0.270] recv (stream_id=13) :scheme: https[ 0.270] recv (stream_id=13) host: www.colinbendell.com[ 0.271] recv (stream_id=13) accept: */*[ 0.271] recv (stream_id=13) user-agent: nghttp2/1.6.0[ 0.271] recv (stream_id=13) accept-encoding: gzip, deflate[ 0.271] recv PUSH_PROMISE frame <length=72, flags=0x04, stream_id=13>

; END_HEADERS(padlen=0, promised_stream_id=2)

Existing Stream

Even: Server Initiated

Page 32: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

[ 0.313] recv (stream_id=2, sensitive) :status: 200[ 0.313] recv (stream_id=2, sensitive) server: Apache[ 0.313] recv (stream_id=2, sensitive) etag: "e00af44aba37028e02014b6842fd3748:1461342896"[ 0.313] recv (stream_id=2, sensitive) last-modified: Fri, 22 Apr 2016 16:34:56 GMT[ 0.313] recv (stream_id=2, sensitive) accept-ranges: bytes[ 0.313] recv (stream_id=2, sensitive) content-length: 64[ 0.313] recv (stream_id=2, sensitive) content-type: text/css[ 0.313] recv (stream_id=2, sensitive) cache-control: max-age=3571[ 0.313] recv (stream_id=2, sensitive) expires: Sun, 24 Apr 2016 16:22:33 GMT[ 0.313] recv (stream_id=2, sensitive) date: Sun, 24 Apr 2016 15:23:02 GMT[ 0.313] recv HEADERS frame <length=469, flags=0x04, stream_id=2>

; END_HEADERS(padlen=0); First push response header

[ 0.313] recv (stream_id=2, length=64, srecv=64, crecv=621) DATALorem;ipsum[ 0.313] recv DATA frame <length=64, flags=0x00, stream_id=2>[ 0.313] recv DATA frame <length=0, flags=0x01, stream_id=2>

; END_STREAM

Delay, Push Response

Page 33: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2

PUSH_PROMISE$ nghttp https://www.colinbendell.com/demo/h2/pushtest.html -vv --no-push[ 0.123] ConnectedThe negotiated protocol: h2[ 0.518] 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]

Push Not Supported

[ 0.230] send RST_STREAM frame <length=5, flags=0x07, stream_id=4>

Push not accepted

Page 34: Promise of Push (HTTP/2 Web Performance)

chrome://net-internals

Page 35: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Invoking

Page 36: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 PUSH

How do I enable?

HTTP/1.1 200 OKContent-Type: text/htmlLink: /jquery.js; rel=preload; as=scriptLink: /global.css; rel=preload; as=style

1. Use the ` Link: <URL>; rel=preload; as=style` notation

Pros:• Easy to implement• H2O / nginX support

Cons:• Too-Late; Is TTFB• Status & headers committed• Interferes with Browser's Pre-Loader

Page 37: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 PUSH

How do I enable?public class MyServlet extends HttpServlet{public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException{String uri = request.getRequestURI();if ("/index.html".equals(uri)){String resourceToPush = "/js/jquery.js";RequestDispatcher dispatcher =

request.getRequestDispatcher(resourceToPush);dispatcher.push(request);

}}

}

2. Manually Instrument

Page 38: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 PUSH

How do I enable?2. Manually Instrument

Pros:• Before TTFB• Not impacted by page• Can extend to Next Page

Cons:• Another layer to maintain

Page 39: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Visualizing & Debug

Page 40: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Visualizing Results

Page 41: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Delayed Push with

Link=preload

Page 42: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Manual Instrument (Jetty)

Page 43: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Push headers are 'provisional'

Page 44: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Timeline not helpful (Chrome 50)

Page 45: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Canary (52) shows PUSH in Timeline

Page 46: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 (Chrome)

Adopted Push Stream

chrome://net-internals to find unclaimed pushes

Adopted pushes are logged (not a frame)

* PUSH is kept in memory for 5 minutes and then get deleted if unclaimed

Page 47: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Debugging PUSH• Terminal: nghttp

• Chrome: look for provisional header or use net-internals

• Firefox: enabling logging

• PUSHed content isn't added to cache until used in the page

Page 48: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Browser Behavior

Page 49: Promise of Push (HTTP/2 Web Performance)

Browser support

Testing PUSH

Page 50: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2

Connection Coalescing

Coalescing is ignored by Chrome/FF

Page 51: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 Chrome

Connection coalescing not availif (!HostPortPair::FromURL(gurl).Equals(host_port_pair())) {

if (proxy_delegate_ &&proxy_delegate_->IsTrustedSpdyProxy(

ProxyServer(ProxyServer::SCHEME_HTTPS, host_port_pair()))) {

if (gurl.SchemeIs("https")) {EnqueueResetStreamFrame(

stream_id, request_priority, RST_STREAM_REFUSED_STREAM,base::StringPrintf("Rejected push of cross origin HTTPS

content %d ""from trusted proxy",associated_stream_id));

return false;}

Only Host + Port considered! Boo!

Page 52: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Browser Support

Implementation notes• PUSHed content from different hosts are

rejected instead of coalescing

• Only used PUSHes hit cache

• FF uses init flow control of 64kb

Page 53: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Chapter 3: PUSH opportunity

Page 54: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

www.rakuten.co.uk

TTFB: Network Waste

TTFB: 330ms

95.9% Waste

Page 55: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

www.rakuten.co.uk

Time-to-First-Resource

TTFR: 762ms

91.1% Waste

Page 56: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

www.rakuten.co.uk

33.7% Perf Waste1.48s (full throughput)

87.6% WASTE Vis. Complete: 4.38s

Page 57: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

www.forever21.com

WPT: Network Waste81.7%

0.6s (full throughput)

Page 58: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Browser Support

Implementation notes• Measures opportunity to use the network

ahead of DOM/Browser load

• Indicator metric – NOT silver bullet

• Examines WPT results

• Tool to be released later this month

Page 59: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Chapter 4: Results

Page 60: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH Results

Insurance SiteOriginal CSS/JSOriginal

Everything Images

Page 61: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH Results

Cosmetics Site

Original

CSS/JS Everything

Images

Page 62: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Automatic PUSH_PROMISE

But when you get it Right:

5.27s 8.59s

Page 63: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH Results

Conclusions• Bad: too much, slows DOM complete

• Bad: too much can compete with preloader

• Bad: Wrong order congests network

• Good: Critical CSS & JS (& some images)

• Awesome: Network + Resource Timing

Page 64: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH Results

Implementation questions• Impact on Set-Cookie session tracking?

• REsponsive ServerSide?

• Client Hints?

Page 65: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Chapter 5: Epilogue

Page 66: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

HTTP/2 PUSH_PROMISE

Programmatic accept<?php$transfers = 1;$callback = function() use (&$transfers) {

$transfers++;return CURL_PUSH_OK;

};$mh = curl_multi_init();curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, $callback);$ch = curl_init();curl_setopt($ch, CURLOPT_VERBOSE, 1);curl_setopt($ch, CURLOPT_URL, 'https://localhost:8443/index.html');

Page 67: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH

What's Next:• Browser & OS Support

• Automated PUSH using analytics

• Next page resources

• Host coalescing

Page 68: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH

What about?• Javascript / CSS / Image early processing? • 3rd Party Content & Link=PreConnect ?

• PUSH to surrogate but not client?

• Delay & FlowControl: PUSH + Priorities• Cache Management / Invalidation

Page 69: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

PUSH

10? 10?7??

Page 70: Promise of Push (HTTP/2 Web Performance)

©2016 AKAMAI | FASTER FORWARD™

Thanks!@ColinBendell