Kévin Dunglas
Contributed by Kévin Dunglas in #21478

One of the most relevant new features proposed by HTTP/2 to improve the loading of web pages is called Server Push. HTTP/2 Push allows a web server to send resources to a web browser before the browser gets to request them.

In Symfony 3.3 we added HTTP/2 Push support for web assets (CSS, JS, images) to allow preloading them as explained in the Preload W3C Working Draft. In practice, and following the traditional Symfony philosophy of using composition, the new feature is enabled by wrapping your assets with the new preload() function:

1
2
3
4
5
6
7
8
9
10
11
12
13
<head>
    {# by default, assets are pushed #}
    <link rel="stylesheet" href="{{ preload(asset('/css/app.css')) }}">
    {# ... but you can disable pushing... #}
    <link rel="stylesheet" href="{{ preload(asset('/css/app.css'), { nopush: true }) }}">
    {# ... and you can also explicit the asset type #}
    <link rel="stylesheet" href="{{ preload(asset('/css/app.css'), { as: 'style' }) }}">
    ...
</head>
<body>
    ...
    <script src="{{ preload(asset('/js/app.js')) }}"></script>
</body>

Behind the scenes, the preload() function adds a Link HTTP header that is processed by intermediate proxies compatible with HTTP/2:

1
2
3
4
HTTP/1.1 200 OK
Content-Type: text/html
...
Link: </css/app.css>; rel=preload,</cjs/app.js>; rel=preload

An added bonus of using this technique is that all those assets are downloaded using just one connection, improving the page speed dramatically.

Published in #Living on the edge