diff --git a/core/MAINTAINERS.txt b/core/MAINTAINERS.txt
index 63748c2..69802ff 100644
--- a/core/MAINTAINERS.txt
+++ b/core/MAINTAINERS.txt
@@ -261,6 +261,10 @@ Basic Auth module
- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
- Juampy Novillo Requena 'juampy' https://www.drupal.org/u/juampy
+BigPipe module
+- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
+- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
+
Block module
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
diff --git a/core/composer.json b/core/composer.json
index e8120c6..dbe1db9 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -48,6 +48,7 @@
"drupal/bartik": "self.version",
"drupal/ban": "self.version",
"drupal/basic_auth": "self.version",
+ "drupal/big_pipe": "self.version",
"drupal/block": "self.version",
"drupal/block_content": "self.version",
"drupal/book": "self.version",
diff --git a/core/modules/big_pipe/big_pipe.info.yml b/core/modules/big_pipe/big_pipe.info.yml
new file mode 100644
index 0000000..0108e1f
--- /dev/null
+++ b/core/modules/big_pipe/big_pipe.info.yml
@@ -0,0 +1,6 @@
+name: BigPipe
+type: module
+description: 'Sends pages in a way that allows browsers to show them much faster. Uses the BigPipe technique.'
+package: Core (Experimental)
+version: VERSION
+core: 8.x
diff --git a/core/modules/big_pipe/big_pipe.libraries.yml b/core/modules/big_pipe/big_pipe.libraries.yml
new file mode 100644
index 0000000..6da49b7
--- /dev/null
+++ b/core/modules/big_pipe/big_pipe.libraries.yml
@@ -0,0 +1,11 @@
+big_pipe:
+ version: VERSION
+ js:
+ js/big_pipe.js: {}
+ drupalSettings:
+ bigPipePlaceholderIds: []
+ dependencies:
+ - core/jquery
+ - core/jquery.once
+ - core/drupal.ajax
+ - core/drupalSettings
diff --git a/core/modules/big_pipe/big_pipe.module b/core/modules/big_pipe/big_pipe.module
new file mode 100644
index 0000000..1970c27
--- /dev/null
+++ b/core/modules/big_pipe/big_pipe.module
@@ -0,0 +1,66 @@
+' . t('About') . '';
+ $output .= '
' . t('The BigPipe module sends pages with dynamic content in a way that allows browsers to show them much faster. For more information, see the online documentation for the BigPipe module.', [':big_pipe-documentation' => 'https://www.drupal.org/documentation/modules/big_pipe']) . '
';
+ $output .= '' . t('Uses') . '
';
+ $output .= '';
+ $output .= '- ' . t('Speeding up your site') . '
';
+ $output .= '- ' . t('The module requires no configuration. Every part of the page contains metadata that allows BigPipe to figure this out on its own.') . '
';
+ $output .= '
';
+
+ return $output;
+ }
+}
+
+/**
+ * Implements hook_page_attachments().
+ *
+ * @see \Drupal\big_pipe\Controller\BigPipeController::setNoJsCookie()
+ */
+function big_pipe_page_attachments(array &$page) {
+ // Routes that don't use BigPipe also don't need no-JS detection.
+ if (\Drupal::routeMatch()->getRouteObject()->getOption('_no_big_pipe')) {
+ return;
+ }
+
+ $request = \Drupal::request();
+ // BigPipe is only used when there is an actual session, so only add the no-JS
+ // detection when there actually is a session.
+ // @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy.
+ $session_exists = \Drupal::service('session_configuration')->hasSession($request);
+ $page['#cache']['contexts'][] = 'session.exists';
+ // Only do the no-JS detection while we don't know if there's no JS support:
+ // avoid endless redirect loops.
+ $has_big_pipe_nojs_cookie = $request->cookies->has(BigPipeStrategy::NOJS_COOKIE);
+ $page['#cache']['contexts'][] = 'cookies:' . BigPipeStrategy::NOJS_COOKIE;
+ if ($session_exists && !$has_big_pipe_nojs_cookie) {
+ $page['#attached']['html_head'][] = [
+ [
+ // Redirect through a 'Refresh' meta tag if JavaScript is disabled.
+ '#tag' => 'meta',
+ '#noscript' => TRUE,
+ '#attributes' => [
+ 'http-equiv' => 'Refresh',
+ // @todo: Switch to Url::fromRoute() once https://www.drupal.org/node/2589967 is resolved.
+ 'content' => '0; URL=' . Url::fromUri('internal:/big_pipe/no-js', ['query' => \Drupal::service('redirect.destination')->getAsArray()])->toString(),
+ ],
+ ],
+ 'big_pipe_detect_nojs',
+ ];
+ }
+}
diff --git a/core/modules/big_pipe/big_pipe.routing.yml b/core/modules/big_pipe/big_pipe.routing.yml
new file mode 100644
index 0000000..c7981dc
--- /dev/null
+++ b/core/modules/big_pipe/big_pipe.routing.yml
@@ -0,0 +1,9 @@
+big_pipe.nojs:
+ path: '/big_pipe/no-js'
+ defaults:
+ _controller: '\Drupal\big_pipe\Controller\BigPipeController:setNoJsCookie'
+ _title: 'BigPipe no-JS check'
+ options:
+ no_cache: TRUE
+ requirements:
+ _access: 'TRUE'
diff --git a/core/modules/big_pipe/big_pipe.services.yml b/core/modules/big_pipe/big_pipe.services.yml
new file mode 100644
index 0000000..b06255a
--- /dev/null
+++ b/core/modules/big_pipe/big_pipe.services.yml
@@ -0,0 +1,25 @@
+services:
+ html_response.big_pipe_subscriber:
+ class: Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber
+ tags:
+ - { name: event_subscriber }
+ arguments: ['@big_pipe']
+ placeholder_strategy.big_pipe:
+ class: Drupal\big_pipe\Render\Placeholder\BigPipeStrategy
+ arguments: ['@session_configuration', '@request_stack', '@current_route_match']
+ tags:
+ - { name: placeholder_strategy, priority: 0 }
+ big_pipe:
+ class: Drupal\big_pipe\Render\BigPipe
+ arguments: ['@renderer', '@session', '@request_stack', '@http_kernel', '@event_dispatcher']
+ html_response.attachments_processor.big_pipe:
+ public: false
+ class: \Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor
+ decorates: html_response.attachments_processor
+ decoration_inner_name: html_response.attachments_processor.original
+ arguments: ['@html_response.attachments_processor.original', '@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler']
+
+ route_subscriber.no_big_pipe:
+ class: Drupal\big_pipe\EventSubscriber\NoBigPipeRouteAlterSubscriber
+ tags:
+ - { name: event_subscriber }
diff --git a/core/modules/big_pipe/js/big_pipe.js b/core/modules/big_pipe/js/big_pipe.js
new file mode 100644
index 0000000..41dbc67
--- /dev/null
+++ b/core/modules/big_pipe/js/big_pipe.js
@@ -0,0 +1,107 @@
+/**
+ * @file
+ * Renders BigPipe placeholders using Drupal's Ajax system.
+ */
+
+(function ($, Drupal, drupalSettings) {
+
+ 'use strict';
+
+ /**
+ * Executes Ajax commands in ' . "\n";
+ flush();
+
+ // A BigPipe response consists of a HTML response plus multiple embedded
+ // AJAX responses. To process the attachments of those AJAX responses, we
+ // need a fake request that is identical to the master request, but with
+ // one change: it must have the right Accept header, otherwise the work-
+ // around for a bug in IE9 will cause not JSON, but