Skip to content

Performance: 20x fewer field-lookup queries, screen-gated heavy assets, 4MB lighter zip#451

Closed
cbravobernal wants to merge 3 commits into
tests/full-coverage-batteryfrom
perf/runtime-and-asset-optimizations
Closed

Performance: 20x fewer field-lookup queries, screen-gated heavy assets, 4MB lighter zip#451
cbravobernal wants to merge 3 commits into
tests/full-coverage-batteryfrom
perf/runtime-and-asset-optimizations

Conversation

@cbravobernal

Copy link
Copy Markdown
Contributor

Stacked on #450 (test battery) — merge that first; this branch contains it. Every change here is gated by that suite passing unmodified.

This PR implements the highest-impact, lowest-risk items from a measured performance audit of the plugin (PHP runtime profiled in wp-env with query/timing instrumentation; asset graph audited bundle-by-bundle). All changes are behavior-identical: the full battery (2788 PHPUnit / 946 Jest / 253 E2E / PHPStan) passes without modifying a single test.

PHP runtime

Change Measured impact
Prime sibling field definitions when a field key resolves (includes/acf-field-functions.php) get_field() over a 50-field template: 101 → 5 SQL queries, ~17ms → ~2.8ms (cache-less hosts)
Decode each local JSON file once per request instead of 4× (includes/local-json.php) 200 JSON files: 44ms → 16ms per request
Per-request cache for acf_get_option_meta() with invalidation via core option hooks (includes/acf-meta-functions.php) Options-page meta: 1 LIKE query then 0 on repeat
acf_decode_taxonomy_term(): raw term_taxonomy SQL → get_term() (term cache) Uncached query eliminated
Blocks save-path early bail when no block types registered (includes/blocks.php) Skips block parsing on every save for non-block sites
Gate escaped-html notice script to when the notice renders (includes/admin/admin.php) Removes script+localize from every admin page
Memoize the version check in acf_is_using_datastore() (includes/datastore.php) Partial by design: the setting filter is still applied per call (tests/runtime toggle it mid-request)

The priming behavior has an escape hatch: acf/prime_field_group_fields filter (default true) for plugins that filter per-key field queries (e.g. multilingual plugins). Per-field acf/load_field filters still run exactly as before — only the raw key→post lookup is primed.

Assets / enqueue

Change Impact
scf-bindings moved to enqueue_block_editor_assets (includes/assets.php) Stops pulling the full wp-editor dependency stack onto classic admin pages and public front-end acf_form() pages where the bindings UI cannot function
Command-palette scripts gated on wp_script_is( 'wp-commands', 'enqueued' ) (includes/admin/admin-commands.php) On WP ≤ 6.8, stops loading React + wp-components on every classic admin page; behavior-neutral on 6.9+ where core loads the palette everywhere
Drop injectPolyfill from webpack Removes the wp-polyfill dependency (~30 KB gz) from every script handle, including front-end forms
Fix pro CSS suffix (includes/assets.php) Production now loads acf-pro-input.min.css (32.6 KB) instead of the unminified 47.2 KB file on every edit screen and front-end form
Gate acf-pro-ui-options-page (admin-only feature) with is_admin() No longer ships to front-end forms
Fix acf-dark stylesheet path (includes/third-party.php) Was 404ing on every request for dark-mode-plugin users (assets/css/ never existed)
Trim release zip (bin/create-release-zip.sh): exclude assets/src/ and source maps 9.2 MB → 5.0 MB staged assets (−4.2 MB). Unminified build files kept (SCF_DEVELOPMENT_MODE loads them); select2 v3 kept (still reachable via the select2_version setting)

Deliberately not included (higher risk, future candidates)

Splitting acf-global.css (loads 21 KB gz on every admin page — needs visual QA), lazy field-type loading, defer on acf/acf-input (third-party scripts assume acf at parse time), conditional select2 loading, and CSS recompilation from source partials.

Verification

  • composer test:php: OK (2788 tests, 6371 assertions) — zero tests modified
  • composer test:phpstan: clean
  • npm run test:unit: 946/946
  • Full Playwright suite: passing (see checks)
  • Targeted verification during development: authenticated curls confirming script presence/absence per screen type; before/after query+timing benchmarks in the wp-env container; command palette (12 e2e tests), bindings site-editor, block render specs
  • phpcs: zero new violations on touched files (several carry pre-existing baseline violations)

Closes

Use of AI Tools

This PR was authored by Claude Code (Claude Fable 5) under human direction. The audit, the selection of which optimizations to implement vs defer, and all changes were validated by benchmarks and the full test battery; build artifacts are generated by the standard npm run build.

… screens

PHP runtime (measured in wp-env, cache-less host):
- Prime sibling field definitions when a field key resolves: get_field()
  across a 50-field template drops from 101 SQL queries / ~17ms to
  5 queries / ~2.8ms. Opt-out via acf/prime_field_group_fields filter;
  per-field load_field filters unchanged.
- Decode each local JSON file once per request instead of 4x:
  44ms -> 16ms at 200 files.
- Per-request cache for acf_get_option_meta() LIKE queries, invalidated
  via core added/updated/deleted_option hooks.
- acf_decode_taxonomy_term(): raw term_taxonomy SQL -> get_term().
- Early-bail block save parsing when no block types are registered.
- Enqueue the escaped-html notice script only when the notice renders.
- Memoize the WP version check in acf_is_using_datastore().

Assets:
- Load scf-bindings only in block editor contexts; it previously pulled
  the full wp-editor dependency stack onto classic admin pages and
  public front-end acf_form() pages.
- Gate command-palette scripts on wp-commands being enqueued (stops
  React + wp-components loading on every classic admin page on WP <=6.8).
- Drop wp-polyfill dependency from all bundles (webpack injectPolyfill).
- Fix pro CSS min suffix: production shipped unminified acf-pro-input.css.
- Gate admin-only acf-pro-ui-options-page script with is_admin().
- Fix acf-dark stylesheet 404 (wrong path since the build move).
- Exclude assets/src and source maps from the release zip (-4.2MB).

Verified: 2788 PHPUnit / 946 Jest / 253 E2E tests green, PHPStan clean,
zero tests modified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props cbravobernal.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@cbravobernal

Copy link
Copy Markdown
Contributor Author

Superseded by #466. This PR was auto-closed when its base branch (the test battery) merged into trunk; GitHub does not allow reopening/retargeting a PR whose base branch was deleted, so the work continues in #466 (rebased onto trunk, conflict resolved to keep both the option-meta cache and the #462 esc_like fix).

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