.../HtmlResponseBigPipeSubscriber.php              |  2 +-
 core/modules/big_pipe/src/Render/BigPipe.php       |  7 +---
 .../Render/BigPipeResponseAttachmentsProcessor.php |  8 +++++
 .../src/Render/Placeholder/BigPipeStrategy.php     | 42 ++++++++++++++++++----
 4 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/core/modules/big_pipe/src/EventSubscriber/HtmlResponseBigPipeSubscriber.php b/core/modules/big_pipe/src/EventSubscriber/HtmlResponseBigPipeSubscriber.php
index 769581f..a96c44c 100644
--- a/core/modules/big_pipe/src/EventSubscriber/HtmlResponseBigPipeSubscriber.php
+++ b/core/modules/big_pipe/src/EventSubscriber/HtmlResponseBigPipeSubscriber.php
@@ -79,7 +79,7 @@ public function onRespond(FilterResponseEvent $event) {
     }
 
     $attachments = $response->getAttachments();
-    if (empty($attachments['big_pipe_placeholders'])) {
+    if (empty($attachments['big_pipe_placeholders']) && empty($attachments['big_pipe_nojs_placeholders'])) {
       // Remove our marker again.
       $content = $response->getContent();
       $content = str_replace('', '', $content);
diff --git a/core/modules/big_pipe/src/Render/BigPipe.php b/core/modules/big_pipe/src/Render/BigPipe.php
index 284de02..d7b5a61 100644
--- a/core/modules/big_pipe/src/Render/BigPipe.php
+++ b/core/modules/big_pipe/src/Render/BigPipe.php
@@ -122,12 +122,7 @@ public function sendContent($content, array $attachments) {
     }
 
     $placeholders = isset($attachments['big_pipe_placeholders']) ? $attachments['big_pipe_placeholders'] : [];
-    $half_pipe_placeholders = [];
-
-    if (empty($_SESSION['big_pipe_has_js'])) {
-      $half_pipe_placeholders = $placeholders;
-      $placeholders = [];
-    }
+    $half_pipe_placeholders = isset($attachments['big_pipe_nojs_placeholders']) ? $attachments['big_pipe_nojs_placeholders'] : [];
 
     if (!empty($half_pipe_placeholders)) {
       $extra_attachments = $this->doHalfPipe($page_parts[0], $half_pipe_placeholders);
diff --git a/core/modules/big_pipe/src/Render/BigPipeResponseAttachmentsProcessor.php b/core/modules/big_pipe/src/Render/BigPipeResponseAttachmentsProcessor.php
index 3e54417..7abda9b 100644
--- a/core/modules/big_pipe/src/Render/BigPipeResponseAttachmentsProcessor.php
+++ b/core/modules/big_pipe/src/Render/BigPipeResponseAttachmentsProcessor.php
@@ -85,10 +85,15 @@ public function processAttachments(AttachmentsInterface $response) {
     // know (nor need to know) how to process those.
     $attachments = $response->getAttachments();
     $big_pipe_placeholders = [];
+    $big_pipe_nojs_placeholders = [];
     if (isset($attachments['big_pipe_placeholders'])) {
       $big_pipe_placeholders = $attachments['big_pipe_placeholders'];
       unset($attachments['big_pipe_placeholders']);
     }
+    if (isset($attachments['big_pipe_nojs_placeholders'])) {
+      $big_pipe_nojs_placeholders = $attachments['big_pipe_nojs_placeholders'];
+      unset($attachments['big_pipe_nojs_placeholders']);
+    }
     $response->setAttachments($attachments);
 
     // Call HtmlResponseAttachmentsProcessor to process all other attachments.
@@ -99,6 +104,9 @@ public function processAttachments(AttachmentsInterface $response) {
     if (count($big_pipe_placeholders)) {
       $attachments['big_pipe_placeholders'] = $big_pipe_placeholders;
     }
+    if (count($big_pipe_nojs_placeholders)) {
+      $attachments['big_pipe_nojs_placeholders'] = $big_pipe_nojs_placeholders;
+    }
     $response->setAttachments($attachments);
 
     return $response;
diff --git a/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php b/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
index be75fcb..6db3b8b 100644
--- a/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
+++ b/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
@@ -50,7 +50,6 @@
  * @see \Drupal\big_pipe\Render\BigPipe
  *
  * @todo Rename #attached[big_pipe_placeholders] to #attached[big_pipe_js_placeholders]
- * @todo Introduce #attached[big_pipe_nojs_placeholders] and remove the current globals-based switching logic in this class and the BigPipe class
  */
 class BigPipeStrategy implements PlaceholderStrategyInterface {
 
@@ -83,11 +82,6 @@ public function processPlaceholders(array $placeholders) {
       return $return;
     }
 
-    // @todo Add 'session' cache context.
-    if (empty($_SESSION['big_pipe_has_js'])) {
-      return $return;
-    }
-
     foreach ($placeholders as $placeholder => $placeholder_elements) {
       // BigPipe uses JavaScript and the DOM to find the placeholder to replace.
       // This means finding the placeholder to replace must be efficient. Most
@@ -107,7 +101,14 @@ public function processPlaceholders(array $placeholders) {
         continue;
       }
       else {
-        $return[$placeholder] = static::createBigPipeJsPlaceholder($placeholder, $placeholder_elements);
+        // If the current session doesn't have JavaScript, fall back to no-JS
+        // BigPipe.
+        if (empty($_SESSION['big_pipe_has_js'])) {
+          $return[$placeholder] = static::createBigPipeNoJsPlaceholder($placeholder, $placeholder_elements);
+        }
+        else {
+          $return[$placeholder] = static::createBigPipeJsPlaceholder($placeholder, $placeholder_elements);
+        }
       }
     }
 
@@ -163,4 +164,31 @@ protected static function createBigPipeJsPlaceholder($original_placeholder, arra
     ];
   }
 
+  /**
+   * Creates a BigPipe no-JS placeholder.
+   *
+   * @param string $original_placeholder
+   *   The original placeholder.
+   * @param array $placeholder_render_array
+   *   The render array for a placeholder.
+   *
+   * @return array
+   *   The resulting BigPipe no-JS placeholder render array.
+   */
+  protected static function createBigPipeNoJsPlaceholder($original_placeholder, array $placeholder_render_array) {
+    $html_placeholder = Html::getId($original_placeholder);
+    return [
+      '#markup' => '',
+      '#cache' => [
+        'contexts' => ['session'],
+        'max-age' => 0,
+      ],
+      '#attached' => [
+        'big_pipe_nojs_placeholders' => [
+          $html_placeholder => $placeholder_render_array,
+        ],
+      ],
+    ];
+  }
+
 }