Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 178821e

Browse filesBrowse files
committed
refactor
1 parent 9f4ae9b commit 178821e
Copy full SHA for 178821e

File tree

2 files changed

+285
-268
lines changed
Filter options

2 files changed

+285
-268
lines changed

‎components/weblink.rst

Copy file name to clipboardExpand all lines: components/weblink.rst
+11-265Lines changed: 11 additions & 265 deletions
Original file line numberDiff line numberDiff line change
@@ -11,259 +11,21 @@ The WebLink Component
1111
.. versionadded:: 3.3
1212
The WebLink component was introduced in Symfony 3.3.
1313

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+
------------
4516

4617
.. code-block:: terminal
4718
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
25820
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.
26122

262-
.. code-block:: php
23+
.. include:: /components/require_autoload.rst.inc
26324

264-
<?php
25+
Usage
26+
-----
26527

266-
require __DIR__.'/../vendor/autoload.php';
28+
Basic usage::
26729

26830
use Fig\Link\GenericLinkProvider;
26931
use Fig\Link\Link;
@@ -276,28 +38,12 @@ standalone PHP library:
27638

27739
echo 'Hello';
27840

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.
28141

282-
While we're speaking about interoperability, WebLink can deal with any link implementing
283-
`PSR-13`_.
42+
.. seealso::
28443

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.
28646

28747
.. _`Web Links`: https://tools.ietf.org/html/rfc5988
28848
.. _`HTTP/2 Server Push`: https://tools.ietf.org/html/rfc7540#section-8.2
28949
.. _`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

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.