92716e2cc01580404ce5757bd45f95af7b15c2f9 1.jpg

Symfony at full speed with ESI

Guillem

3 reading minutes

Since we started creating our own components and packages (bundles in Symfony) to incorporate content management tools in our developments, one of our obsessions has been performance.

The loading speed of a website is essential for providing a good user experience and keeping their attention. If a page takes too long to load, the user is likely to become frustrated and end up abandoning it. In addition, loading speed is also important for search engine positioning, since Google and other search engines reward pages that load faster.

But we also want increasingly complete and complex experiences, more content on our pages, more functionality. Mixing both things involves optimizing the code, compressing images, reducing the amount of external resources used, among other techniques.

Aside from optimizing code, images, reducing resources, and other techniques, there are many software tools for caching pages. When you visit a web page, the browser downloads all the resources needed to display that page, such as images, styles, scripts, etc. Each time you visit that page again, the browser has to download all the content again, which can be very slow.

A cache is a temporary memory stored by your browser or server that allows you to save a copy of the page or some elements of the page on your computer or mobile device. This way, when you visit that page again, your browser can load the page much faster because it already has a copy stored in the cache.

The same dilemma always arises when it comes to caching: what happens when everything on a page is cacheable except for a small piece? The HTML standard incorporates a technology, ESI, which comes from Edge Side Includes, and which is used for exactly this. ESI is a language for including fragments of web pages in other web pages. It is like an HTML include statement that works through HTTP.

On most websites, a lot of content is shared between pages. Regenerating this content for every page view is wasteful, and ESI tries to address this by allowing you to decide the caching policy for each fragment individually.

In Symfony we have "HTTP Cache ESI" (included in Symfony 2.2 or later), which allows you to cache specific parts of your web pages to make them load faster.

The HTTP Cache ESI works by creating "fragments" that can be cached independently of the rest of the page. Then, when the page is requested, the fragments are assembled to display the full page.

It's not that we're reinventing the wheel, 10 years ago the people at Basecamp were already talking about Russian doll caching,   https://signalvnoise.com/posts/3690-the-performance-impact-of-russian-doll-caching   because of the idea of caching in incremental parts. From a list you cache up to the list element, then the list, then the component that shows the list, then the block on the page, then the page. It may seem counterproductive because of the amount of things you are caching and because, in case you have to change an element of the list, you have to invalidate all those things that we had been saving, but then to regenerate them, in the case of the list, since the rest of the elements will remain the same, it is actually done very quickly.

How to implement it in Symfony?

But how does all this work? Well, first of all, you need to create the fragments you want to cache. This is done using the command   render_esi(controller)   in your Twig template, where controller will be the controller that returns that separate fragment you want to be able to cache. Next, you need to configure the cache to use ESI. This is done by including the directive   that's it   to your cache settings:

If you use Varnish it is done with the line   set beresp.do_esi = true;   to your Varnish configuration file.

If you use Symfony cache it is done by including the line   esi: true   to the cache configuration file.

In both cases you need to make sure that your snippets have the appropriate headers. In particular, you need to include the headers   Cache-Control   and   Surrogate-Control.

Once you've done this, Symfony will take care of caching the fragments and assembling them when the full page is requested. And that's it! Your website will now be faster and more efficient thanks to Symfony's HTTP Cache ESI.


📫
Here’s today’s article. Feel free to reach out to us on social media as always, or at hola@softspring.es with any questions or suggestions!

Let’s work together!

Do you want to tell us your idea?

CONTACT US