diff --git a/core/modules/block/block.services.yml b/core/modules/block/block.services.yml
index df4d0d7..7ba57c2 100644
--- a/core/modules/block/block.services.yml
+++ b/core/modules/block/block.services.yml
@@ -24,4 +24,4 @@ services:
       - { name: 'event_subscriber' }
   block.repository:
     class: Drupal\block\BlockRepository
-    arguments: ['@entity.manager', '@theme.manager', '@context.handler']
+    arguments: ['@entity.manager', '@theme.manager', '@context.handler', '@cache.data']
diff --git a/core/modules/block/src/BlockRepository.php b/core/modules/block/src/BlockRepository.php
index 485a66f..0b420ab 100644
--- a/core/modules/block/src/BlockRepository.php
+++ b/core/modules/block/src/BlockRepository.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Plugin\Context\ContextHandlerInterface;
 use Drupal\Core\Theme\ThemeManagerInterface;
+use Drupal\Core\Cache\CacheBackendInterface;
 
 /**
  * Provides a repository for Block config entities.
@@ -31,6 +32,12 @@ class BlockRepository implements BlockRepositoryInterface {
   protected $themeManager;
 
   /**
+   * The cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+
+  /**
    * Constructs a new BlockRepository.
    *
    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
@@ -40,10 +47,11 @@ class BlockRepository implements BlockRepositoryInterface {
    * @param \Drupal\Core\Plugin\Context\ContextHandlerInterface $context_handler
    *   The plugin context handler.
    */
-  public function __construct(EntityManagerInterface $entity_manager, ThemeManagerInterface $theme_manager, ContextHandlerInterface $context_handler) {
+  public function __construct(EntityManagerInterface $entity_manager, ThemeManagerInterface $theme_manager, ContextHandlerInterface $context_handler, CacheBackendInterface $cache_backend) {
     $this->blockStorage = $entity_manager->getStorage('block');
     $this->themeManager = $theme_manager;
     $this->contextHandler = $context_handler;
+    $this->cacheBackend = $cache_backend;
   }
 
   /**
@@ -74,7 +82,17 @@ public function getVisibleBlocksPerRegion(array $contexts) {
     $empty = array_fill_keys(array_keys($this->getRegionNames()), array());
 
     $full = array();
-    foreach ($this->blockStorage->loadByProperties(array('theme' => $this->getTheme())) as $block_id => $block) {
+    $cid = 'block_list:' . $this->getTheme();
+    $cached = $this->cacheBackend->get($cid);
+    if ($cached) {
+      $blocks = $cached->data;
+    }
+    else {
+      $blocks = $this->blockStorage->loadByProperties(array('theme' => $this->getTheme()));
+      // @todo: cache tags.
+      $this->cacheBackend->set($cid, $blocks);
+    }
+    foreach ($blocks as $block_id => $block) {
       /** @var \Drupal\block\BlockInterface $block */
       // Set the contexts on the block before checking access.
       if ($block->setContexts($contexts)->access('view')) {
