Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit6beb4eb

Browse files
committed
Add docs for the WebLink component
1 parent795febe commit6beb4eb

File tree

7 files changed

+315
-0
lines changed

7 files changed

+315
-0
lines changed
356 KB
Loading
358 KB
Loading
55.5 KB
Loading
367 KB
Loading

‎components/weblink.rst‎

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
..index::
2+
single: WebLink
3+
single: Components; WebLink
4+
5+
The WebLink Component
6+
======================
7+
8+
The WebLink component provides tools to create `Web Links`_.
9+
It allows to easily leverage `HTTP/2 Server Push`_ as well as `Resource Hints`_.
10+
11+
..versionadded::3.3
12+
The WebLink component was introduced in Symfony 3.3.
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:
45+
46+
..code-block::terminal
47+
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 `Bootstrap`_, 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'
258+
259+
Last but not least, as all Symfony components, WebLink can be used as a
260+
standalone PHP library:
261+
262+
..code-block::php
263+
264+
<?php
265+
266+
require __DIR__.'/../vendor/autoload.php';
267+
268+
use Fig\Link\GenericLinkProvider;
269+
use Fig\Link\Link;
270+
use Symfony\Component\WebLink\HttpHeaderSerializer;
271+
272+
$linkProvider = (new GenericLinkProvider())
273+
->withLink(new Link('preload', '/bootstrap.min.css'));
274+
275+
header('Link: '.(new HttpHeaderSerializer())->serialize($linkProvider->getLinks()));
276+
277+
echo 'Hello';
278+
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+
282+
While we're speaking about interoperability, WebLink can deal with any link implementing
283+
`PSR-13`_.
284+
285+
Thanks to Symfony WebLink, there is no excuses to not to switch to HTTP/2!
286+
287+
.. _`Web Links`:https://tools.ietf.org/html/rfc5988
288+
.. _`HTTP/2 Server Push`:https://tools.ietf.org/html/rfc7540#section-8.2
289+
.. _`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/

‎index.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Topics
5454
testing
5555
translation
5656
validation
57+
weblink
5758
workflow
5859

5960
Best Practices

‎weblink.rst‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
WebLink
2+
=======
3+
4+
Symfony natively supports `Web Linking`_. It is especially useful to improve
5+
the performance of your application by leveraging the HTTP/2 protocol and
6+
preloading capabilities of modern web browsers.
7+
8+
Read the the:doc:`WebLink Component documentation</components/weblink>` to learn how
9+
to use these features.
10+
11+
.. _`Web Linking`_: https://tools.ietf.org/html/rfc5988

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp