4

I've got BigPipe enabled in Drupal 8, and it helps to make pages initially load faster.

However, the header block is always one of the blocks that loads in on a delay, which visually looks bad since the content shifts down afterwards.

Is there any type of preprocess on a block to exclude it from BigPipe not be loaded on a delay, and force it to be in the initial page load?

Many thanks.

2 Answers 2

7

You can exclude a block from BigPipe by disabling placeholdering in the block build (preprocess is too late).

/**
 * Implements hook_block_build_BASE_BLOCK_ID_alter().
 */
function mymodule_block_build_example_block_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  // Disable placeholdering of this block.
  $build['#create_placeholder'] = FALSE;
}

But if this is one of the blocks always having a delay it could make the entire module BigPipe useless.

You can solve the content shift in CSS. Delay or stop the block rendering (in this case you can use preprocess) and fill the gap in the partially loaded page with CSS.

Or make the header block more granular. When all dynamic parts are placeholdered the rest of the block is cacheable and loads with the initial page load.

Example block:

  public function build() {
   
    $build = [];
   
    $build[] = [
      '#markup' => '<p>Static part of the block, loads with the initial page.</p>',
    ];

    $build[] = [
      '#lazy_builder' => ['\Drupal\mymodule\LazyBuilders::getUser', []],
      '#cache' => ['contexts' => ['user']],
      // contexts user, session or max-age 0 are automatically placeholdered
    ];

    return $build;
  }

/src/LazyBuilders.php:

<?php

namespace Drupal\mymodule;

use Drupal\Core\Render\Element\RenderCallbackInterface;

class LazyBuilders implements RenderCallbackInterface {

  public static function getUser() {
    return [
      '#markup' => \Drupal::currentUser()->getDisplayName(),
    ];
  }

}
1
  • Thanks, I'll give this a try.
    – chantdev
    Aug 5, 2021 at 17:48
2

I could not get 4uk4 solution to work but based on it I was able to

use \Drupal\Core\Block\BlockPluginInterface;

function MYMODULE_block_build_alter(array &$build, BlockPluginInterface $block) {
  if ($block->getPluginId() === 'system_menu_block:main') {
    $build['#create_placeholder'] = FALSE;
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.