diff --git a/src/GroupMembershipLoader.php b/src/GroupMembershipLoader.php
index 7971c16..371b6fe 100644
--- a/src/GroupMembershipLoader.php
+++ b/src/GroupMembershipLoader.php
@@ -22,6 +22,20 @@ use Drupal\group\Entity\GroupInterface;
 class GroupMembershipLoader implements GroupMembershipLoaderInterface {
 
   /**
+   * Static cache of a user memberships per user.
+   *
+   * @var array
+   */
+  protected $userMemberships = [];
+
+  /**
+   * Static cache of group memberships per group.
+   *
+   * @var array
+   */
+  protected $groupMemberships = [];
+
+  /**
    * The entity type manager.
    *
    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
@@ -69,7 +83,7 @@ class GroupMembershipLoader implements GroupMembershipLoaderInterface {
   protected function wrapGroupContentEntities($entities) {
     $group_memberships = [];
     foreach ($entities as $group_content) {
-      $group_memberships[] = new GroupMembership($group_content);
+      $group_memberships[$group_content->gid->target_id] = new GroupMembership($group_content);
     }
     return $group_memberships;
   }
@@ -78,30 +92,45 @@ class GroupMembershipLoader implements GroupMembershipLoaderInterface {
    * {@inheritdoc}
    */
   public function load(GroupInterface $group, AccountInterface $account) {
-    $filters = ['entity_id' => $account->id()];
-    $group_contents = $this->groupContentStorage()->loadByGroup($group, 'group_membership', $filters);
-    $group_memberships = $this->wrapGroupContentEntities($group_contents);
-    return $group_memberships ? reset($group_memberships) : FALSE;
+    if (!isset($this->userMemberships[$account->id()])) {
+      $this->loadByUser($account);
+    }
+    return isset($this->userMemberships[$account->id()][$group->id()]) ? $this->userMemberships[$account->id()][$group->id()] : FALSE;
   }
 
   /**
    * {@inheritdoc}
    */
   public function loadByGroup(GroupInterface $group, $roles = NULL) {
-    $filters = [];
+    if (isset($this->groupMemberships[$group->id()])) {
+      $this->groupMemberships[$group->id()];
+    }
 
+    $filters = [];
     if (isset($roles)) {
       $filters['group_roles'] = (array) $roles;
     }
 
-    $group_contents = $this->groupContentStorage()->loadByGroup($group, 'group_membership', $filters);
-    return $this->wrapGroupContentEntities($group_contents);
+    $group_contents = $this->groupContentStorage()
+      ->loadByGroup($group, 'group_membership', $filters);
+    $this->groupMemberships[$group->id()] = $this->wrapGroupContentEntities($group_contents);
+
+    return $this->groupMemberships[$group->id()];
   }
 
   /**
    * {@inheritdoc}
    */
   public function loadByUser(AccountInterface $account = NULL, $roles = NULL) {
+    $cache_id = $account->id();
+    if ($roles) {
+      $cache_id .= is_array($roles) ? ':' . md5(implode('-', $roles)) : ':' . md5($roles);
+    }
+
+    if (isset($this->userMemberships[$cache_id])) {
+      return $this->userMemberships[$cache_id];
+    }
+
     if (!isset($account)) {
       $account = $this->currentUser;
     }
@@ -113,7 +142,8 @@ class GroupMembershipLoader implements GroupMembershipLoaderInterface {
 
     // If none were found, there can be no memberships either.
     if (empty($group_content_types)) {
-      return [];
+      $this->userMemberships[$cache_id] = [];
+      return $this->userMemberships[$cache_id];
     }
 
     // Try to load all possible membership group content for the user.
@@ -129,7 +159,8 @@ class GroupMembershipLoader implements GroupMembershipLoaderInterface {
 
     /** @var \Drupal\group\Entity\GroupContentInterface[] $group_contents */
     $group_contents = $this->groupContentStorage()->loadByProperties($properties);
-    return $this->wrapGroupContentEntities($group_contents);
+    $this->userMemberships[$cache_id] = $this->wrapGroupContentEntities($group_contents);
+    return $this->userMemberships[$cache_id];
   }
 
 }
