Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Globally cached components #177

Open
mfendeksilverstripe opened this issue Nov 3, 2023 · 5 comments
Open

RFC: Globally cached components #177

mfendeksilverstripe opened this issue Nov 3, 2023 · 5 comments

Comments

@mfendeksilverstripe
Copy link
Collaborator

mfendeksilverstripe commented Nov 3, 2023

RFC: Globally cached components

This module is really great to improve performance on websites. There are some limitations though especially for large websites that can be tricky to deal with. I wanted to tackle the challenge on how to deal with global components such as header navigation menu.

Screenshot 2023-11-03 at 2 55 40 PM

The problem

Global component such as header navigation menu are usually not changed often but when they do change, they cause site-wide impact as almost every page on the site has this global component. With this module in place this can be tricky to deal with in a timely fashion as the only option available is to recache the whole site. The duration depends on the size of the site, this can be hours, even days.

Potential solution

In one of our projects we implemented a globally cached component feature to deal with this challenge. The idea behind this is simple:

  • global components such as header navigation menu are cached in separate files so they can be recached independently of individual pages
  • static cache files of individual pages do not contain the rendered global component but rather a simple placeholder
  • static cache handler composes a valid page response by taking the static cache file of an individual page and replaces the placeholders within that file with their matching global components.

Behaviour change

Let's try to visualise the solution.

Current behaviour

Static cache handler will put together two files - HTML file containing page render and PHP file containing headers. Together they create a valid page response.

Screenshot 2023-11-03 at 3 03 38 PM

With global components support

In this case the static cache handler needs to put together three files - HTML file containing page render, PHP file containing headers and the global component (header navigation menu) which has its own cache file. The global component is injected into the page render file by replacing a placeholder representing the place where the global component is expected to appear. Placeholder can be arbitrary string but we used an HTML comment containing component name so the page render HTML file contains valid HTML (for example <!-- HEADER -->).

Screenshot 2023-11-03 at 3 06 28 PM

What can this be used for

Global components can be anything. For example it can be used to inject inline CSS into your page HTML. This is usually done to ensure that the very basic CSS is available from the start of the page load. Overall, this feature can cover lot of cases where there is the need to have the ability to quickly recache one component that is present on potentially all pages on your site.

Downsides

This feature sounds very cool but it does bring complexity into your application. The page response composition is now more complex and you may need to think about cases where not all global components have cache files available. Some global components may need page specific data which can be stored in the page PHP file which normally contains only headers.

The most notable downside is different rendering mode for pages when they are generating static cache and when they are rendered dynamically. For example, when you are rendering the page in a CMS preview screen you want your global components to be rendered within the page. On the other hand if the page render is executed within the static cache job we want to render placeholders instead. This causes more test cases to be present and the overall code complexity is increased.

Summary

I'm looking for feedback on this feature - if people would find this feature useful and in what cases. Also, reasons why this is a bad idea and why people would not like to use it.

@mfendeksilverstripe
Copy link
Collaborator Author

@GuySartorelli
Copy link
Member

GuySartorelli commented Nov 3, 2023

Sounds like a great idea.

I'd recommend using include component.php in the main page php, so you have

Main page:

  • headers
  • includes components

Components:

  • just the cached content - by default for the whole page, but configurable to be multiple cached components which get included.

This is much simpler than having a string replace and uses pre-existing php functionality. This is how you'd make composable php pages back in the day. I think doing it this way will be sufficiently light weight to not meaningfully impact performance compared with the current functionality.

@GuySartorelli
Copy link
Member

The main thing I think will be finding a sensible way to define "this part is component x" and mapping that correctly when creating the static content.

@emteknetnz
Copy link
Member

emteknetnz commented Nov 3, 2023

Feels like this solution is similar to an old fashioned php website:

MyTemplate.php

<?php
include 'header.php'; // includes the mega menu
include 'content.php';
include 'footer.php';

The problem is that changing something in headers.php e.g. a Page title, still requires the entire sites static cache to be purged and rebuilt, because the the Page title in the mega menu is still part of the statically cached page. The proposed solution is just a performance optimisation that's going to make the creation of headers.php a one-off instead of having to do it everytime.

As a completely different solution to solve the same problem:

Would it work to simply XHR in your "header navigation menu" served from a controller endpoint with HTTP caching on it? That would do away with any requirement to rebuild the site entire static cache whenever a page title changes. I'm assuming that these days this wouldn't have any SEO downside.

@mfendeksilverstripe
Copy link
Collaborator Author

FYI: @chrispenny

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants