 big_pipe.libraries.yml |  2 +-
 js/big_pipe.js         | 41 ++++++++++++++++++++++++-----------------
 src/Render/BigPipe.php |  4 ++--
 3 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/big_pipe.libraries.yml b/big_pipe.libraries.yml
index 88ecff6..7013da9 100644
--- a/big_pipe.libraries.yml
+++ b/big_pipe.libraries.yml
@@ -6,6 +6,6 @@ big_pipe:
     bigPipePlaceholders: []
   dependencies:
     - core/jquery
-    - core/drupal
+    - core/jquery.once
     - core/drupal.ajax
     - core/drupalSettings
diff --git a/js/big_pipe.js b/js/big_pipe.js
index e21df03..dd8a4e9 100644
--- a/js/big_pipe.js
+++ b/js/big_pipe.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Provides Ajax page updating via BigPipe.
+ * Renders BigPipe placeholders using Drupal's Ajax system.
  */
 
 (function ($, Drupal, drupalSettings) {
@@ -8,23 +8,26 @@
   'use strict';
 
   /**
-   * Execute Ajax commands included in the script tag.
+   * Executes Ajax commands in <script type="application/vnd.drupal-ajax"> tag.
+   *
+   * These Ajax commands replace placeholders with HTML and load missing CSS/JS.
    *
    * @param {number} index
    *   Current index.
    * @param {HTMLScriptElement} placeholder
-   *   Script tag created by bigPipe.
+   *   Script tag created by BigPipe.
    */
   function bigPipeProcessPlaceholder(index, placeholder) {
-    var placeholderName = this.getAttribute('data-big-pipe-placeholder');
+    var placeholderName = placeholder.getAttribute('data-big-pipe-placeholder');
     var content = this.textContent.trim();
-    // Ignore any placeholders that are not in the known placeholder list.
-    // This is used to avoid someone trying to XSS the site via the
-    // placeholdering mechanism.;
+    // Ignore any placeholders that are not in the known placeholder list. Used
+    // to avoid someone trying to XSS the site via the placeholdering mechanism.
     if (typeof drupalSettings.bigPipePlaceholders[placeholderName] !== 'undefined') {
-      // If we try to parse the content too early textContent will be empty,
-      // making JSON.parse fail. Remove once so that it can be processed again
+      // If we try to parse the content too early (when the JSON containing Ajax
+      // commands is still arriving), textContent will be empty which will cause
+      // JSON.parse() to fail. Remove once so that it can be processed again
       // later.
+      // @see bigPipeProcessContainer()
       if (content === '') {
         $(this).removeOnce('big-pipe');
       }
@@ -38,24 +41,28 @@
   }
 
   /**
+   * Processes a streamed HTML document receiving placeholder replacements.
    *
    * @param {HTMLDocument} context
-   *   Main
+   *   The HTML document containing <script type="application/vnd.drupal-ajax">
+   *   tags generated by BigPipe.
    *
    * @return {bool}
-   *   Returns true when processing has been finished and a stop tag has been
+   *   Returns true when processing has been finished and a stop signal has been
    *   found.
    */
-  function bigPipeProcessContainer(context) {
-    // Make sure we have bigPipe related scripts before processing further.
+  function bigPipeProcessDocument(context) {
+    // Make sure we have BigPipe-related scripts before processing further.
     if (!context.querySelector('script[data-big-pipe-event="start"]')) {
       return false;
     }
 
-    $(context).find('script[data-drupal-ajax-processor="big_pipe"]').once('big-pipe')
+    $(context).find('script[data-big-pipe-placeholder]')
+      .once('big-pipe')
       .each(bigPipeProcessPlaceholder);
 
-    // If we see a stop element always clear the timeout.
+    // If we see the stop signal, clear the timeout: all placeholder
+    // replacements are guaranteed to be received and processed.
     if (context.querySelector('script[data-big-pipe-event="stop"]')) {
       if (timeoutID) {
         clearTimeout(timeoutID);
@@ -68,7 +75,7 @@
 
   function bigPipeProcess() {
     timeoutID = setTimeout(function () {
-      if (!bigPipeProcessContainer(document)) {
+      if (!bigPipeProcessDocument(document)) {
         bigPipeProcess();
       }
     }, interval);
@@ -86,7 +93,7 @@
     if (timeoutID) {
       clearTimeout(timeoutID);
     }
-    bigPipeProcessContainer(document);
+    bigPipeProcessDocument(document);
   });
 
 })(jQuery, Drupal, drupalSettings);
diff --git a/src/Render/BigPipe.php b/src/Render/BigPipe.php
index abe8133..487e5a8 100644
--- a/src/Render/BigPipe.php
+++ b/src/Render/BigPipe.php
@@ -285,7 +285,7 @@ class BigPipe implements BigPipeInterface {
       return;
     }
 
-    // Send a container and the start signal.
+    // Send the start signal.
     print "\n";
     print '<script type="application/json" data-big-pipe-event="start"></script>' . "\n";
     flush();
@@ -338,7 +338,7 @@ class BigPipe implements BigPipeInterface {
       // Send this embedded AJAX response.
       $json = $ajax_response->getContent();
       $output = <<<EOF
-    <script type="application/json" data-big-pipe-placeholder="$placeholder" data-drupal-ajax-processor="big_pipe">
+    <script type="application/json" data-big-pipe-placeholder="$placeholder">
     $json
     </script>
 EOF;
