Skip to content

[6.x] Performance for large Replicators, Relationships and Conditional fields #13385

@martyf

Description

@martyf

Bug description

This has been a little issue in Statamic 5, but with my testing, it feels more obvious in Statamic 6 - maybe it is the Inertia side of things (and the progress bar at the top) that makes it more obvious.

One use case for Statamic is to have a Replicator fieldtype that is block-level page builder. Each block could have many different types of fields: Bard, Text, Select, Entry, Asset... and also have conditionals within them.

When you have many blocks (i.e. over a dozen), page loads start to crawl. The server-side request is fast - but it is the rendering in the JS side of things, specifically around:

  • rendering a Bard field (if Set is expanded)
  • rendering the preview of a Bard field (if Set is collapsed)
  • conditional fields

If I just hit refresh on the page, and the Replicator is fully expanded (so all Sets are shown) there is a noticeable delay while the Bard field renders.

If the Replicator is fully collapsed (all Sets hidden), there is still a noticeable delay, but it is the appearance of the Preview of the Bard content in the header.

In this example there are also numerous Conditional fields in play, and IIRC this was a bit of a JS bottleneck in the past because of the level of computation.

Add in fields like Entry which call relationships, if you've got one of these per block, and 10 blocks, that's 10 relationships calls that get fired at once. Make that multiple fields that need lookups - Entry, Asset, etc - that number of calls can increase phenomenally. 10 blocks, each with an Entry and an Image, that now is 20 calls. Add more Sets in the Bard content, and even more calls are made.

And oddly, they sometimes then get called a second time during the page load - there's a load of data, load of relationships, then relationships can get called again.

What compounds it further is that each request is actually doing the same thing. With 10 blocks in your Replicator, each with an Entry fieldtype, each of the 10 relationships calls is pulling the list of options for that field to display. In this instance, each of the 10 calls returns an identical response - so 9 of those 10 calls are actually not needed at all.

I'm not sure if there is a way to hook in to these load requests, and create a bulk approach to loading relationships and data - especially on initial page load. This would have a massive impact on initial page response times and server load.

After an Entry is loaded, doing calls one-by-one (such as if you add a new Set) is totally expected and while it still hits the server, has a smaller scope of impact.

The real giveaway is that the page loads and renders its initial layout, and Inertia is finished, but the browser tab is still loading and shows that in its loading icon.

If you open Dev Tools, it amplifies the issue, and I've had it completely hang the browser (i.e. the script timeout bar on the browser appears).

I have a basic repo that demonstrates the issue... but in a full-blown site I've been building with Statamic 6, it is incredibly noticeable on some pages.

I'm not sure what makes sense here - the repo... screen recordings of issues... happy to share both the repo and even the project (private repo only) to help see configurations in a real-world setup and the impact it can have. If you need private repo access, let me know who should have it (and note it's a WIP so is being changed day by day, but I can keep a great example of a poor page load intact).

How to reproduce

Statamic 6 Alpha 19

I have a leaner repo that shows the issue (but a bit harder to see), and a project that has much more noticeable issues (private repo). Access to both can be provided if needed.

Issue is present with zero addons installed on a clean install.

Logs

Environment

Environment
Application Name: Statamic
Laravel Version: 12.43.1
PHP Version: 8.4.15
Composer Version: 2.9.2
Environment: local
Debug Mode: ENABLED
URL: s6-plain.test
Maintenance Mode: OFF
Timezone: UTC
Locale: en

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: file
Database: sqlite
Logs: stack / single
Mail: log
Queue: sync
Session: file

Storage
public/storage: NOT LINKED

Statamic
Addons: 0
Sites: 1
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 6.0.0-alpha.19 PRO

Installation

Fresh statamic/statamic site via CLI

Additional details

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions