Skip to content

[6.x] Skip repeated work when reading augmented entries and values - #15806

Open
DanielDarrenJones wants to merge 1 commit into
statamic:6.xfrom
DanielDarrenJones:perf/6x-augmentation-fast-paths
Open

DanielDarrenJones wants to merge 1 commit into
statamic:6.xfrom
DanielDarrenJones:perf/6x-augmentation-fast-paths

Conversation

@DanielDarrenJones

Copy link
Copy Markdown
Contributor

A few small fast paths on the reads that dominate rendering:

  • Value::value() keeps the augmented value for select, radio, button group, toggle, text and textarea fields, whose augmented value depends only on the raw value and the field's config. This only applies to those exact classes (not subclasses), and only while the Value has the same fieldtype instance. setFieldtype() drops it.
  • Entry::id(), locale() and blueprint() return directly when used as getters, instead of building a FluentGetterSetter each time. blueprint() only takes the short cut when Blink already has the blueprint, so EntryBlueprintFound fires exactly as before.
  • FluentGetterSetter reads properties through one closure per class, instead of binding a new one on every read.
  • Site::absoluteUrl() keeps the absolute URL of a site with a relative URL for the rest of the request. It's keyed on the request's root URL, its script name and the trailing slash setting. Sites with absolute URLs go the usual way.
  • AugmentedEntry::keys() and AugmentedPage::keys() merge, deduplicate and sort plain arrays instead of chaining collections. The flags are the same, and so is the result.
  • The translator only checks for a CP route when the key starts with validation..

Benchmark

A generated site on 6.40.0 (entries, structured collections, navs of three sizes), six warm scenarios: three sets of page renders and three nav renders. Each request runs in its own PHP process, as PHP-FPM serves it (boot not timed, opcache on), on an M1 Pro with PHP 8.5. The rendered HTML is byte-identical to stock for two different generated sites.

This change on its own is 5% faster (geometric mean over the six scenarios).

Tests

  • New ValueTest tests: a select's augmented value is kept, and dropped when the fieldtype changes. Subclasses and other fieldtypes are still augmented on every read.
  • A new SiteTest test: a relative site's absolute URL follows the request host, a forced root URL and the trailing slash setting.

The full suite passes.

A handful of small fast paths on the hottest reads while rendering:

- A Value for a select, radio, button group, toggle, text or textarea field
  keeps its augmented value instead of augmenting again on every read.
- Entry::id(), locale() and blueprint() return directly when called as
  getters, without building a FluentGetterSetter each time.
- FluentGetterSetter reads properties through one closure per class instead
  of binding a new one on every read.
- Site::absoluteUrl() keeps the absolute URL of a site with a relative URL for
  the request, keyed on the request's root URL and the trailing slash setting.
- The augmented keys of entries and pages are merged, deduplicated and sorted
  as arrays rather than through a chain of collections.
- The translator only checks whether it's a CP route for validation keys.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant