diff --git a/VERSIONS_HOTLINE/115306 b/VERSIONS_HOTLINE/115306
new file mode 100644
index 0000000000000000000000000000000000000000..48c911d953c2b10cf33dcbaf95d8c32e1e9238fe
--- /dev/null
+++ b/VERSIONS_HOTLINE/115306
@@ -0,0 +1 @@
+ - ticket #115306 : Magasin de thèmes : amélioration de la performance d'affichage de la page mon compte / mes prêts 
\ No newline at end of file
diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php
index 0d2107e3ed413981c04c00bec2912d40870f4e10..67f8a67ad7befe97d5bd66bcd56f5876a45d501a 100644
--- a/application/modules/opac/controllers/AbonneController.php
+++ b/application/modules/opac/controllers/AbonneController.php
@@ -65,12 +65,12 @@ class AbonneController extends ZendAfi_Controller_Action {
 
 
   protected function clearEmprunteurCache() {
+    $no_cache_actions = Class_Template::current()->isLegacy()
+      ? ['prets', 'reservations', 'fiche', 'loans-history', 'ajax-loans', 'suggestions']
+      : ['fiche', 'loans-history', 'ajax-loans', 'suggestions'];
+
     if (!in_array($this->getRequest()->getActionName(),
-                  ['prets',
-                   'reservations',
-                   'fiche',
-                   'loans-history',
-                   'suggestions']))
+                  $no_cache_actions))
       return;
 
     foreach((new Class_User_Cards($this->_user)) as $user)
@@ -428,17 +428,7 @@ class AbonneController extends ZendAfi_Controller_Action {
                                                      'start_issue_date' => $this->_getPost('start_issue_date'),
                                                      'end_issue_date' => $this->_getPost('end_issue_date')]);
 
-    $cards = new Class_User_Cards($this->_user);
-    $loans = $cards->getLoansWithOutPNB($this->_request->getParams());
-    $fiche = $this->_user->getFicheSigb();
-    $error = (isset($fiche['error']) && $fiche['error'])
-      ? $fiche['error']
-      : '';
-
-    $this->view->config = new Class_Entity(['Loans' => $loans,
-                                            'RenewableLoansIds' => $cards->getRenewableLoansIds($loans),
-                                            'User' => $this->_user,
-                                            'Error' => $error,
+    $this->view->config = new Class_Entity(['User' => $this->_user,
                                             'Profile' => Class_Profil::getCurrentProfil(),
                                             'RequestParams' => $this->_request->getParams()]);
   }
@@ -492,6 +482,8 @@ class AbonneController extends ZendAfi_Controller_Action {
   }
 
 
+
+
   public function reservationsAction()  {
     $cards = new Class_User_Cards($this->_user);
 
@@ -1949,7 +1941,6 @@ class AbonneController extends ZendAfi_Controller_Action {
     $callback = function() {
       return $this->view->abonne_AjaxLoans($this->_user);
     };
-
     return $this->_helper->ajax($callback);
   }
 
diff --git a/library/Class/Feature/List.php b/library/Class/Feature/List.php
index 797e86001e596b88b0f35c67f2d684221c9c6cf4..dd12f3fade1f9e9660d8dfbf6263fb9d50319713 100644
--- a/library/Class/Feature/List.php
+++ b/library/Class/Feature/List.php
@@ -890,7 +890,7 @@ class Class_Feature_List {
             ['Label' => $this->_('Géolocalisation des documents sur carte'),
              'Desc' => $this->_('Les boîtes kiosques de notices et articles permettent d\'afficher les documents géolocalisés sur une carte interactive'),
              'Image' => '',
-             'Video' => 'https://www.youtube.com/watch?v=_zkNqHzQ1m4',
+             'Video' => 'https://www.youtube.com/watch?v=jGF26Qmrnsk',
              'Category' => $this->_('Mise en page'),
              'Right' => function($feature_description, $user) {return true;},
              'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=G%C3%A9olocalisation_de_contenu',
diff --git a/library/Class/WebService/SIGB/AbstractRESTService.php b/library/Class/WebService/SIGB/AbstractRESTService.php
index 0d375d229d2c4442e3a671235a14825d92f2b1f9..6c8b03fdb6f4100ded19771daadf4c3d84e30d4a 100644
--- a/library/Class/WebService/SIGB/AbstractRESTService.php
+++ b/library/Class/WebService/SIGB/AbstractRESTService.php
@@ -218,10 +218,10 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
     $xml = $this->httpGet($params);
 
     if (0 === strpos($xml, '<html>'))
-      return $emprunteur;
+      return null;
 
     if ($this->_getTagData($xml, $error_tag))
-      return $emprunteur;
+      return null;
 
     return $reader
       ->setEmprunteur(Class_WebService_SIGB_Emprunteur::nullInstance())
diff --git a/library/Class/WebService/SIGB/Koha/LoansPageReader.php b/library/Class/WebService/SIGB/Koha/LoansPageReader.php
index 1c041690f00e613b25061f5c725834f34b066749..909d32bd732a78161505ebdb6c8e100c13d792ff 100644
--- a/library/Class/WebService/SIGB/Koha/LoansPageReader.php
+++ b/library/Class/WebService/SIGB/Koha/LoansPageReader.php
@@ -32,12 +32,12 @@ class Class_WebService_SIGB_Koha_LoansPageReader
   }
 
 
-  public function endLoans() {
+  public function endLoans($data) {
     //intentionnaly do nothing
   }
 
 
-  public function endLoan() {
+  public function endLoan($data) {
     $this->_loans [] = $this->_currentLoan;
   }
 
diff --git a/library/ZendAfi/View/Helper/Abonne/LoansBoard.php b/library/ZendAfi/View/Helper/Abonne/LoansBoard.php
index 808a57bb8cb7bfc15bfd078291f22bcf8f400970..35bc60e6b7312432c57351d76c7ff5d476bbf082 100644
--- a/library/ZendAfi/View/Helper/Abonne/LoansBoard.php
+++ b/library/ZendAfi/View/Helper/Abonne/LoansBoard.php
@@ -26,51 +26,88 @@ class ZendAfi_View_Helper_Abonne_LoansBoard extends ZendAfi_View_Helper_BaseHelp
     $_config,
     $_extend_all,
     $_preferences,
-    $_profile;
+    $_loans,
+    $_renewable_loans;
+
+
+  public function init() {
+    $this->_preferences = new Class_Profil_Preferences_Loans();
+  }
 
 
   public function abonne_LoansBoard($config) {
     $this->_config = $config;
-    $loans = $config->getLoans();
-    $renewable_loans = $config->getRenewableLoansIds();
-    $user = $config->getUser();
-    $this->_profile = $profile = $config->getProfile();
-    $error = $config->getError();
-    $request_params = $config->getRequestParams();
-    $this->_preferences = $preferences = new Class_Profil_Preferences_Loans();
-
-    $html = [$this->view->openBoiteContent($this->_('Prêts en cours'))];
-
-    if($error) {
-      $html [] = $this->_tag('p', $error, ['class' => 'error']);
-      $html [] = $this->view->closeBoiteContent();
-      $html [] = $this->view->abonne_RetourFiche();
-      return implode($html);
-    }
-
-    $extend_all = $renewable_loans
+
+    return
+      $this
+      ->_readConfig($config)
+      ->_renderHTML();
+  }
+
+
+  protected function _readConfig($config) {
+    $cards = new Class_User_Cards($config->getUser());
+    $this->_loans = $cards->getLoansWithOutPNB($config->getRequestParams());
+    $this->_renewable_loans = $cards->getRenewableLoansIds($this->_loans);
+    return $this;
+  }
+
+
+  protected function _renderHTML() {
+    $content = ($error = $this->_getError())
+      ? $this->_renderError($error)
+      : $this->_renderLoans();
+
+    return
+      $this->view->openBoiteContent($this->_('Prêts en cours'))
+      . $content
+      . $this->view->closeBoiteContent()
+      . $this->view->abonne_RetourFiche();
+  }
+
+
+  protected function _renderError($error) {
+    return $this->_tag('p', $error, ['class' => 'error']);
+  }
+
+
+  protected function _renderLoans() {
+    $html = [];
+    $html [] = $this->_tag('div',
+                           $this->_config->getUser()->getNomAff(),
+                           ['class' => 'abonneTitre']);
+    $html [] = $this->_renderTools();
+    $html [] = $this->view->abonne_Loans($this->_loans);
+    $html [] = $this->_renderRenewAllLoansAction();
+    $html [] = $this->_renderPNB();
+    return implode(array_filter($html));
+  }
+
+
+  protected function _renderRenewAllLoansAction() {
+    return  $this->_renewable_loans
       ? ($this->view->tagAnchor(['action' => 'prolongerPret',
-                                 'id_pret' => $renewable_loans],
+                                 'id_pret' => $this->_renewable_loans],
                                 $this->_('Tout prolonger'),
                                 ['class' => 'extend_all']))
       : '';
+  }
+
 
-    $pnb = ($user->hasPNB())
+  protected function _renderPNB() {
+    $user = $this->_config->getUser();
+    return ($user->hasPNB())
       ? ($this->_tag('h2', $this->_('Prêts numériques en cours'))
          . $this->view->abonne_LoansPNB($user->getPNBLoans()))
       : '';
+  }
 
-    $html [] = $this->_tag('div',
-                            $user->getNomAff(),
-                           ['class' => 'abonneTitre']);
-    $html [] = $this->_renderTools();
-    $html [] = $this->view->abonne_Loans($loans);
-    $html [] = $this->_extend_all;
-    $html [] = $pnb;
-    $html [] = $this->view->closeBoiteContent();
-    $html [] = $this->view->abonne_RetourFiche();
 
-    return implode(array_filter($html));
+  protected function _getError() {
+    $fiche = $this->_config->getUser()->getFicheSigb();
+    $error = (isset($fiche['error']) && $fiche['error'])
+      ? $fiche['error']
+      : '';
   }
 
 
@@ -80,12 +117,12 @@ class ZendAfi_View_Helper_Abonne_LoansBoard extends ZendAfi_View_Helper_BaseHelp
 
 
   public function getLoans() {
-    return $this->_config->getLoans();
+    return $this->_loans;
   }
 
 
   public function getRenewableLoans  () {
-    return $this->_config->getRenewableLoansIds();
+    return $this->_renewable_loans;
   }
 
 
@@ -96,7 +133,7 @@ class ZendAfi_View_Helper_Abonne_LoansBoard extends ZendAfi_View_Helper_BaseHelp
 
   protected function _renderTools() {
     $tools = [];
-    $composition = $this->_preferences->getToolsCompositionOf($this->_profile);
+    $composition = $this->_preferences->getToolsCompositionOf($this->_config->getProfile());
     $selected_tools = $composition->getSelected();
     foreach($selected_tools as $tool)
       $tools [] = $tool->renderWith($this);
diff --git a/library/ZendAfi/View/Helper/Abonne/LoansHistory.php b/library/ZendAfi/View/Helper/Abonne/LoansHistory.php
index 51b8087980773fc78a7e59ece72970e20017c8e6..9caed76d3db0c814a64aff4dc57e1dde25665643 100644
--- a/library/ZendAfi/View/Helper/Abonne/LoansHistory.php
+++ b/library/ZendAfi/View/Helper/Abonne/LoansHistory.php
@@ -24,7 +24,7 @@ class ZendAfi_View_Helper_Abonne_LoansHistory extends ZendAfi_View_Helper_Abonne
   protected $_paginator;
 
   public function abonne_LoansHistory($loans) {
-    if($loans->isEmpty()
+    if(!$loans || $loans->isEmpty()
        || (!$description = $this->_getDescription()))
       return $this->_tag('p', $this->_('Pas de prêts dans l\'historique'), ['class' => 'error']);
 
diff --git a/library/ZendAfi/View/Helper/Abonne/LoansHistoryBoard.php b/library/ZendAfi/View/Helper/Abonne/LoansHistoryBoard.php
index ffeee07507f2a71eb8c8a7cf6a64becbf188acb0..703842c75177591b98e86552566cfba0f19a9027 100644
--- a/library/ZendAfi/View/Helper/Abonne/LoansHistoryBoard.php
+++ b/library/ZendAfi/View/Helper/Abonne/LoansHistoryBoard.php
@@ -21,26 +21,47 @@
 
 
 class ZendAfi_View_Helper_Abonne_LoansHistoryBoard extends ZendAfi_View_Helper_Abonne_LoansBoard {
+  public function init() {
+    $this->_preferences = new Class_Profil_Preferences_LoansHistory();
+  }
+
 
   public function abonne_LoansHistoryBoard($config) {
-    $this->_config = $config;
-    $loans = $config->getLoans();
-    $user = $config->getUser();
-    $this->_profile = $profile = $config->getProfile();
-    $error = $config->getError();
-    $request_params = $config->getRequestParams();
-    $this->_preferences = $preferences = new Class_Profil_Preferences_LoansHistory();
+    return parent::abonne_LoansBoard($config);
+  }
+
+
+  protected function _renderError($error) {
+    return $this->_tag('div', $error, ['class' => 'error']);
+  }
+
+
+  protected function _readConfig($config) {
+    $this->_loans = $config->getLoans();
+    return $this;
+  }
+
+
+  protected function _getError() {
+    return $this->_config->getError();
+  }
+
+
+  protected function _renderHTML() {
+    return ($error = $this->_getError())
+      ? $this->_renderError($error)
+      : $this->_renderLoans();
+  }
 
-    if($error)
-      return $this->_tag('div', $error, ['class' => 'error']);
 
+  protected function _renderLoans() {
     $content = [$this->_tag('div',
-                            $user->getNomAff(),
+                            $this->_config->getUser()->getNomAff(),
                             ['class' => 'abonneTitre']),
 
                 $this->_renderTools(),
 
-                $this->view->abonne_LoansHistory($loans)];
+                $this->view->abonne_LoansHistory($this->_loans)];
 
     return implode(array_filter($content));
   }
diff --git a/library/storm b/library/storm
index 2b5c85fe5664378b8405e5dc235a624f7f34e836..49099cb341a0f6f4e8b95cbfc34d928289a10bd0 160000
--- a/library/storm
+++ b/library/storm
@@ -1 +1 @@
-Subproject commit 2b5c85fe5664378b8405e5dc235a624f7f34e836
+Subproject commit 49099cb341a0f6f4e8b95cbfc34d928289a10bd0
diff --git a/library/templates/Intonation/Assets/css/intonation.css b/library/templates/Intonation/Assets/css/intonation.css
index 535ecece06411af8d8edae55e1d99fcf50228fa2..1a7f5c0082feac7c9e28e4861fead3656102e27e 100644
--- a/library/templates/Intonation/Assets/css/intonation.css
+++ b/library/templates/Intonation/Assets/css/intonation.css
@@ -886,4 +886,10 @@ input[id^="select_record"] + * {
 
 .added_to_selection .card-img-overlay .add_to_selection_link::before {
     color: var(--success);
-}
\ No newline at end of file
+}
+
+.loading_icon {
+    border-radius: 50% !important;
+    border: .25em solid currentColor !important;
+    border-right-color: transparent !important;
+}
diff --git a/library/templates/Intonation/Library/Settings.php b/library/templates/Intonation/Library/Settings.php
index 8407009ca8b7b533bcd780614f2fe4daa350e19f..06ad93418791d984dc2dc14647bb718334e17fea 100644
--- a/library/templates/Intonation/Library/Settings.php
+++ b/library/templates/Intonation/Library/Settings.php
@@ -228,6 +228,7 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                                                   'div class zoom_cardify_img' => 'col-6 p-3 order-1',
                                                   'div class zoom_cardify_content' => 'col-6 col-sm-3 p-3 order-2',
                                                   'div class zoom_cardify_actions' => 'col-12 col-sm-3 p-3 order-3',
+                                                  'div class loading_icon' => 'spinner-border'
                           ],
 
                           'icons_map_doc_types' => [],
@@ -235,6 +236,7 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                           'icons_map_library' => ['author' => 'class fas fa-user',
                                                   'search_more' => 'class fas fa-list',
                                                   'library' => 'class fas fa-landmark',
+                                                  'history' => 'class fas fa-history',
                                                   'available' => 'class far fa-check-circle',
                                                   'not-available' => 'class far fa-times-circle',
                                                   'readed' => 'class fas fa-check-circle text-success',
diff --git a/library/templates/Intonation/Library/View/Wrapper/Record.php b/library/templates/Intonation/Library/View/Wrapper/Record.php
index a124e9424a5eca3b2105d9fc9070f3b6a354f018..0639b1b10b54026ddd3c75cd4aa0a592b2a4bba5 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Record.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Record.php
@@ -295,7 +295,8 @@ class Intonation_Library_View_Wrapper_Record extends Intonation_Library_View_Wra
                          },
                          ['RecordProReviewsbadge',
                           'RecordUsersReviewsbadge',
-                          'RecordCommunityReviewsbadge']);
+                          // 'RecordCommunityReviewsbadge' too slow
+                         ]);
 
     return (new Storm_Collection($sources))
       ->injectInto($badges,
diff --git a/library/templates/Intonation/Library/View/Wrapper/RichContent/Section.php b/library/templates/Intonation/Library/View/Wrapper/RichContent/Section.php
index 4687897f7e1f59c9e6eb3560c4a112696e2cedbf..39b1b2864ff0df25848ae011d581ebf66da541a2 100644
--- a/library/templates/Intonation/Library/View/Wrapper/RichContent/Section.php
+++ b/library/templates/Intonation/Library/View/Wrapper/RichContent/Section.php
@@ -144,7 +144,7 @@ abstract class Intonation_Library_View_Wrapper_RichContent_Section {
 
 
   protected function _getJsCallback() {
-    return sprintf("if ($('.%s .jumbotron_section_content [data-ajax-content] > *').length) $('.%s').removeClass('d-none text-black-50 disabled');",
+    return sprintf("if ($('.%s .jumbotron_section_content [data-ajax-content] > *').length) { $('.%s').removeClass('d-none text-black-50 disabled'); $('.loading_icon').parent().remove(); }",
                    $this->getClass(),
                    $this->getClass());
   }
diff --git a/library/templates/Intonation/Library/View/Wrapper/User/RichContent/LoansHistory.php b/library/templates/Intonation/Library/View/Wrapper/User/RichContent/LoansHistory.php
new file mode 100644
index 0000000000000000000000000000000000000000..5dbc57284a00b53bc5ea0e22488e66c385518da7
--- /dev/null
+++ b/library/templates/Intonation/Library/View/Wrapper/User/RichContent/LoansHistory.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Intonation_Library_View_Wrapper_User_RichContent_LoansHistory extends Intonation_Library_View_Wrapper_User_RichContent_Loans {
+
+  protected $_is_visible = false;
+
+
+  public function getTitle() {
+    return $this->_('Mon historique de prêts');
+  }
+
+
+  public function getContent() {
+    if ($this->_content)
+      return $this->_content;
+
+    return $this->_content = $this->_view->renderAjax('abonne',
+                                                      'ajax-loans',
+                                                      ['id' => $this->_model->getId(),
+                                                      'history' => 1],
+                                                      $this->_getJsCallback());
+  }
+
+
+  public function getNavIco() {
+    return 'class fas fa-book';
+  }
+
+
+  public function getNavTitle() {
+    return $this->_('Mon historique de prêts');
+  }
+}
diff --git a/library/templates/Intonation/View/Abonne/AjaxLoans.php b/library/templates/Intonation/View/Abonne/AjaxLoans.php
index b89e4c5bd60178f8e15dea1f5d6d5be2a78b6fd0..d3823d7bdbc1b401a701dd923bd25654f27a6a19 100644
--- a/library/templates/Intonation/View/Abonne/AjaxLoans.php
+++ b/library/templates/Intonation/View/Abonne/AjaxLoans.php
@@ -30,10 +30,8 @@ class Intonation_View_Abonne_AjaxLoans extends ZendAfi_View_Helper_BaseHelper {
       return '';
 
     $this->_model = $user;
-
     $cards = new Class_User_Cards($this->_model);
     $loans = $cards->getLoansWithOutPNB([]);;
-
     $fiche = $this->_model->getFicheSigb();
     $error = (isset($fiche['error']) && $fiche['error'])
       ? $fiche['error']
diff --git a/library/templates/Intonation/View/Abonne/AjaxLoansHistory.php b/library/templates/Intonation/View/Abonne/AjaxLoansHistory.php
new file mode 100644
index 0000000000000000000000000000000000000000..359d1977610f5c22323a74bd0ee905d731a49e57
--- /dev/null
+++ b/library/templates/Intonation/View/Abonne/AjaxLoansHistory.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Intonation_View_Abonne_AjaxLoansHistory extends ZendAfi_View_Helper_BaseHelper {
+
+  protected $_model, $_ajax = true;
+
+
+  public function abonne_AjaxLoansHistory($config) {
+    if (! $user = $config->getUser())
+      return '';
+
+    $this->_model = $user;
+
+    $cards = new Class_User_Cards($this->_model);
+    $fiche = $this->_model->getFicheSigb();
+
+    $loans = $cards->getLoansHistory();
+    $error = (isset($fiche['error']) && $fiche['error'])
+      ? $fiche['error']
+      : '';
+
+    return $this->_getContent((new Class_Entity(['Cards' => $cards,
+                                                 'User' => $this->_model,
+                                                 'Error' => $error,
+                                                 'Loans' => $loans,
+                                                 'Profile' => Class_Profil::getCurrentProfil(),
+                                                 'RequestParams' => $config->getRequestParams()])));
+  }
+
+
+  protected function _getContent($settings) {
+    $cards = $settings->getCards();
+    $history = $this->view->abonne_LoansHistoryList($settings);
+
+    $html = [];
+
+    $html [] = $this->view->div(['class' => 'col-12'],
+                                $history);
+
+    return $this->view->grid(implode($html));
+  }
+}
\ No newline at end of file
diff --git a/library/templates/Intonation/View/Abonne/LoansBoard.php b/library/templates/Intonation/View/Abonne/LoansBoard.php
index db42c9ad69db3622359f78ba3f2eb442eae9abb0..945e60900913508a2fe606f8abafb8d8004f99ad 100644
--- a/library/templates/Intonation/View/Abonne/LoansBoard.php
+++ b/library/templates/Intonation/View/Abonne/LoansBoard.php
@@ -22,10 +22,29 @@
 
 class Intonation_View_Abonne_LoansBoard extends Intonation_View_Abonne {
 
-  protected $_show_current_section = 'user_loans';
+  protected $_show_current_section = 'user_loans', $_config;
 
 
   public function abonne_LoansBoard($config) {
-    return $this->_renderSection($config->getUser());
+    $this->_config = $config;
+
+
+    return $this->_renderSection($this->_config->getUser());
+  }
+
+  protected function _hookOn($rich_content) {
+    if (!isset($this->_config->getRequestParams()['history']))
+      return;
+
+    $sections = $rich_content->getSections();
+
+    $sections [Intonation_Library_View_Wrapper_User_RichContent::LOANS] = (new Intonation_Library_View_Wrapper_User_RichContent_LoansHistory)
+      ->setModel($this->view->user)
+      ->setView($this->view)
+      ->beActive()
+      ->beVisible();
+
+    $rich_content->setSections($sections);
   }
+
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/View/Abonne/LoansHistoryList.php b/library/templates/Intonation/View/Abonne/LoansHistoryList.php
new file mode 100644
index 0000000000000000000000000000000000000000..235460e8117255e7b7a4f2654490dbcce4ea8fda
--- /dev/null
+++ b/library/templates/Intonation/View/Abonne/LoansHistoryList.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Intonation_View_Abonne_LoansHistoryList extends Intonation_View_Abonne_LoansList   {
+  protected $_config;
+
+  public function abonne_LoansHistoryList($config) {
+    return $this->abonne_LoansList($config);
+  }
+
+
+  protected function _getActions() {
+    return [ new Intonation_Library_Link(['Url' => ['controller' => 'abonne',
+                                                    'action' => 'prets',
+                                                    'history' => null
+                                                      ],
+                                          'Text' =>  $this->_('Mes prêts'),
+                                          'Title' => $this->_('Voir mes prêts'),
+                                          'Image' => Class_Template::current()->getIco($this->view,
+                                                                                            'loan',
+                                                                                       'library')]) ];
+  }
+}
diff --git a/library/templates/Intonation/View/Abonne/LoansList.php b/library/templates/Intonation/View/Abonne/LoansList.php
index 2ddcf179789ce89e8a76a7747bdf17140bdf70c6..ba4141bd734a48d734633270fba277827783c3ca 100644
--- a/library/templates/Intonation/View/Abonne/LoansList.php
+++ b/library/templates/Intonation/View/Abonne/LoansList.php
@@ -45,6 +45,13 @@ class Intonation_View_Abonne_LoansList extends ZendAfi_View_Helper_BaseHelper {
     if (!$loans)
       return '';
 
+    $actions = $this->_getActions();
+
+    return $this->view->renderCollection(new Storm_Collection($loans), $actions);
+  }
+
+
+  protected function _getActions() {
     $actions = [];
 
     if ($this->_config->getExtendAll())
@@ -56,7 +63,6 @@ class Intonation_View_Abonne_LoansList extends ZendAfi_View_Helper_BaseHelper {
                                                  'Image' => Class_Template::current()->getIco($this->view,
                                                                                               'extend-loan',
                                                                                               'library')]);
-
-    return $this->view->renderCollection(new Storm_Collection($loans), $actions);
+    return $actions;
   }
 }
diff --git a/library/templates/Intonation/View/Jumbotron.php b/library/templates/Intonation/View/Jumbotron.php
index c06fd03c74484fc39d22a202aa653b9eb719beed..2ffb254249b9c1adc913b305a40f943afe2ccc01 100644
--- a/library/templates/Intonation/View/Jumbotron.php
+++ b/library/templates/Intonation/View/Jumbotron.php
@@ -207,13 +207,25 @@ class Intonation_View_Jumbotron extends ZendAfi_View_Helper_BaseHelper {
                           $class,
                           $element->getActiveClass());
 
-    return
-      $this->_div(['class' => $classes],
-                  $this->_tag('h2',
-                              Class_Template::current()->getIco($this->view, $element->getDBNavIco())
-                              . $this->view->tag('span', $element->getDBTitle()),
-                              ['class' => 'jumbotron_section_title'])
-                  . $this->view->div(['class' => 'jumbotron_section_content'],
-                                      $element->getContent()));
+
+
+    $content = $this->_div(['class' => $classes],
+                           $this->_tag('h2',
+                                       Class_Template::current()->getIco($this->view, $element->getDBNavIco())
+                                       . $this->view->tag('span', $element->getDBTitle()),
+                                       ['class' => 'jumbotron_section_title'])
+                           . $this->view->div(['class' => 'jumbotron_section_content'],
+                                              $element->getContent()));
+
+    return ($element->isAjax())
+      ? ($this->_renderLoadingIcon() . $content)
+      : $content;
+  }
+
+
+  protected function _renderLoadingIcon() {
+    return $this->_div(['class' => 'col-12 text-center'],
+                       $this->_div(['class' => 'loading_icon'],
+                                   ''));
   }
 }
diff --git a/library/templates/Intonation/View/RenderAjax.php b/library/templates/Intonation/View/RenderAjax.php
index 4fe7e77f7804791a6af7fbbec001079c7a6083bc..d5ad9985812a8e7cf0061c3b1a6e32fd829450c1 100644
--- a/library/templates/Intonation/View/RenderAjax.php
+++ b/library/templates/Intonation/View/RenderAjax.php
@@ -36,7 +36,7 @@ class Intonation_View_RenderAjax extends ZendAfi_View_Helper_BaseHelper {
 
     return $this->_div(['id' => $id,
                         'data-ajax-content' => 1,
-                        'class' => 'col-12 mb-3 p-0 ' . $action],
+                        'class' => 'spinner col-12 mb-3 p-0 ' . $action],
                        '');
   }
 }
diff --git a/tests/scenarios/Activitypub/ActivitypubReviewTest.php b/tests/scenarios/Activitypub/ActivitypubReviewTest.php
index aed35b6729d784ba00637a9cec798d285a18a6d4..7921d74879f1b6126e2c3a4be1c8441c703bdd1a 100644
--- a/tests/scenarios/Activitypub/ActivitypubReviewTest.php
+++ b/tests/scenarios/Activitypub/ActivitypubReviewTest.php
@@ -1375,7 +1375,9 @@ class ActivitypubReviewTemplateIntonationRecordReviewsTest extends AbstractContr
   }
 
 
-  /** @test */
+  /** @disabledtest
+   *  federated reviews badges disabled as too slow.
+   */
   public function badgesShouldContainsSixteenFederationReview() {
     $this->assertXPathContentContains('//span[contains(@class, "badge")]', '16 avis commu.');
   }
diff --git a/tests/scenarios/Templates/TemplatesTest.php b/tests/scenarios/Templates/TemplatesTest.php
index 5d4aba8a0f3b290a5cf3688868d211c161fa7140..ab30bcb6819b49dce594dbc5423234dcb27febde 100644
--- a/tests/scenarios/Templates/TemplatesTest.php
+++ b/tests/scenarios/Templates/TemplatesTest.php
@@ -2030,6 +2030,7 @@ class TemplatesDispatchIntonationSearchListFormatWallTest extends TemplatesInton
 
 
 abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTestCase {
+  protected $_mock_emprunts, $_emprunteur;
 
   public function setUp() {
     parent::setUp();
@@ -2131,8 +2132,9 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
                               'libelle' => 'Istres',
                               'id_origine' => 'IST']);
 
-    $emprunteur = new Class_WebService_SIGB_Emprunteur('1234', 'Florence');
-    $emprunteur
+
+    $this->_emprunteur = new Class_WebService_SIGB_Emprunteur('1234', 'Florence');
+    $this->_emprunteur
       ->setLibraryCode('IST')
       ->empruntsAddAll([$potter, $alice])
       ->reservationsAddAll([$dobby]);
@@ -2143,7 +2145,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
       ->setIdabon(123456)
       ->setDateFin('2020/01/01')
       ->setFicheSigb(['type_comm' => 2,
-                      'fiche' => $emprunteur,
+                      'fiche' => $this->_emprunteur,
                       'erreur' => ''])
       ->setPseudo('Paul')
       ->beAbonneSIGB();
@@ -2401,28 +2403,31 @@ class TemplatesDispatchAbonneInformationsTest extends TemplatesIntonationAccount
 
 
 
+
 class TemplatesDispatchAbonneLoansTest extends TemplatesIntonationAccountTestCase {
-  /** @test */
-  public function loanAliceShouldBeDisplay() {
+  public function setUp() {
+    parent::setUp();
     $this->dispatch('/opac/abonne/prets/id_profil/72');
-    $this->assertXPathContentContains('//div', 'Alice');
   }
 
 
   /** @test */
-  public function shouldContainsLoanAlice() {
-    $this->dispatch('/opac/abonne/ajax-loans/id_profil/72');
-    $this->assertXPathContentContains('//div', 'Alice');
+  public function pageShouldContainsScriptToAjaxLoadLoans() {
+    $this->assertXPathContentContains('//script', 'load("/abonne/ajax-loans/id_profil/72');
   }
 
 
   /** @test */
-  public function shouldContainsLoanDrHouse() {
-    $this->dispatch('/opac/abonne/ajax-loans/id_profil/72');
-    $this->assertXPathContentContains('//div', 'Dr House');
+  public function pageShouldContainsSpinnerAsLoadingIcon() {
+    $this->assertXPath('//div[@class="loading_icon spinner-border"]');
   }
 
+}
+
 
+
+
+class TemplatesDispatchAbonneLoansPaginatedTest extends TemplatesIntonationAccountTestCase {
   /** @test */
   public function page2ShouldContainsSearchInputWithMd5Key() {
     Storm_Cache::beVolatile();
@@ -2537,6 +2542,164 @@ class TemplatesDispatchAbonneLoansTest extends TemplatesIntonationAccountTestCas
 
 
 
+class TemplatesDispatchAbonneAjaxLoansTest extends TemplatesIntonationAccountTestCase {
+  public function setUp(){
+    parent::setUp();
+    $this->dispatch('/opac/abonne/ajax-loans/id_profil/72');
+  }
+
+  /** @test */
+  public function ajaxLoanAliceShouldDisplayButtonToutProlonger() {
+    $this->assertXPathContentContains('//div[contains(@class,"button_text")]', 'Tout prolonger');
+  }
+
+
+  /** @test */
+  public function shouldContainsLoanAlice() {
+    $this->assertXPathContentContains('//div', 'Alice');
+  }
+
+
+  /** @test */
+  public function shouldContainsLoanDrHouse() {
+    $this->assertXPathContentContains('//div', 'Dr House');
+  }
+
+
+  /** @test */
+  public function ajaxLoansShouldNotDisplayTitleHistoriqueDesPrets() {
+    $this->assertNotXPathContentContains('//h3', 'Historique des prêts');
+  }
+
+
+  /** @test */
+  public function shouldNotContainsLoanHistoryPottifar() {
+    $this->assertNotXPathContentContains('//div', 'Pottifar');
+  }
+}
+
+
+
+
+
+class TemplatesDispatchAbonneMonHistoriqueTest extends TemplatesIntonationAccountTestCase {
+  public function setUp(){
+    parent::setUp();
+
+    $pottifar_old = new Class_WebService_SIGB_LoansHistory($this->_emprunteur);
+    $notice_unimarc = (new Class_NoticeUnimarc_Fluent);
+    $notice_unimarc->newZone()->label('200')->addChild('a', 'Pottifar');
+
+    $notice = $this->fixture('Class_Notice',
+                   ['id' => 890,
+                    'clef_alpha' => 'MYSUPERkey',
+                    'unimarc' => $notice_unimarc->render(),
+                    'facettes' => 'M8897 T1 B3 A18 Lfre']);
+
+    $exemplaire = $this->fixture('Class_Exemplaire',
+                   ['id' => 891,
+                    'id_origine' => 1234,
+                    'code_barres' => 456,
+                    'id_int_bib' => 1,
+                    'zone995' => serialize([['clef' => 'a', 'valeur' => 'PottifarItem']]),
+                    'notice' => $notice]);
+
+    $pottifar_old_issue = new Class_WebService_SIGB_Emprunt('42', new Class_WebService_SIGB_Exemplaire(456));
+    $pottifar_old_issue
+      ->setCodeBarre(456)
+      ->setDateRetour('10/01/1981')
+      ->setIssueDate('1981-01-01')
+      ->beReturned()
+      ->getExemplaire()
+      ->setTitre('Pottifar')
+      ->setExemplaireOPAC($exemplaire)
+      ->setNoticeOPAC($notice);
+
+    $pottifar_old->addLoan($pottifar_old_issue);
+
+    $this->_mock_emprunts = $this->mock()
+                                 ->whenCalled('loansHistory')
+                                 ->answers($pottifar_old)
+                                 ->whenCalled('getLoansPerPage')
+                                 ->answers(3)
+                                 ->whenCalled('providesPagedLoans')
+                                 ->answers(false);
+
+    $this->_emprunteur->setService($this->_mock_emprunts);
+
+    $this->dispatch('/opac/abonne/prets/history/1/id_profil/72');
+  }
+
+
+
+  /** @test */
+  public function pageShouldDisplayTitleMonHistoriqueDePrets() {
+    $this->assertXPathContentContains('//h2//span', 'Mon historique de prêts', $this->_response->getBody());
+  }
+}
+
+
+
+
+class TemplatesDispatchAbonneLoansWithHistoryTest extends TemplatesIntonationAccountTestCase {
+  public function setUp(){
+    parent::setUp();
+
+    $pottifar_old = new Class_WebService_SIGB_LoansHistory($this->_emprunteur);
+    $notice_unimarc = (new Class_NoticeUnimarc_Fluent);
+    $notice_unimarc->newZone()->label('200')->addChild('a', 'Pottifar');
+
+    $notice = $this->fixture('Class_Notice',
+                   ['id' => 890,
+                    'clef_alpha' => 'MYSUPERkey',
+                    'unimarc' => $notice_unimarc->render(),
+                    'facettes' => 'M8897 T1 B3 A18 Lfre']);
+
+    $exemplaire = $this->fixture('Class_Exemplaire',
+                   ['id' => 891,
+                    'id_origine' => 1234,
+                    'code_barres' => 456,
+                    'id_int_bib' => 1,
+                    'zone995' => serialize([['clef' => 'a', 'valeur' => 'PottifarItem']]),
+                    'notice' => $notice]);
+
+    $pottifar_old_issue = new Class_WebService_SIGB_Emprunt('42', new Class_WebService_SIGB_Exemplaire(456));
+    $pottifar_old_issue
+      ->setCodeBarre(456)
+      ->setDateRetour('10/01/1981')
+      ->setIssueDate('1981-01-01')
+      ->beReturned()
+      ->getExemplaire()
+      ->setTitre('Pottifar')
+      ->setExemplaireOPAC($exemplaire)
+      ->setNoticeOPAC($notice);
+
+    $pottifar_old->addLoan($pottifar_old_issue);
+
+    $this->_mock_emprunts = $this->mock()
+                                 ->whenCalled('loansHistory')
+                                 ->answers($pottifar_old)
+                                 ->whenCalled('getLoansPerPage')
+                                 ->answers(3)
+                                 ->whenCalled('saveEmprunteur')
+                                 ->answers(null)
+                                 ->whenCalled('providesPagedLoans')
+                                 ->answers(false);
+
+    $this->_emprunteur->setService($this->_mock_emprunts);
+
+
+    $this->dispatch('/opac/abonne/ajax-loans/history/1/id_profil/72');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsPottifar() {
+    $this->assertXPathContentContains('//div','Pottifar', $this->_response->getBody());
+  }
+}
+
+
 class TemplatesDispatchAbonneHoldsTest extends TemplatesIntonationAccountTestCase {
   /** @test */
   public function holdsDobbyPotterShouldBeDisplay() {