diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 12c50d8f86f1dbdc41d7db7a68fd37dff1322aa9..a375d807c25d18083144a77b5e67846368843cd0 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -610,6 +610,8 @@ $config = [
         // driver is not defined here, it will inherit configuration from a configured
         // parent class.  The defaultTab setting may be used to specify the default
         // active tab; if null, the value from the relevant .ini file will be used.
+        // You can also specify which tabs are loaded in the background when arriving
+        // at a record tabs view with backgroundLoadedTabs as a list of tab indexes.
         'recorddriver_tabs' => [
             'VuFind\RecordDriver\EDS' => [
                 'tabs' => [
@@ -654,6 +656,7 @@ $config = [
                     'Details' => 'StaffViewArray',
                 ],
                 'defaultTab' => null,
+                // 'backgroundLoadedTabs' => ['UserComments', 'Details']
             ],
             'VuFind\RecordDriver\SolrMarc' => [
                 'tabs' => [
diff --git a/module/VuFind/src/VuFind/Controller/AbstractBase.php b/module/VuFind/src/VuFind/Controller/AbstractBase.php
index 16b6701f572f65e6d55933c44b5d055ff048a3d5..5c9900cd4d983c49cec7fd9273f46b04f53ff630 100644
--- a/module/VuFind/src/VuFind/Controller/AbstractBase.php
+++ b/module/VuFind/src/VuFind/Controller/AbstractBase.php
@@ -637,4 +637,15 @@ class AbstractBase extends AbstractActionController
     {
         $this->followup()->clear('url');
     }
+
+    /**
+     * Get the tab configuration for this controller.
+     *
+     * @return array
+     */
+    protected function getRecordTabConfig()
+    {
+        $cfg = $this->getServiceLocator()->get('Config');
+        return $cfg['vufind']['recorddriver_tabs'];
+    }
 }
diff --git a/module/VuFind/src/VuFind/Controller/AbstractRecord.php b/module/VuFind/src/VuFind/Controller/AbstractRecord.php
index 317c6fd665795ab7ebd46109dbd589c2af5c0714..7ea90a10dba3ca1796b86e05966640ce39671f53 100644
--- a/module/VuFind/src/VuFind/Controller/AbstractRecord.php
+++ b/module/VuFind/src/VuFind/Controller/AbstractRecord.php
@@ -614,14 +614,15 @@ class AbstractRecord extends AbstractBase
     }
 
     /**
-     * Get the tab configuration for this controller.
+     * Alias to getRecordTabConfig for backward compatibility.
+     *
+     * @deprecated use getRecordTabConfig instead
      *
      * @return array
      */
     protected function getTabConfiguration()
     {
-        $cfg = $this->getServiceLocator()->get('Config');
-        return $cfg['vufind']['recorddriver_tabs'];
+        return $this->getRecordTabConfig();
     }
 
     /**
@@ -635,11 +636,14 @@ class AbstractRecord extends AbstractBase
         $request = $this->getRequest();
         $rtpm = $this->getServiceLocator()->get('VuFind\RecordTabPluginManager');
         $details = $rtpm->getTabDetailsForRecord(
-            $driver, $this->getTabConfiguration(), $request,
+            $driver, $this->getRecordTabConfig(), $request,
             $this->fallbackDefaultTab
         );
         $this->allTabs = $details['tabs'];
         $this->defaultTab = $details['default'] ? $details['default'] : false;
+        $this->backgroundTabs = $rtpm->getBackgroundTabNames(
+            $driver, $this->getRecordTabConfig()
+        );
     }
 
     /**
@@ -669,6 +673,19 @@ class AbstractRecord extends AbstractBase
         return $this->allTabs;
     }
 
+    /**
+     * Get names of tabs to be loaded in the background.
+     *
+     * @return array
+     */
+    protected function getBackgroundTabs()
+    {
+        if (null === $this->backgroundTabs) {
+            $this->loadTabDetails();
+        }
+        return $this->backgroundTabs;
+    }
+
     /**
      * Is the result scroller active?
      *
@@ -709,6 +726,7 @@ class AbstractRecord extends AbstractBase
         $view->tabs = $this->getAllTabs();
         $view->activeTab = strtolower($tab);
         $view->defaultTab = strtolower($this->getDefaultTab());
+        $view->backgroundTabs = $this->getBackgroundTabs();
         $view->loadInitialTabWithAjax
             = isset($config->Site->loadInitialTabWithAjax)
             ? (bool) $config->Site->loadInitialTabWithAjax : false;
diff --git a/module/VuFind/src/VuFind/Controller/AjaxController.php b/module/VuFind/src/VuFind/Controller/AjaxController.php
index 98c7b7f50d4406259e076cbc6c1bb023b725b8b2..af4244d91d1318d60d490e66ad2aad6efbfefa4f 100644
--- a/module/VuFind/src/VuFind/Controller/AjaxController.php
+++ b/module/VuFind/src/VuFind/Controller/AjaxController.php
@@ -796,6 +796,7 @@ class AjaxController extends AbstractBase
                 'Information'
             );
 
+        $rtpm = $this->getServiceLocator()->get('VuFind\RecordTabPluginManager');
         $html = $this->getViewRenderer()
             ->render(
                 "record/ajaxview-" . $viewtype . ".phtml",
@@ -803,6 +804,9 @@ class AjaxController extends AbstractBase
                     'defaultTab' => $details['default'],
                     'driver' => $driver,
                     'tabs' => $details['tabs'],
+                    'backgroundTabs' => $rtpm->getBackgroundTabNames(
+                        $driver, $this->getRecordTabConfig()
+                    )
                 ]
             );
         return $this->output($html, self::STATUS_OK);
diff --git a/module/VuFind/src/VuFind/Controller/CollectionController.php b/module/VuFind/src/VuFind/Controller/CollectionController.php
index 7b3e42f4ed9c72e199487c471687b1f6fb6065a0..a0233529ab007f335f498858b0d8b18f34dc4af9 100644
--- a/module/VuFind/src/VuFind/Controller/CollectionController.php
+++ b/module/VuFind/src/VuFind/Controller/CollectionController.php
@@ -59,7 +59,7 @@ class CollectionController extends AbstractRecord
      *
      * @return array
      */
-    protected function getTabConfiguration()
+    protected function getRecordTabConfig()
     {
         $cfg = $this->getServiceLocator()->get('Config');
         return $cfg['vufind']['recorddriver_collection_tabs'];
diff --git a/module/VuFind/src/VuFind/RecordTab/PluginManager.php b/module/VuFind/src/VuFind/RecordTab/PluginManager.php
index 514710b40bba9cd41e3e5d64a8caaca1b6063488..28792dafdbfb55e994fe7a4ec3914ecbced62863 100644
--- a/module/VuFind/src/VuFind/RecordTab/PluginManager.php
+++ b/module/VuFind/src/VuFind/RecordTab/PluginManager.php
@@ -95,6 +95,21 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager
         return $this->getConfigByClass($driver, $config, 'tabs', []);
     }
 
+    /**
+     * Get an array of tabs names configured to load via AJAX in the background
+     *
+     * @param AbstractRecordDriver $driver Record driver
+     * @param array                $config Tab configuration (associative array
+     * including 'tabs' array mapping driver class => tab service name)
+     *
+     * @return array
+     */
+    public function getBackgroundTabNames(AbstractRecordDriver $driver,
+        array $config
+    ) {
+        return $this->getConfigByClass($driver, $config, 'backgroundLoadedTabs', []);
+    }
+
     /**
      * Get a default tab by looking up the provided record driver in the tab
      * configuration array.
diff --git a/themes/bootstrap3/js/embedded_record.js b/themes/bootstrap3/js/embedded_record.js
index 51e7f0cb04bd783f9447df6509172d9535175a96..0d4eeb028ebe7cb7ec5e43508dadd1ce8a8346a9 100644
--- a/themes/bootstrap3/js/embedded_record.js
+++ b/themes/bootstrap3/js/embedded_record.js
@@ -157,6 +157,9 @@ VuFind.register('embedded', function embedded() {
                   );
                 }
               );
+              longNode.find('[data-background]').each(function setupEmbeddedBackgroundTabs(index, el) {
+                ajaxLoadTab(el.id, false);
+              });
               // Add events to record toolbar
               VuFind.lightbox.bind(longNode);
               if (typeof checkSaveStatuses == 'function') {
diff --git a/themes/bootstrap3/js/record.js b/themes/bootstrap3/js/record.js
index 863968bc504eef6184135ee680cd6af5988c498e..5df87a2e8cd9e3d27ef53b0a5b7069d45bdf22e2 100644
--- a/themes/bootstrap3/js/record.js
+++ b/themes/bootstrap3/js/record.js
@@ -231,6 +231,19 @@ function ajaxTagUpdate(_link, tag, _remove) {
   });
 }
 
+function getNewRecordTab(tabid) {
+  return $('<div class="tab-pane ' + tabid + '-tab"><i class="fa fa-spinner fa-spin" aria-hidden="true"></i> ' + VuFind.translate('loading') + '...</div>');
+}
+
+function backgroundLoadTab(tabid) {
+  if ($('.' + tabid + '-tab').length > 0) {
+    return;
+  }
+  var newTab = getNewRecordTab(tabid);
+  $('.nav-tabs a.'+tabid).closest('.result,.record').find('.tab-content').append(newTab);
+  return ajaxLoadTab(newTab, tabid, false);
+}
+
 function applyRecordTabHash() {
   var activeTab = $('.record-tabs li.active a').attr('class');
   var $initiallyActiveTab = $('.record-tabs li.initiallyActive a');
@@ -277,12 +290,16 @@ function recordDocReady() {
       window.location.hash = tabid;
       return false;
     } else {
-      var newTab = $('<div class="tab-pane active ' + tabid + '-tab"><i class="fa fa-spinner fa-spin" aria-hidden="true"></i> ' + VuFind.translate('loading') + '...</div>');
+      var newTab = getNewRecordTab(tabid).addClass('active');
       $top.find('.tab-content').append(newTab);
       return ajaxLoadTab(newTab, tabid, !$(this).parent().hasClass('initiallyActive'));
     }
   });
 
+  $('[data-background]').each(function setupBackgroundTabs(index, el) {
+    backgroundLoadTab(el.className);
+  });
+
   registerTabEvents();
   applyRecordTabHash();
 }
diff --git a/themes/bootstrap3/templates/collection/view.phtml b/themes/bootstrap3/templates/collection/view.phtml
index 640a86b41269d297dc656fa57f002d54aa271d66..08b328f6ff679b60ca91fe9a6cdd901506b3c866 100644
--- a/themes/bootstrap3/templates/collection/view.phtml
+++ b/themes/bootstrap3/templates/collection/view.phtml
@@ -62,14 +62,12 @@
 
 <?=$this->record($this->driver)->getToolbar()?>
 
-<div class="row">
+<div class="record row">
   <div class="<?=$tree ? 'col-sm-12' : $this->layoutClass('mainbody') ?>">
-    <div class="record">
-      <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" id="record_id" />
-      <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?>" class="hiddenSource" />
-      <?=$this->flashmessages()?>
-      <?=$this->record($this->driver)->getCollectionMetadata()?>
-    </div>
+    <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" id="record_id" />
+    <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?>" class="hiddenSource" />
+    <?=$this->flashmessages()?>
+    <?=$this->record($this->driver)->getCollectionMetadata()?>
 
     <? if (count($this->tabs) > 0): ?>
       <a name="tabnav"></a>
@@ -91,7 +89,7 @@
               if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; }
             ?>
             <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>>
-              <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"><?=$this->transEsc($desc)?></a>
+              <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>><?=$this->transEsc($desc)?></a>
             </li>
           <? endforeach; ?>
         </ul>
diff --git a/themes/bootstrap3/templates/record/ajaxview-accordion.phtml b/themes/bootstrap3/templates/record/ajaxview-accordion.phtml
index 71916a3a67661b4fa829a94e6b6d16e155b23787..150886392be963bd898b552655b03bcda093d236 100644
--- a/themes/bootstrap3/templates/record/ajaxview-accordion.phtml
+++ b/themes/bootstrap3/templates/record/ajaxview-accordion.phtml
@@ -75,7 +75,7 @@
         if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; }
       ?>
       <div class="panel panel-default <?=implode(' ', $tab_classes) ?>">
-        <div id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle panel-heading" data-toggle="collapse" data-parent="#accordion_<?=$idSuffix?>" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content">
+        <div id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle panel-heading" data-toggle="collapse" data-parent="#accordion_<?=$idSuffix?>" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>>
           <h4 class="panel-title">
             <a class="accordion-toggle" data-href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"><?=$desc ?></a>
           </h4>
diff --git a/themes/bootstrap3/templates/record/ajaxview-tabs.phtml b/themes/bootstrap3/templates/record/ajaxview-tabs.phtml
index 955095841b3a57b27915ae2c504a666d52724889..a995b43151542b2ef4e59c86ded443ba0405e5c0 100644
--- a/themes/bootstrap3/templates/record/ajaxview-tabs.phtml
+++ b/themes/bootstrap3/templates/record/ajaxview-tabs.phtml
@@ -43,7 +43,7 @@
       if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; }
     ?>
     <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>>
-      <a id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav" data-toggle="tab" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"><?=$this->transEsc($desc)?></a>
+      <a id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav" data-toggle="tab" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>><?=$this->transEsc($desc)?></a>
     </li>
   <? endforeach; ?>
 </ul>
diff --git a/themes/bootstrap3/templates/record/view.phtml b/themes/bootstrap3/templates/record/view.phtml
index 180eaeee6a81f39381ad8f9546b88724e4af6710..d17786fd5b43a7ddcd00221c1b919edda019ba75 100644
--- a/themes/bootstrap3/templates/record/view.phtml
+++ b/themes/bootstrap3/templates/record/view.phtml
@@ -56,14 +56,12 @@
 
 <?=$this->record($this->driver)->getToolbar()?>
 
-<div class="row">
+<div class="record source<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?> row">
   <div class="<?=$this->layoutClass('mainbody')?>">
-    <div class="record source<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?>">
-      <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" />
-      <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier()) ?>" class="hiddenSource" />
-      <?=$this->flashmessages()?>
-      <?=$this->record($this->driver)->getCoreMetadata()?>
-    </div>
+    <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" />
+    <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier()) ?>" class="hiddenSource" />
+    <?=$this->flashmessages()?>
+    <?=$this->record($this->driver)->getCoreMetadata()?>
 
     <? if (count($this->tabs) > 0): ?>
       <a name="tabnav"></a>
@@ -85,7 +83,7 @@
               if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; }
             ?>
             <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>>
-              <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"><?=$this->transEsc($desc)?></a>
+              <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>><?=$this->transEsc($desc)?></a>
             </li>
           <? endforeach; ?>
         </ul>