BeaconCMS / beacon

Open-source content management system (CMS) built with Phoenix LiveView. Faster render times to boost SEO performance, even for the most content-heavy pages.
https://beaconcms.org
MIT License
818 stars 84 forks source link

[Discussion] Page Storage strategies #533

Open leandrocp opened 1 week ago

leandrocp commented 1 week ago

This issue is a discussion and overview of possible strategies to serve pages dynamically.

Beacon needs to serve templates and data for each page that are created at runtime and there are different strategies with its own benefits and trade-offs. In order to compare such strategies, let's list the requirements first:

Requirements

Keep in mind such storage is dynamic as new pages are published it must be updated at runtime.

Below is a simplified pseudo-code of how templates and assigns are used in the LiveView that handle all requests:

defmodule PageLive do
  def mount(params, session, socket) do
    page = load_page(site, path)
    {:ok, assign(title: page.title)}
  end

  def render(assigns) do
    page.template
  end
end

Essentially the PageLive is a proxy that loads pages and serves the template and data on the regular LiveView workflow.

Strategies

Single Pages Module

One single module containing all templates and all assigns of all pages in this format:

defmodule Pages do
  def render("/" = _path) do
    ~H"<h1>Home</h1>"
  end

  def assigns("/" = _path) do
    %{title: "Home"}
  end

  def render("/contact" = _path) do
    ~H"<h1>Contact</h1>"
  end

  def assigns("/contact" = _path) do
    %{title: "Contact"}
  end
end

Pros

Cons

Multiple Page Modules

The current strategy in use.

defmodule PageA do
  def render do
    ~H"<h1>Home</h1>"
  end

  def assigns do
    %{title: "Home"}
  end
end

defmodule PageB do
  def render do
    ~H"<h1>Contact</h1>"
  end

  def assigns do
    %{title: "Contact"}
  end
end

Pros

Cons

ETS

Essentially similar to multiple page modules but store pages into ETS, thus have essential the same pros and cons with the biggest difference that it's slower but handles concurrent requests more easily.

Persistent Term

Very similar to ETS but should be a bit faster to read and much slower to write.


Performance is essential and can't be ignored. An initial benchmark shows that modules are faster than persistent_term and ETS.