Skip to content

Fix Block::load() N+1 and cache manifest generation#832

Merged
jjroelofs merged 4 commits into
8.xfrom
jur/8.x/828-fix-block-load-and-manifest
Jul 8, 2026
Merged

Fix Block::load() N+1 and cache manifest generation#832
jjroelofs merged 4 commits into
8.xfrom
jur/8.x/828-fix-block-load-and-manifest

Conversation

@jjroelofs

Copy link
Copy Markdown
Collaborator

Linked issues

Solution

Two performance fixes:

  1. Block::load() N+1: Replace the per-block Block::load() call in dxpr_theme_preprocess_block() with the block entity already available in the render array ($variables['elements']['#block']), eliminating one entity load per block per page.

  2. Manifest regeneration: Guard _dxpr_theme_generate_manifest() and the apple touch icon entity loads (Media::load, ImageStyle::load) with file-existence checks so the manifest and icon URLs are only computed when the cached files do not exist. Delete the cached files when theme settings are saved so they regenerate with updated values.

Checklist

  • I have read the CONTRIBUTING.md document.
  • My commit messages follow the contributing standards and style of this project.
  • My code follows the coding standards and style of this project.
  • Bug fix (non-breaking change which fixes an issue).
  • New feature (non-breaking change which adds functionality).
  • Breaking change (fix or feature that would cause existing functionality to change).
  • Need to run update.php after code changes.
  • Requires a change to end-user documentation.
  • Requires a change to developer documentation.
  • Requires a change to QA tests.
  • Requires a new QA test.
  • I have updated the documentation accordingly.
  • All new and existing tests passed.

jjroelofs added 2 commits July 8, 2026 07:32
Replace the per-block Block::load() call in dxpr_theme_preprocess_block()
with the block entity already available in the render array via
$variables['elements']['#block'], eliminating one entity load per block
per page request.

Guard _dxpr_theme_generate_manifest() and the apple touch icon entity
loads (Media::load, ImageStyle::load) with file-existence checks so they
only run when the cached files do not exist. Delete the cached files when
theme settings are saved so they regenerate with updated values.

@jjroelofs jjroelofs left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review findings from a local pass. GitHub will not allow this account to request changes on its own PR, but these two items should be treated as blocking before merge.

Validation performed locally:

  • git diff --check origin/8.x...origin/pr/832
  • php -l against dxpr_theme.theme from the PR head
  • php -l against theme-settings.php from the PR head

I could not run PHPCS because this checkout does not have vendor/bin/phpcs installed.

Comment thread dxpr_theme.theme Outdated
function dxpr_theme_preprocess_block(&$variables) {
if (isset($variables['elements']['#id'])) {
$block = Block::load($variables['elements']['#id']);
$block = $variables['elements']['#block'] ?? NULL;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it will silently skip the existing block behavior. Drupal core adds #block for BlockViewBuilder::preRender(), but that same pre-render callback unsets #block before the block theme hook and theme preprocess callbacks run. By the time dxpr_theme_preprocess_block() runs, $variables['elements']['#block'] is normally gone, so $block stays NULL and we stop setting region and the block_classes content_class. The block templates use region for the card/sticker logic, so this is a visible regression. We need another way to carry those values before removing the Block::load() fallback.

Comment thread dxpr_theme.theme Outdated

_dxpr_theme_generate_manifest($web_icons_media_id, $manifest_path);
// Generate manifest only when the file does not already exist.
if (!file_exists($manifest_path)) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caching the manifest solely by file existence makes it stale for inputs that are not invalidated by the theme-settings submit handler. _dxpr_theme_generate_manifest() reads system.site:name, so changing the site name or importing config that changes system.site will keep serving the old manifest name/short_name until someone happens to save theme settings. Please key or regenerate the cached manifest from all of its inputs, or invalidate it when those inputs change.

jjroelofs added 2 commits July 8, 2026 11:28
BlockViewBuilder::preRender() unsets #block before theme preprocess
runs, so $variables['elements']['#block'] is always NULL. Restore
Block::load() which uses the entity static cache.

Regenerate manifest when the site name changes instead of only when
the file is missing, so config changes to system.site are reflected.
@jjroelofs jjroelofs merged commit fd127de into 8.x Jul 8, 2026
5 checks passed
@jjroelofs jjroelofs deleted the jur/8.x/828-fix-block-load-and-manifest branch July 8, 2026 09:33
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.

Refactoring: fix Block::load() N+1 and per-request manifest regeneration

1 participant