@@ -11,259 +11,21 @@ The WebLink Component
11
11
.. versionadded :: 3.3
12
12
The WebLink component was introduced in Symfony 3.3.
13
13
14
- By implementing cutting edge web standards, namely `HTTP/2 Server Push `_ and
15
- W3C's `Resource Hints `_, the WebLink component
16
- brings great opportunities to boost webapp's performance.
17
-
18
- Thanks to WebLink, HTTP/2 (**h2 **) servers are able to push resources to clients
19
- before they even know that they need them (think to CSS or JavaScript
20
- files, or relations of an API resource). WebLink also enables other very
21
- efficient optimisations that work with HTTP 1:
22
-
23
- - telling the browser to fetch or to render another webpage in the
24
- background ;
25
- - init early DNS lookups, TCP handshakes or TLS negotiations
26
-
27
- Let's discover how easy it is to use it and the real life benefits you
28
- can expect.
29
-
30
- To benefit from HTTP/2 Server Pushes, a HTTP/2 server and a HTTPS connection
31
- are mandatory (even in local).
32
- Both Apache, Nginx and Caddy support these protocols.
33
- Be sure they are properly configured before reading.
34
-
35
- Alternatively, you can use the `Docker installer and runtime for
36
- Symfony `_ provided by Kévin Dunglas (community supported).
37
-
38
- It includes everything you need to run Symfony
39
- (PHP :doc: `configured properly for Symfony </performance >`, and Composer)
40
- as well as a development reverse proxy (Apache) supporting HTTP/2 Server Push
41
- and HTTPS (most clients only support HTTP/2 over TLS).
42
-
43
- Unzip the downloaded archive, open a shell in the resulting directory and run
44
- the following command:
14
+ Installation
15
+ ------------
45
16
46
17
.. code-block :: terminal
47
18
48
- # Install Symfony and start the project
49
- $ docker-compose up
50
-
51
- Open ``https://localhost``, if this nice page appears, you
52
- successfully created your first Symfony 4 project and are browsing it in
53
- HTTP/2!
54
-
55
- .. image :: /_images/components/weblink/symfony4-http2.png
56
-
57
- Let's create a very simple homepage using
58
- the `Twig`_ templating engine.
59
-
60
- The first step is to install the library itself:
61
-
62
- .. code-block :: terminal
63
-
64
- composer req twig
65
-
66
- Symfony is smart enough to download Twig, to automatically register it,
67
- and to enable Symfony features requiring the library.
68
- It also generates a base HTML5 layout in the ``templates/`` directory.
69
-
70
- Now, download `Boostrap `_, extract the archive and copy the file
71
- ``dist/css/bootstrap.min.css `` in the ``public/`` directory of our
72
- project.
73
-
74
- Symfony comes with a `nice integration with of the most popular CSS framework`_.
75
-
76
- .. note::
77
-
78
- In a real project, you should use Yarn or NPM with
79
- :doc:`Symfony Encore </frontend/encore/bootstrap>`_
80
- to install Bootstrap.
81
-
82
- Now, it's time to create the template of our homepage:
83
-
84
- .. code-block:: html
85
-
86
- <!DOCTYPE html>
87
- <html>
88
- <head>
89
- <meta charset="UTF-8">
90
- <title>Welcome!</title>
91
- <link rel="stylesheet" href="/bootstrap.min.css">
92
- </head>
93
- <body>
94
- <main role="main" class="container">
95
- <h1>Hello World</h1>
96
- <p class="lead">That's a lot of highly dynamic content, right?</p>
97
- </main>
98
- </body>
99
- </html>
100
-
101
- And finally, register our new template as the homepage using the builtin
102
- :doc:`TemplateController </templating/render_without_controller>`_:
103
-
104
- .. code-block:: yaml
105
-
106
- # config/routes.yaml
107
- index:
108
- path: /
109
- defaults:
110
- _controller: 'Symfony\Bundle\FrameworkBundle\Controller\TemplateController::templateAction'
111
- template: 'homepage.html.twig'
112
-
113
- Refresh your browser, this nice homepage should appear:
114
-
115
- .. image:: /_images/components/weblink/homepage-requests.png
116
-
117
- HTTP requests are issued by the browser, one for the homepage, and
118
- another one for Bootstrap. But we know from the very beginning that the
119
- browser **will** need Bootstrap. Instead of waiting that the browser
120
- downloads the homepage, parses the HTML (notice "Initiator: Parser" in
121
- Chrome DevTools), encounters the reference to ``bootstrap.min.css `` and
122
- finally sends a new HTTP request, we could take benefit of the HTTP/2
123
- Push feature to directly send both resources to the browser.
124
-
125
- Let's do it! Install the WebLink component:
126
-
127
- .. code-block :: terminal
128
-
129
- composer req weblink
130
-
131
- As for Twig, Symfony will automatically download and register this component into our app.
132
- Now, update the template to use the ``preload`` Twig helper that
133
- leverages the WebLink component:
134
-
135
- .. code:: html+twig
136
-
137
- {# ... #}
138
- <link rel="stylesheet" href="{{ preload('/bootstrap.min.css') }}">
139
- {# ... #}
140
-
141
- Reload the page:
142
-
143
- .. image:: /_images/components/weblink/http2-server-push.png
144
-
145
- As you can see (Initiator: Push), both
146
- responses have been sent directly by the server.
147
- ``bootstrap.min.css `` has started to be received before the browser even requested it!
148
-
149
- .. note ::
150
-
151
- Google Chrome provides a nice interface to debug HTTP/2 connections.
152
- Open ``chrome://net-internals/#http2 `` to start the tool.
153
-
154
- How does it works?
155
- ~~~~~~~~~~~~~~~~~~
156
-
157
- The WebLink component tracks Link HTTP headers to add to the response.
158
- When using the ``preload() `` helper, a ``Link `` header
159
- with a `preload `_
160
- ``rel`` attribute is added to the response:
161
-
162
- .. image:: /_images/components/weblink/response-headers.png
163
-
164
- According to `the Preload specification`_,
165
- when a HTTP/2 server detects that the original (HTTP 1) response
166
- contains this HTTP header, it will automatically trigger a push for the
167
- related file in the same HTTP/2 connection.
168
- The Apache server provided in the Docker setup supports this feature.
169
- It's why Bootstrap is pushed
170
- to the client!
171
-
172
- Popular proxy services and CDN including
173
- `Cloudflare`_, `Fastly`_ and `Akamai`_ also leverage this feature.
174
- It means that you can push resources to
175
- clients and improve performance of your apps in production right now!
176
- All you need is Symfony 3.3+ and a compatible web server or CDN service.
177
-
178
- If you want to prevent the push but let the browser preload the resource by
179
- issuing an early separate HTTP request, use the ``nopush `` attribute:
180
-
181
- .. code-block :: html+twig
182
-
183
- {# ... #}
184
- <link rel="stylesheet" href="{{ preload('/bootstrap.min.css', {nopush: true}) }}">
185
- {# ... #}
186
-
187
- Before using HTTP/2 Push, be sure to read `this great article `_ about
188
- known issues, cache implications and the state of the support in popular
189
- browsers.
190
-
191
- In addition to HTTP/2 Push and preloading, the WebLink component also
192
- provide some helpers to send `Resource
193
- Hints <https://www.w3.org/TR/resource-hints/#resource-hints> `__ to
194
- clients, the following helpers are available:
195
-
196
- - ``dns_prefetch ``: "indicate an origin that will be used to fetch
197
- required resources, and that the user agent should resolve as early
198
- as possible"
199
- - ``preconnect ``: "indicate an origin that will be used to fetch
200
- required resources. Initiating an early connection, which includes
201
- the DNS lookup, TCP handshake, and optional TLS negotiation, allows
202
- the user agent to mask the high latency costs of establishing a
203
- connection"
204
- - ``prefetch ``: "identify a resource that might be required by the next
205
- navigation, and that the user agent *should* fetch, such that the
206
- user agent can deliver a faster response once the resource is
207
- requested in the future"
208
- - ``prerender ``: "identify a resource that might be required by the
209
- next navigation, and that the user agent *should* fetch and
210
- execute, such that the user agent can deliver a faster response once
211
- the resource is requested in the future"
212
-
213
- The component can also be used to send HTTP link not related to
214
- performance. For instance, any `link defined in the HTML specification `_:
215
-
216
- .. code :: html+twig
217
-
218
- {# ... #}
219
- <link rel="alternate" href="{{ link('/index.jsonld', 'alternate') }}">
220
- <link rel="stylesheet" href="{{ preload('/bootstrap.min.css', {nopush: true}) }}">
221
- {# ... #}
222
-
223
- The previous snippet will result in this HTTP header being sent to the
224
- client:
225
- ``Link: </index.jsonld>; rel="alternate",</bootstrap.min.css>; rel="preload"; nopush ``
226
-
227
- You can also add links to the HTTP response directly from a controller
228
- or any service:
229
-
230
- .. code :: php
231
-
232
- // src/Controller/BlogPostAction.php
233
- namespace App\Controller;
234
-
235
- use Fig\Link\GenericLinkProvider;
236
- use Fig\Link\Link;
237
- use Symfony\Component\HttpFoundation\Request;
238
- use Symfony\Component\HttpFoundation\Response;
239
-
240
- final class BlogPostAction
241
- {
242
- public function __invoke(Request $request): Response
243
- {
244
- $linkProvider = $request->attributes->get('_links', new GenericLinkProvider());
245
- $request->attributes->set('_links', $linkProvider->withLink(new Link('preload', '/bootstrap.min.css')));
246
-
247
- return new Response('Hello');
248
- }
249
- }
250
-
251
- .. code-block :: yaml
252
-
253
- # app/config/routes.yaml
254
- blog_post :
255
- path : /post
256
- defaults :
257
- _controller : ' App\Controller\BlogPostAction'
19
+ $ composer require symfony/weblink
258
20
259
- Last but not least, as all Symfony components, WebLink can be used as a
260
- standalone PHP library:
21
+ Alternatively, you can clone the `<https://github.com/symfony/weblink >`_ repository.
261
22
262
- .. code-block :: php
23
+ .. include :: /components/require_autoload.rst.inc
263
24
264
- <?php
25
+ Usage
26
+ -----
265
27
266
- require __DIR__.'/../vendor/autoload.php';
28
+ Basic usage::
267
29
268
30
use Fig\Link\GenericLinkProvider;
269
31
use Fig\Link\Link;
@@ -276,28 +38,12 @@ standalone PHP library:
276
38
277
39
echo 'Hello';
278
40
279
- To see how WebLink is used in the wild, take a look to the `Bolt `_
280
- and `Sulu `_ CMS, they both use WebLink to trigger HTTP/2 pushes.
281
41
282
- While we're speaking about interoperability, WebLink can deal with any link implementing
283
- `PSR-13 `_.
42
+ .. seealso ::
284
43
285
- Thanks to Symfony WebLink, there is no excuses to not to switch to HTTP/2!
44
+ Read the :doc: `WebLink documentation </weblink >`_ to learn how
45
+ to use the features implemented by this component.
286
46
287
47
.. _`Web Links`: https://tools.ietf.org/html/rfc5988
288
48
.. _`HTTP/2 Server Push` : https://tools.ietf.org/html/rfc7540#section-8.2
289
49
.. _`Resource Hints` : https://www.w3.org/TR/resource-hints/
290
- .. _`Twig` : https://twig.symfony.com/
291
- .. _`Docker installer and runtime for Symfony` : https://github.com/dunglas/symfony-docker
292
- .. _`Bootstrap` : https://getbootstrap.com/
293
- .. _`nice integration with of the most popular CSS framework` : https://symfony.com/blog/new-in-symfony-3-4-bootstrap-4-form-theme
294
- .. _`preload` : https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
295
- .. _`the Preload specification` : https://www.w3.org/TR/preload/#server-push-(http/2)
296
- .. _`Cloudflare` : https://blog.cloudflare.com/announcing-support-for-http-2-server-push-2/
297
- .. _`Fastly` : https://docs.fastly.com/guides/performance-tuning/http2-server-push
298
- .. _`Akamai` : https://blogs.akamai.com/2017/03/http2-server-push-the-what-how-and-why.html
299
- .. _`this great article` : https://www.shimmercat.com/en/blog/articles/whats-push/
300
- .. _`link defined in the HTML specification` : https://html.spec.whatwg.org/dev/links.html#linkTypes
301
- .. _`Bolt` : https://bolt.cm/
302
- .. _`Sulu` : https://sulu.io/
303
- .. _`PSR-13` : http://www.php-fig.org/psr/psr-13/
0 commit comments