Slide 1

Slide 1 text

@dunglas Webperf: PHP after Server Push 1

Slide 2

Slide 2 text

@dunglas Kévin Dunglas ❏ Co-founder of Les-Tilleuls.coop ❏ Creator of API Platform, Vulcain, Mercure... ❏ Symfony Core Team WebLink, Panther, Serializer, PropertyInfo, autowiring, PSR-7 Bridge… 2 @dunglas

Slide 3

Slide 3 text

@dunglas web, API and cloud experts ✊ Self-managed since 2011 ⬆ 50 people, Lille, Paris, Nantes, Lyon, ... 👷 ➡ [email protected] Les-Tilleuls.coop 3

Slide 4

Slide 4 text

@dunglas , powering the web since 1989 Hypertext Transfer Protocol, initiated by Tim Berners Lee at CERN… when I was 1 year old. 4

Slide 5

Slide 5 text

@dunglas HTTP/1.1 : back to the basics ❏ RFC 2068 (1997), replaced by RFC 7230 (2014) ❏ Client-server / Request-response ❏ Text protocol (ASCII) ❏ On top of TCP/IP ❏ Designed for performance at web-scale: cache 5

Slide 6

Slide 6 text

@dunglas 6 $ telnet les-tilleuls.coop 80 GET /en/jobs HTTP/1.1 Host: les-tilleuls.coop User-Agent: MyBrowser Accept: text/html HTTP/1.1 200 OK Content-Type: text/html …

Hi, AFUP folks!

Connection closed by foreign host.

Slide 7

Slide 7 text

@dunglas HTTP/2 : from text to binary ❏ RFC 7540 (2015) ❏ Goal: a faster web ❏ same semantic and high level features as HTTP/1 ❏ Improved performance: binary protocol, multiplexing ❏ Server Push 7

Slide 8

Slide 8 text

@dunglas HTTP/2: frames and streams 8 © Narayan Prustyq qnimate.com/what-is-multiplexing-in-http2/

Slide 9

Slide 9 text

@dunglas HTTP/2 global support: 97% of all internet users 9

Slide 10

Slide 10 text

@dunglas 10

Slide 11

Slide 11 text

@dunglas HTTP/3 : from TCP to QUIC ❏ 🧪 Still an Internet Draft (RFC in 2021?) ❏ Goal: a faster web ❏ Same features as HTTP/2 ❏ Improved performance: new transport using QUIC (built on top of UDP) instead of TCP ❏ Server Push 11

Slide 12

Slide 12 text

@dunglas HTTP/3 global support: 68% of all internet users 12

Slide 13

Slide 13 text

@dunglas 13

Slide 14

Slide 14 text

@dunglas 14

Slide 15

Slide 15 text

@dunglas HTTP/2, HTTP/3 and PHP 15

Slide 16

Slide 16 text

@dunglas HTTP/2, HTTP/3 and PHP 16 1. The web server manages the HTTP connection 2. The web server uses the (Fast)CGI protocol to call the PHP scripts 3. PHP sends a (Fast)CGI response, the web server converts it in an HTTP (1, 2 or 3) response ➡ keep this in mind: PHP doesn’t handle the HTTP (nor TCP/QUIC) connection directly

Slide 17

Slide 17 text

@dunglas 17 © Loginsoft

Slide 18

Slide 18 text

@dunglas 18 ✌ Good news: no changes needed to your PHP apps to support HTTP/2 & 3 ✌

Slide 19

Slide 19 text

@dunglas Caddy ❤ 19 { php_fastcgi unix//php-fpm.sock } ❏ Automatic HTTP/2 support, automatic TLS ❏ 💪 Server Push support ❏ Experimental HTTP/3 support (no server push support)

Slide 20

Slide 20 text

@dunglas NGINX 20 server { listen 443 ssl http2; # ssl_certificate config # fastcgi_pass config } ❏ 💪 Server Push support ❏ HTTP/3 support under development

Slide 21

Slide 21 text

@dunglas Apache 21 Listen 443 SSLEngine on # SSL config Protocols h2 http/1.1 ❏ 💪 Server Push support ❏ Currently no HTTP/3 support

Slide 22

Slide 22 text

@dunglas h2/3 and PHP: at edge Edge servers natively supporting HTTP/2 and h3: ❏ Fastly ❏ Akamai ❏ Cloudflare When using one of these services, your origin server doesn’t have to support HTTP/2 or h3. 22

Slide 23

Slide 23 text

@dunglas Server Push 23

Slide 24

Slide 24 text

@dunglas 24

Slide 25

Slide 25 text

@dunglas 25 © Simone Border slideshare.net/SimoneBordet/http2-and-java-current-status

Slide 26

Slide 26 text

@dunglas Server Push: internals ❏ Server Push is supported only with HTTP/2 and 3 ❏ The server sends to the client: ❏ A request 🤯, with headers, in a special frame: PUSH_PROMISE ❏ The response, in a new stream ❏ The client use the response if it matches a future request (headers are also checked) ❏ The client can refuse or cancel a push ❏ Push support is optional ❏ Supported by all major browsers (for now…) 26

Slide 27

Slide 27 text

@dunglas Server Push and web APIs 27

Slide 28

Slide 28 text

@dunglas 28 Vulcain: API resources preloading

Slide 29

Slide 29 text

@dunglas 29

Slide 30

Slide 30 text

@dunglas Server Push and PHP 30

Slide 31

Slide 31 text

@dunglas Reminder 31 © Loginsoft

Slide 32

Slide 32 text

@dunglas 32 😱 Bad news: as PHP doesn’t handle the HTTP connection, it cannot create PUSH_PROMISE frames directly 😱

Slide 33

Slide 33 text

@dunglas The Preload Spec ⚡ 33

Slide 34

Slide 34 text

@dunglas W3C Preload ❏ Keyword for the Link HTTP header to hint web servers to push resources to clients ❏ Supported by Caddy, NGINX, Apache, Cloudflare, Fastly, Akamai... 34

Slide 35

Slide 35 text

@dunglas 35 The web server and the proxy will (may) push the linked resource using HTTP/2 or HTTP/3 Link: ; rel=preload; as=style Link: ; rel=preload; as=script

Slide 36

Slide 36 text

@dunglas Drama time 😱 36

Slide 37

Slide 37 text

@dunglas 37

Slide 38

Slide 38 text

@dunglas Removing Server Push? Why? 38 Why removing the iconic feature of HTTP/2? ❏ Rarely used in the wild (0,05% of the HTTP/2 conns) ❏ Footgun/“Over pushing”: only 40% of pushed requests are used: ❏ Resource pushed but already in the local cache ❏ Pushed request doesn’t match the actual one ❏ Invalid pushes ❏ Complexity in Chrome’s code base

Slide 39

Slide 39 text

@dunglas Could we save Server Push? 39 ❏ The Internet Draft “Cache Digests for HTTP/2” (2019) proposes to fix the over-pushing problem ❏ It introduces a special frame using a Cuckoo-filter to allow the client to inform the server of its cache contents ❏ It’s unlikely to be implemented ❏ Similar solutions using cookies exist (ex: CASPer)

Slide 40

Slide 40 text

@dunglas What are the alternatives? 40

Slide 41

Slide 41 text

@dunglas Alternatives? 41 In the mail thread proposing the withdrawal of Server Push, the Google team mentions 3 alternatives: ❏ WebTransport ❏ Preload and Resource Hints ❏ The 103 Status Code

Slide 42

Slide 42 text

@dunglas WebTransport 42

Slide 43

Slide 43 text

@dunglas WebTransport 43 ❏ W3C Editor Draft introducing a new JavaScript API to send data between a browser and a server using HTTP/3 and QUIC ❏ Replacement for WebSockets (compatible with HTTP/3, and more powerful) ❏ It’s a low level network API ❏ It’s not really comparable with Server Push: low level, verbose, requires JavaScript code

Slide 44

Slide 44 text

@dunglas WebTransport Example async function receiveData(url, processTheData) { const wt = new WebTransport(url); for await (const readable of wt.incomingUnidirectionalStreams) { // consume streams individually, reporting per-stream errors (async () => { try { for await (const chunk of readable) { processTheData(chunk); } } catch (e) { console.error(e); } })(); } } 44

Slide 45

Slide 45 text

@dunglas The Preload Spec (continued) ⚡ 45

Slide 46

Slide 46 text

@dunglas Preload / Resource Hints ❏ Two specs: Resource Hints and Preload ❏ W3C Working Drafts, widely implemented ❏ Keywords for the Link HTTP header to hint clients about resources they should load ❏ Hints the browser to preconnect/prerender/prefetch a resource ❏ Also work with the HTML element 46 Link: ; rel=preload; as=style; nopush Link: ; rel=preload; as=script; nopush

Slide 47

Slide 47 text

@dunglas Preload ❏ Preload links can be handled directly by the client (without a push) ❏ Fix the over-pushing/cache problem ❏ Also work with the HTML element 47 Link: ; rel=preload; as=style; nopush Link: ; rel=preload; as=script; nopush

Slide 48

Slide 48 text

@dunglas Relation types ❏ preload: early, mandatory, high priority download ❏ prefetch: early, optional, low priority, download ❏ prerender: early, optional, low priority, rendering by the browser (example: next page) ❏ dns_prefetch: early DNS lookup ❏ preconnect: early DNS lookup, TCP handshake and (optional) TLS negotiation 48

Slide 49

Slide 49 text

@dunglas Preload vs Server Push Benefits ❏ Takes the local cache into account (no over pushing) ❏ Works with HTTP 1, 2 and 3 ❏ Already implemented by major browsers ❏ Supported by all servers (simple header) Disadvantage ❏ The browser must wait for all headers to be received before downloading the resource 49

Slide 50

Slide 50 text

@dunglas Preload global support: 92% of all internet users 50

Slide 51

Slide 51 text

@dunglas The Symfony WebLink Component Preload and Early Hints from any PHP app! 51

Slide 52

Slide 52 text

@dunglas Symfony WebLink Component ❏ Manages and serializes any HTTP Link headers ❏ Uses the PSR-13 (Link interface) ❏ Standalone PHP library ❏ But also integrated in Symfony Full Stack ❏ Implements W3C Preload and Resource Hints specs ❏ Provides a bunch of useful Twig helpers 52

Slide 53

Slide 53 text

@dunglas Install 53 composer req symfony/web-link Or with Flex: composer req web-link

Slide 54

Slide 54 text

@dunglas Standalone usage 54

Slide 55

Slide 55 text

@dunglas In a Symfony controller 55

Slide 56

Slide 56 text

@dunglas In Twig 56

Slide 57

Slide 57 text

@dunglas Resulting Header 57

Slide 58

Slide 58 text

@dunglas In the Browser 58 A push will be triggered by the web server if supported by the browser and if there is no nopush directive. Otherwise, fallback on preload Link.

Slide 59

Slide 59 text

@dunglas Other Built-in Twig Helpers ❏ link() ❏ preload() ❏ dns_prefetch() ❏ preconnect() ❏ prefetch() ❏ prerender() 59

Slide 60

Slide 60 text

@dunglas 103 Early Hints 🤩 60

Slide 61

Slide 61 text

@dunglas 103 Early Hints 61 ❏ Experimental spec (RFC 8297) introducing a new HTTP Status Code: 103 ❏ Informational response that contains headers that are likely to be included in the final response ❏ Can be sent before knowing the final status code and headers ❏ Designed to be used with Preload ❏ Designed from the ground up as an alternative to Server Push

Slide 62

Slide 62 text

@dunglas 103 Early Hints HTTP/1.1 103 Early Hints Link: ; rel=preload; as=style Link: ; rel=preload; as=script HTTP/1.1 200 OK ... Link: ; rel=preload; as=style Link: ; rel=preload; as=script ... 62

Slide 63

Slide 63 text

@dunglas 103 vs Server Push Benefits ❏ Takes the local cache into account (no over pushing) ❏ Works with HTTP 1, 2 and 3 ❏ Low latency, only 1 RTT ❏ Less complex to implement Disadvantage ❏ 1 more RTT (SP = 0 RTT) 63

Slide 64

Slide 64 text

@dunglas Chrome is implementing it 64

Slide 65

Slide 65 text

@dunglas Go is working on it (Vulcain/Caddy) 65 dunglas.fr/2021/02/using-the-103-early-hints-status-code-in-go-applications/

Slide 66

Slide 66 text

@dunglas Other implementations ❏ Already supported by Apache (configurable) ❏ Experimental module for NGINX (no signal regarding an official support) ❏ Not implemented by Firefox, but likely to happen ❏ Not implemented by Safari 66

Slide 67

Slide 67 text

@dunglas PHP is working on it 67

Slide 68

Slide 68 text

@dunglas 68 © Loginsoft But we have a problem

Slide 69

Slide 69 text

@dunglas PHP and the 103 status code Problem ❏ CGI/FastCGI doesn’t support sending multiple HTTP responses ❏ Putting the final response in the body of the CGI response doesn’t work with h2 and h3 (binary protocol) Possible solutions ❏ Replace FastCGI by a pure HTTP server (ex: AMPHP HTTP Server) ❏ Hack FastCGI (ex: using extension headers) ❏ Publish a new revision of the CGI RFC (unlikely) 69

Slide 70

Slide 70 text

@dunglas Upgrade Path 70

Slide 71

Slide 71 text

@dunglas Upgrade path: Chrome will not remove Server Push until 103 is rolling out 71

Slide 72

Slide 72 text

@dunglas Upgrade Path 72 ❏ Use “Preload” links ❏ Send a 103 response ❏ Configure the web server fallback on Server Push if browser doesn’t support Early Hints ❏ Measure to check that it works as expected ❏ Profit!

Slide 73

Slide 73 text

@dunglas The Future of Vulcain 73

Slide 74

Slide 74 text

@dunglas The Future of Vulcain 74 ❏ Vulcain-style APIs works equally well with Server Push and Early Hints ❏ The Vulcain spec supports Preload links and Early Hints since day 1 ❏ Vulcain APIs benefit from a better local cache ❏ The Vulcain Gateway Server support Preload links since day 1 ❏ The dev version for VGS supports Early Hints with HTTP/3 (h1 and h2 support in progress)

Slide 75

Slide 75 text

@dunglas 75

Slide 76

Slide 76 text

@dunglas Summary ❏ Server Push was promising and is widely available, but it has issues and Chrome is killing it ❏ Preload links are widely available, and better than nothing ❏ Early Hints are the new kids on the block, and there is an upgrade path from Server Push! Use HTTP/2 and HTTP/3 and Preload right now Vulcain is more relevant than ever, expect some exciting news soon! 76

Slide 77

Slide 77 text

@dunglas 77 Thanks! @dunglas @coopTilleuls