Edge Side Includes
Tags: edge, webdev, performance
Published: 2023-09-25 14:16:38

A popular use case for edge computing among web and full stack developers is the injection of dynamic content into static assets and pages.

This technique increases the performance of our applications by allowing us to cache more of our content at the edge or at the Content Delivery Network (CDN), and by reducing the amount of data that needs to be requested and sent to our users from the origin server.

I recently saw a demo of code that leveraged Edge Side Includes (ESI) to inject dynamic content into static pages as the response was streamed back to the user, and it made me interested in how it works and if I might want to consider using it in my applications.

## What is ESI?

ESI is XML markup that's embedded in the HTML itself. It takes the following format:

`<esi:include src="<url-to-request>" />`

As an example, let's say that you have an e-commerce site that has a homepage that is static, unchanging content except for the shopping cart, which differs for each user.

You would use ESI to make a request for the shopping cart content by doing the following:

As an example, let's say that you have an e-commerce site that has a homepage that is static, unchanging content except for the shopping cart, which differs for each user.

You would use ESI to make a request for the shopping cart content by doing the following:

```html
<html>
  <head>
      <title>My Ecommerce Site</title>
  </head>
  <body>
    <div id="content">
      <div id="header">
        <img src="/images/logo.jpg" />
        **<esi:include src="/shopping_cart" />** 
      </div>
      <div id="items">
        <span id="item_1">...</span>
        <span id="item_2">...</span>
        ...
        <span id="item_n">...</span>
      </div>
    </div>
  </body>
</html>
```
*Source for code: [Fastly](https://www.fastly.com/blog/using-esi-part-1-simple-edge-side-include)*

When the response is returned to the user, rather than see the ESI tag in the HTML, it would be the shopping cart content.

## Why is this useful?
ESI allows for the 'mixing and matching' of static and dynamic content at an edge server or CDN.

This is useful because HTML pages mostly contain static content on their pages with a small amount of dynamic elements. At the time that ESI was introduced in 2001, any time dynamic content existed the whole page would have been uncachable and would have had to have been served from the origin server.

By caching the static elements and only requesting the dynamic ones, we'd have the ability to cache the majority of the page and have faster performance on the request for the dynamic elements since they make up a much smaller subset of the page.

## Where is ESI at today?
ESI was originally proposed to [the W3C in 2001](https://www.w3.org/TR/esi-lang/) but was never adopted as a standard. 

Various CDN providers such as Akamai, Fastly, and Cloudflare have support for ESI, but the feature sets between them vary. For example, [Akamai](https://techdocs.akamai.com/property-mgr/docs/esi-edge-side-includes) and [Fastly](https://developer.fastly.com/reference/vcl/statements/esi/) parse the ESI tags for you, while Cloudflare [seems to require you to write a (simple) Cloudflare Worker]((https://blog.cloudflare.com/edge-side-includes-with-cloudflare-workers/)) that does the parsing of the tag and insertion of dynamic content.

## What are the alternatives to ESI?

Back when ESI was introduced, AJAX requests were considered the alternative approach. Rather than use ESI tags, you would use Javascript to update an empty `<span>` with the dynamic content on the page.

However, the [islands architecture](https://www.patterns.dev/posts/islands-architecture) is the best alternative today that has similar outcomes to ESI, but differs in where the dynamic content is injected.

In islands architecture, placeholders are included in the HTML for the dynamic content when the page is being rendered on the server. These placeholders contain both the static content needed as part of the dynamic content and the Javascript needed to fetch the necessary data.

Whereas content is fetched at an edge location or at the CDN with ESI, using the islands architecture in your application means that the dynamic content is fetched using the returned Javascript on the client side.

One thing to note though is that the islands architecture approach renders the static content immediately for a page while the dynamic content is being requested, whereas the ESI approach doesn't return the page until all the content is available for it.

## Should I use ESI in my application?

As always - it depends on your use case. There are [security concerns to be aware of when using ESI](https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/), and the internet is more available (and reliable) than it was in 2001 when ESI was first introduced.

If it were me I'd go with the islands architecture approach due to the sense of 'responsiveness' users would get from having the static content rendered immediately on their pages, but it's worth knowing about ESI in case there's a time when you need to move the injection of dynamic content from the client side to the server side (or edge/CDN in this case).