Problem/Motivation

Internal fields and disabled fields are instantiated before being filtered out, which is wasteful.

We know whether a field is internal or enabled based on its definition and the resource type. Sites that disable fields with ResourceTypeBuildEvent::disableField() or JSON:API Extras pay for every disabled field on every entity.

Steps to reproduce

  1. Install the Standard profile and enable JSON:API.
  2. Disable most fields of node--article in a ResourceTypeBuildEvent subscriber using $event->disableField().
  3. Create some articles and request /jsonapi/node/article with a profiler enabled.
  4. ContentEntityBase::get() is called for every field of every article, including the disabled ones.

Proposed resolution

Filter before getting the fields by checking the field definitions and then calling get() only for enabled, non-internal fields.

Rough performance improvement

This is not a thorough test, but I ran the numbers for my own site with AI assistance on FrankenPHP in worker mode and found the following. For 50 entities, ContentEntityBase::get() calls fell from 1,772 to 577. Observed request duration decreased from about 600 ms to about 400 ms with XHProf enabled (XHProf overhead seems to be about 10x). My site may have an especially large speedup because I have many disabled fields.

AI disclosure: I used AI to help prepare the IS and MR (Claude Code with Opus 5.5).

Issue fork drupal-3626221

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ptmkenny created an issue. See original summary.

ptmkenny’s picture

Status: Active » Needs review