{"id":8004,"date":"2017-09-06T06:00:11","date_gmt":"2017-09-06T10:00:11","guid":{"rendered":"https:\/\/blog.litespeedtech.com\/?p=8004"},"modified":"2017-09-06T06:00:11","modified_gmt":"2017-09-06T10:00:11","slug":"wpw-esi-and-litespeed-cache","status":"publish","type":"post","link":"https:\/\/lswp.store\/index.php\/2017\/09\/06\/wpw-esi-and-litespeed-cache\/","title":{"rendered":"WpW: ESI and LiteSpeed Cache"},"content":{"rendered":"<p><a href=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/wpw17.jpg\"><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-8136\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/wpw17.jpg\" alt=\"WordPress Wednesday: Edge Side Includes Caching\" width=\"640\" height=\"320\" srcset=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/wpw17.jpg 640w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/wpw17-300x150.jpg 300w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/wpw17-600x300.jpg 600w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Welcome to another installment of <a href=\"http:\/\/blog.litespeedtech.com\/tag\/wordpress-wednesday\">WordPress Wednesday<\/a>!<\/p>\n<p>As you may know, <strong>our <a href=\"https:\/\/wordpress.org\/plugins\/litespeed-cache\/\">LiteSpeed Cache for WordPress plugin<\/a> supports <a href=\"https:\/\/en.wikipedia.org\/wiki\/Edge_Side_Includes\">Edge Side Includes<\/a><\/strong>, also known as ESI. Today we are going to talk about why this is such awesome news for your website.<\/p>\n<p><em>Please note: OpenLiteSpeed does not support ESI functionality. You will need <a href=\"https:\/\/www.litespeedtech.com\/products\/litespeed-web-server\">LiteSpeed Web Server Enterprise<\/a>, <a href=\"https:\/\/www.litespeedtech.com\/products\/litespeed-web-adc\">LiteSpeed Web ADC<\/a>, or <a href=\"https:\/\/quic.cloud\">QUIC.cloud CDN<\/a> in order to use ESI.<\/em><\/p>\n<h2>What is ESI?<\/h2>\n<p>ESI is a markup language that allows you to designate parts of your dynamic page as separate fragments that are then assembled together to make the whole page. To put it more quaintly, ESI lets you \u201cpunch holes\u201d in a publicly cached page, and then fill those holes with privately cached content.<\/p>\n<p>With ESI, punched holes can be treated differently than the rest of the page. They can have different TTLs and be purged by events that are completely separate from the page they are on. This allows you to cache more of your site for more of your visitors.<\/p>\n<h2>Public Cache vs. Private Cache<\/h2>\n<p>LiteSpeed Cache is tag-based (which means that each page is stored with an identifier that allows it to be purged from cache as part of a specific subset) and has built-in public and private caches. In the public cache you will find pages that are exactly the same for everyone. Private caches contain content that pertains only to a specific user specified by their IP address and session ID.<\/p>\n<p>Until now, you\u2019ve had to think about your site\u2019s pages in their entirety. Is this page publicly cacheable? Is that one publicly cacheable? If a page had any private data on it at all, you\u2019d have to say \u201cno, it cannot be stored in the public cache.\u201d This issue of having to cache a full page in its entirety is why our WordPress plugin <a href=\"https:\/\/lswp.store\/2017\/08\/30\/wpw-private-cache-vs-public-cache\/\">until 2017<\/a>\u00a0only cached pages for non-logged-in users. In WordPress, non-logged-in users are almost always served only public content. And in the few cases where they are not (password-protected posts, moderated comments, etc.), that content is usually considered non-cacheable for that user. ESI changes this.<\/p>\n<h2>How do ESI and Public\/Private Cache Work Together?<\/h2>\n<p>ESI allows you to disassemble a full page and treat the pieces differently from each other.<\/p>\n<p>LiteSpeed Web Server allows you to store content in either the public cache or a private cache.<\/p>\n<p>Combine these two elements and you get something very powerful. You get a system that can break apart a page into public and private pieces, cache each piece appropriately, and then re-compose the full-page content from the relevant caches and serve it to a user without ever hitting the PHP backend.<\/p>\n<p>That is pretty amazing.<\/p>\n<p><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/null-1.jpeg\" alt=\"Edge Side Includes Caching\" width=\"672\" height=\"448\" \/><\/p>\n<p><strong>This combination allows you to cache content for logged-in WordPress users.<\/strong> With ESI enabled you can say, \u201cHey this page is <em>mostly<\/em> public. Let\u2019s cache it, punch a few holes in it for the private content, and save that content in the private cache.\u201d<\/p>\n<h2>Examples<\/h2>\n<p>Let\u2019s look at a few common scenarios and see how they play out with ESI enabled and without ESI.<\/p>\n<h3>Example #1: Admin Bar<\/h3>\n<p>You\u2019re the site admin, you are logged in, and you visit your site\u2019s home page, which is in the public cache.<\/p>\n<p><strong>Without ESI<\/strong>: your request hits the backend, because the admin bar at the top of the page is private content, and as such this page (and every other page on your site, for that matter) cannot be served to you from cache.<\/p>\n<p><strong>With ESI<\/strong>: most of this page is served to you from the public cache, while the admin bar is served to you from your private cache. There is no need to invoke PHP.<\/p>\n<h3>Example #2: Recent Posts Widget<\/h3>\n<p>You have a large site with much static content that rarely changes. Every page has a sidebar, and the sidebar widget \u201cRecent Posts\u201d appears on each page.<\/p>\n<p><strong>Without ESI<\/strong>: Every time a new post is published, every single page in the site must be purged so that the widget displays up-to-date data. Re-populating the entire cache requires a crawler to run, or visitors to hit all of the pages of the site.<\/p>\n<p><strong>With ESI<\/strong>: All of the pages in the site can remain cached with a nice long TTL, while the Recent Posts widget is the only thing that needs to be purged. Re-populating that one bit of the cache requires just one visitor to request any page one time.<\/p>\n<p>You can see how ESI + LSCache can have huge implications for the speed of your site!<\/p>\n<h2>Enabling and Configuring ESI<\/h2>\n<p>LiteSpeed Cache for WordPress considers all cacheable full pages to be publicly cached.<\/p>\n<p>When you enable ESI, you instruct LSCWP to punch holes in public pages. LiteSpeed then caches the content according to the settings for each block: public, private or not at all, and with its own TTL, independent of the page it is on.<\/p>\n<p>When you enable ESI, LSCWP creates the following ESI blocks:<\/p>\n<ul>\n<li>Admin Bar<\/li>\n<li>Comments<\/li>\n<li>Comment form<\/li>\n<li>Recent Posts widget<\/li>\n<li>Recent Comments widget<\/li>\n<\/ul>\n<p>Any widget can be an ESI block if you want it to be. By default, ESI is disabled for all but the two widgets listed above, but you can change that in WP Admin.<\/p>\n<p><strong>Note<\/strong>: ESI doesn\u2019t come without a cost. It is much simpler for the server to return fully-cached pages than it is for it to piece together pages from several different blocks (although it&#8217;s still more efficient than invoking PHP would be), and so this must be a factor in your decision to enable ESI. Will the speed benefits outweigh the efficiency hit? It depends on your site, really, and it may require some experimentation on your part.<\/p>\n<h3>Basic ESI Settings<\/h3>\n<p><img decoding=\"async\" class=\"alignnone wp-image-12187 size-large\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esi-1024x676.png\" alt=\"Edge Side Includes in LiteSpeed Cache\" width=\"1024\" height=\"676\" srcset=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esi-1024x676.png 1024w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esi-300x198.png 300w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esi-768x507.png 768w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esi-600x396.png 600w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esi.png 1039w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>Navigate to <strong>WP Admin &gt; LiteSpeed Cache &gt; Cache&gt; ESI<\/strong>. Set <strong>Enable ESI<\/strong> to <code>ON<\/code>.<\/p>\n<p>This creates the ESI blocks listed above. The blocks will be uncached, unless you enable caching for them via the <strong>Cache Admin Bar<\/strong> and <strong>Cache Comment Form<\/strong> settings.<\/p>\n<h3>Creating new Widget ESI Blocks<\/h3>\n<p>If you are using <a href=\"https:\/\/wordpress.org\/plugins\/classic-widgets\/\">Classic Widgets<\/a>, you can turn any widget into an ESI block. (Please note that at this time, ESI is only available for classic widgets, and not for the new block-style widgets.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-12189\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esiwidget.png\" alt=\"ESI Classic Widgets with LiteSpeed Cache\" width=\"437\" height=\"470\" srcset=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esiwidget.png 437w, https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/esiwidget-279x300.png 279w\" sizes=\"(max-width: 437px) 100vw, 437px\" \/><\/p>\n<p>Navigate to <strong>WP Admin &gt; Appearance &gt; Widgets<\/strong> and select the widget that you want to turn into an ESI block.<\/p>\n<p>Within the widget settings area, you will see a shaded box entitled \u201cLiteSpeed Cache.\u201d By default a widget is not considered an ESI block (unless it is <strong>Recent Posts<\/strong> or <strong>Recent Comments<\/strong>, as mentioned above). If you want the widget to be treated differently than the pages on which it appears, there are a few possible configurations:<\/p>\n<h4>Private widget<\/h4>\n<p>LSCWP will store the contents in private cache, with different copies for each user by IP\/session ID. (Examples: a list of recently viewed posts, or a personalized greeting.)<\/p>\n<ul>\n<li>Set <strong>Enable ESI<\/strong> to <code>Private<\/code>.<\/li>\n<li>Set <strong>Widget Cache TTL<\/strong> to a value appropriate for the contents of the widget.<\/li>\n<\/ul>\n<h4>Public widget<\/h4>\n<p>LSCWP will store the contents in public cache, with each user seeing the exact same thing. (Examples: a list of recent posts, or a calendar of upcoming events).<\/p>\n<ul>\n<li>Set <strong>Enable ESI<\/strong> to <code>Public<\/code>.<\/li>\n<li>Set <strong>Widget Cache TTL<\/strong> to a value appropriate for the contents of the widget.<\/li>\n<\/ul>\n<h4>Uncached widget<\/h4>\n<p>LSCWP will not cache the contents at all, and WordPress will dynamically-generate the widget each time it displays on the page.<\/p>\n<ul>\n<li>Set <strong>Enable ESI<\/strong> to either <code>Public<\/code> or <code>Private<\/code> (it makes no difference, as long as it\u2019s not <code>Disable<\/code>)<\/li>\n<li>Set <strong>Widget Cache TTL<\/strong> to <code>0<\/code>.<\/li>\n<\/ul>\n<h2>ESI and Third Party Plugins<\/h2>\n<p>Our ESI implementation supports a few other blocks that belong to third-party plugins. For instance, we consider the WooCommerce shopping cart to be a private ESI block.<\/p>\n<p>As we mentioned earlier, with ESI enabled, your site pages are now considered publicly-cacheable, because we are able to punch holes for the occasional non-public content. This is true for all native WordPress pages, and for all WooCommerce pages. It is not, however, true with bbPress.<\/p>\n<p>A bbPress page contains so many areas of private data, that it\u2019s actually much more efficient to consider the entire page to be private. So, that\u2019s what we\u2019ve done. LSCache considers all bbPress pages to be private.<\/p>\n<p>If one of your favorite plugins warrants special consideration, we encourage you to get in touch with us via <a href=\"https:\/\/wordpress.org\/support\/plugin\/litespeed-cache\">the WordPress plugin support forum<\/a> and tell us about it.<\/p>\n<p>Or try <a href=\"https:\/\/lswp.store\/2018\/12\/12\/wordpress-shortcodes-esi-blocks\/\">turning third party shortcodes into ESI blocks<\/a>.<\/p>\n<p>P.S. Want to know more technical details about ESI? <a href=\"https:\/\/www.w3.org\/TR\/esi-lang\">Check out the official specs<\/a>.<\/p>\n<p>\u2014<br \/>\n<em>This content was last verified and updated in April of 2023. If you find an inaccuracy, please let us know! In the meantime, see <a href=\"https:\/\/docs.litespeedtech.com\/\">our documentation site<\/a>\u00a0for the most up-to-date information.<\/em><\/p>\n<p>&#8212;<\/p>\n<p>Have some of your own ideas for future <a href=\"http:\/\/blog.litespeedtech.com\/tag\/wordpress-wednesday\">WordPress Wednesday<\/a> topics? Leave us a comment!<\/p>\n<p>Don\u2019t forget to meet us back here next week for the next installment. In the meantime, here are a few other things you can do:<\/p>\n<ul>\n<li>Subscribe to the <a href=\"http:\/\/blog.litespeedtech.com\/tag\/wordpress-wednesday\/feed\/\">WordPress Wednesday RSS feed<\/a><\/li>\n<li>Download <a href=\"https:\/\/wordpress.org\/plugins\/litespeed-cache\/\">LiteSpeed Cache for WordPress plugin<\/a><\/li>\n<li>Learn more about the plugin <a href=\"https:\/\/www.litespeedtech.com\/products\/cache-plugins\/wordpress-acceleration\">on our website<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>LSCWP now support Edge Side Includes, also known as ESI! Let&#8217;s talk about why this is such awesome news for your website.<\/p>\n","protected":false},"author":1,"featured_media":8136,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[28],"tags":[103,316,317],"class_list":["post-8004","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cache","tag-esi","tag-wordpress","tag-wordpress-wednesday"],"jetpack_featured_media_url":"https:\/\/lswp.store\/wp-content\/uploads\/2017\/09\/wpw17.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/8004","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/comments?post=8004"}],"version-history":[{"count":0,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/8004\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media\/8136"}],"wp:attachment":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media?parent=8004"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/categories?post=8004"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/tags?post=8004"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}