function BigPipe::sendPreBody

Same name in other branches
  1. 9 core/modules/big_pipe/src/Render/BigPipe.php \Drupal\big_pipe\Render\BigPipe::sendPreBody()
  2. 8.9.x core/modules/big_pipe/src/Render/BigPipe.php \Drupal\big_pipe\Render\BigPipe::sendPreBody()
  3. 10 core/modules/big_pipe/src/Render/BigPipe.php \Drupal\big_pipe\Render\BigPipe::sendPreBody()

Sends everything until just before </body>.

Parameters

string $pre_body: The HTML response's content until the closing </body> tag.

array $no_js_placeholders: The no-JS BigPipe placeholders.

\Drupal\Core\Asset\AttachedAssetsInterface $cumulative_assets: The cumulative assets sent so far; to be updated while rendering no-JS BigPipe placeholders.

1 call to BigPipe::sendPreBody()
BigPipe::sendContent in core/modules/big_pipe/src/Render/BigPipe.php
Sends an HTML response in chunks using the BigPipe technique.

File

core/modules/big_pipe/src/Render/BigPipe.php, line 265

Class

BigPipe
Service for sending an HTML response in chunks (to get faster page loads).

Namespace

Drupal\big_pipe\Render

Code

protected function sendPreBody($pre_body, array $no_js_placeholders, AttachedAssetsInterface $cumulative_assets) {
    // If there are no no-JS BigPipe placeholders, we can send the pre-</body>
    // part of the page immediately.
    if (empty($no_js_placeholders)) {
        $this->sendChunk($pre_body);
        return;
    }
    // Extract the scripts_bottom markup: the no-JS BigPipe placeholders that we
    // will render may attach additional asset libraries, and if so, it will be
    // necessary to re-render scripts_bottom.
    [
        $pre_scripts_bottom,
        $scripts_bottom,
        $post_scripts_bottom,
    ] = explode('<drupal-big-pipe-scripts-bottom-marker>', $pre_body, 3);
    $cumulative_assets_initial = clone $cumulative_assets;
    $this->sendNoJsPlaceholders($pre_scripts_bottom . $post_scripts_bottom, $no_js_placeholders, $cumulative_assets);
    // If additional asset libraries or drupalSettings were attached by any of
    // the placeholders, then we need to re-render scripts_bottom.
    if ($cumulative_assets_initial != $cumulative_assets) {
        // Create a new HtmlResponse. Ensure the CSS and (non-bottom) JS is sent
        // before the HTML they're associated with.
        // @see \Drupal\Core\Render\HtmlResponseSubscriber
        // @see template_preprocess_html()
        $js_bottom_placeholder = '<nojs-bigpipe-placeholder-scripts-bottom-placeholder token="' . Crypt::randomBytesBase64(55) . '">';
        $html_response = new HtmlResponse();
        $html_response->setContent([
            '#markup' => BigPipeMarkup::create($js_bottom_placeholder),
            '#attached' => [
                'drupalSettings' => $cumulative_assets->getSettings(),
                'library' => $cumulative_assets->getAlreadyLoadedLibraries(),
                'html_response_attachment_placeholders' => [
                    'scripts_bottom' => $js_bottom_placeholder,
                ],
            ],
        ]);
        $html_response->getCacheableMetadata()
            ->setCacheMaxAge(0);
        // Push a fake request with the asset libraries loaded so far and dispatch
        // KernelEvents::RESPONSE event. This results in the attachments for the
        // HTML response being processed by HtmlResponseAttachmentsProcessor and
        // hence the HTML to load the bottom JavaScript can be rendered.
        $fake_request = $this->requestStack
            ->getMainRequest()
            ->duplicate();
        $html_response = $this->filterEmbeddedResponse($fake_request, $html_response);
        $scripts_bottom = $html_response->getContent();
    }
    $this->sendChunk($scripts_bottom);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.