In termini di performance uno dei vantaggi introdotti dal protocollo HTTP/2 è la possibilità di effettuare il pushing di risorse prima che sia il client a richiederlo. Questa funzione, dal nome HTTP/2 Server Push, viene largamente utilizzata per accelerare il processo di download delle risorse critiche.
Nginx introduce questa funzionalità con la versione 1.13.9 rilasciata il 20 Febbraio 2018. Gli utenti Nginx Plus, invece, dovranno attendere la release R15 programmata per Aprile 2018. Vediamo adesso come effettuare pushing di risorse usando Nginx ed HTTP/2.
Con la nuova versione di Nginx è stata introdotta la direttiva http2_push. Di seguito un semplice esempio di utilizzo:
server { # HTTP/2 puo' essere usato solo in condizioni di connessione sicura listen 443 ssl http2; server_name example.com; ssl_certificate /etc/ssl/certs/certificate.pem; ssl_certificate_key /etc/ssl/private/key.pem; root /var/www/sito_web; location = /demo.html { http2_push /style.css; http2_push /image1.jpg; http2_push /image2.jpg; } }
Grazie a questa direttiva è possibile effettuare il pushing delle risorse desiderate. Nell’esempio precedente, al momento in cui viene richiesta la risorsa http://example.com/demo.html
, il web server inizia ad effettuare il pushing delle risorse style.css
, image1.jpg
, image2.jpg
.
Per verificarne il corretto funzionamento basta aprire la DevTools di Google Chrome, posizionarsi sul tab Network e verificare il contenuto della colonna Initiator.
Naturalmente elencare manualmente le risorse in alcuni contesti è operazione quasi impossibile, motivo per cui il team di sviluppatori Nginx ha introdotto una seconda direttiva dal nome http2_push_preload.
Questa direttiva ha il compito di intercettare le risorse per le quali si desidera accelerare il download con la tecnica del preloading ed inviarle al client utilizzando HTTP/2 Server Push. Anche in questo caso l’implementazione è molto banale ed estremamente consigliata:
server { listen 443 ssl http2; ssl_certificate ssl/certificate.pem; ssl_certificate_key ssl/key.pem; root /var/www/html; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; http2_push_preload on; } }
Parlare di performance senza i dovuti test prima/dopo è come parlare di niente. In questo caso prendiamo come esame il test condotto direttamente dal team Nginx il quale ha realizzato una pagina, demo.html
, contenente un foglio di stile, style.css
, contenente a sua volta un riferimento a due immagini, image1.jpg
e image2.jpg
.
In particolare sono state testate le seguenti configurazioni:
Di seguito il grafico risultante dal test dal quale è possibile misurare il numero di round trip (richieste) necessari per il completo caricamento della pagina demo.html
richiesta tramite HTTP, HTTPS e HTTP/2.
Naturalmente le connessioni in HTTP/2 ed HTTPS richiedono dei round trip in più rispetto ad HTTP per questioni legate alle negoziazione TLS.
È possibile notare come grazie al Server Push di HTTP/2 siano stati risparmiati da 1 a 2 round trip, velocizzando di parecchio il tempo di caricamento della pagina se si pensa che si tratta di una pagina con un solo CSS e due immagini.
Questo è stato possibile in quanto il download delle risorse è partito al momento stesso della richiesta della pagina HTML. Naturalmente ogni sito è un mondo a sé ed i benchmark possono variare di moltissimo a seconda del contesto.
Google ha pertanto rilasciato un documento dal titolo Rules of Thumb for HTTP/2 Push con riportate delle regole da utilizzare quando si desidera implementare tale funzionalità in server in produzione.