diff --git a/src/components/follow_list/follow_list.js b/src/components/follow_list/follow_list.js
deleted file mode 100644
index 9777c87e..00000000
--- a/src/components/follow_list/follow_list.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import UserCard from '../user_card/user_card.vue'
-
-const FollowList = {
-  data () {
-    return {
-      loading: false,
-      bottomedOut: false,
-      error: false
-    }
-  },
-  props: ['userId', 'showFollowers'],
-  created () {
-    window.addEventListener('scroll', this.scrollLoad)
-    if (this.entries.length === 0) {
-      this.fetchEntries()
-    }
-  },
-  destroyed () {
-    window.removeEventListener('scroll', this.scrollLoad)
-    this.$store.dispatch('clearFriendsAndFollowers', this.userId)
-  },
-  computed: {
-    user () {
-      return this.$store.getters.userById(this.userId)
-    },
-    entries () {
-      return this.showFollowers ? this.user.followers : this.user.friends
-    },
-    showFollowsYou () {
-      return !this.showFollowers || (this.showFollowers && this.userId !== this.$store.state.users.currentUser.id)
-    }
-  },
-  methods: {
-    fetchEntries () {
-      if (!this.loading) {
-        const command = this.showFollowers ? 'addFollowers' : 'addFriends'
-        this.loading = true
-        this.$store.dispatch(command, this.userId).then(entries => {
-          this.error = false
-          this.loading = false
-          this.bottomedOut = entries.length === 0
-        }).catch(() => {
-          this.error = true
-          this.loading = false
-        })
-      }
-    },
-    scrollLoad (e) {
-      const bodyBRect = document.body.getBoundingClientRect()
-      const height = Math.max(bodyBRect.height, -(bodyBRect.y))
-      if (this.loading === false &&
-        this.bottomedOut === false &&
-        this.$el.offsetHeight > 0 &&
-        (window.innerHeight + window.pageYOffset) >= (height - 750)
-      ) {
-        this.fetchEntries()
-      }
-    }
-  },
-  watch: {
-    'user': 'fetchEntries'
-  },
-  components: {
-    UserCard
-  }
-}
-
-export default FollowList
diff --git a/src/components/follow_list/follow_list.vue b/src/components/follow_list/follow_list.vue
deleted file mode 100644
index 27102edf..00000000
--- a/src/components/follow_list/follow_list.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<template>
-  <div class="follow-list">
-    <user-card
-      v-for="entry in entries"
-      :key="entry.id" :user="entry"
-      :noFollowsYou="!showFollowsYou"
-    />
-    <div class="text-center panel-footer">
-      <a v-if="error" @click="fetchEntries" class="alert error">
-        {{$t('general.generic_error')}}
-      </a>
-      <i v-else-if="loading" class="icon-spin3 animate-spin"/>
-      <span v-else-if="bottomedOut"></span>
-      <a v-else @click="fetchEntries">{{$t('general.more')}}</a>
-    </div>
-  </div>
-</template>
-
-<script src="./follow_list.js"></script>
-
-<style lang="scss">
-
-.follow-list {
-  .panel-footer {
-    padding: 10px;
-  }
-
-  .error {
-    font-size: 14px;
-  }
-}
-
-</style>
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index ebf6c61a..9f9d43e4 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -1,8 +1,32 @@
+import { compose } from 'vue-compose'
 import get from 'lodash/get'
 import UserCardContent from '../user_card_content/user_card_content.vue'
 import UserCard from '../user_card/user_card.vue'
 import Timeline from '../timeline/timeline.vue'
-import FollowList from '../follow_list/follow_list.vue'
+import withLoadMore from '../../hocs/with_load_more/with_load_more'
+import withList from '../../hocs/with_list/with_list'
+
+const FollowerList = compose(
+  withLoadMore({
+    fetch: (props, $store) => $store.dispatch('addFollowers', props.userId),
+    select: (props, $store) => get($store.getters.userById(props.userId), 'followers', []),
+    destory: (props, $store) => $store.dispatch('clearFollowers', props.userId),
+    childPropName: 'entries',
+    additionalPropNames: ['userId']
+  }),
+  withList({ getEntryProps: user => ({ user }) })
+)(UserCard)
+
+const FriendList = compose(
+  withLoadMore({
+    fetch: (props, $store) => $store.dispatch('addFriends', props.userId),
+    select: (props, $store) => get($store.getters.userById(props.userId), 'friends', []),
+    destory: (props, $store) => $store.dispatch('clearFriends', props.userId),
+    childPropName: 'entries',
+    additionalPropNames: ['userId']
+  }),
+  withList({ getEntryProps: user => ({ user }) })
+)(UserCard)
 
 const UserProfile = {
   data () {
@@ -123,7 +147,8 @@ const UserProfile = {
     UserCardContent,
     UserCard,
     Timeline,
-    FollowList
+    FollowerList,
+    FriendList
   }
 }
 
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index ba1a7760..a3d2825f 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -18,16 +18,10 @@
         :user-id="fetchBy"
       />
       <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
-        <FollowList v-if="user.friends_count > 0" :userId="userId" :showFollowers="false" />
-        <div class="userlist-placeholder" v-else>
-          <i class="icon-spin3 animate-spin"></i>
-        </div>
+        <FriendList :userId="userId" />
       </div>
       <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
-        <FollowList v-if="user.followers_count > 0" :userId="userId" :showFollowers="true" />
-        <div class="userlist-placeholder" v-else>
-          <i class="icon-spin3 animate-spin"></i>
-        </div>
+        <FollowerList :userId="userId" :entryProps="{noFollowsYou: isUs}" />
       </div>
       <Timeline
         :label="$t('user_card.media')"
diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js
index 7d53e7ac..b8246ec9 100644
--- a/src/hocs/with_load_more/with_load_more.js
+++ b/src/hocs/with_load_more/with_load_more.js
@@ -7,6 +7,7 @@ import './with_load_more.scss'
 const withLoadMore = ({
   fetch,                      // function to fetch entries and return a promise
   select,                     // function to select data from store
+  destroy,                    // function called at "destroyed" lifecycle
   childPropName = 'entries',  // name of the prop to be passed into the wrapped component
   additionalPropNames = []    // additional prop name list of the wrapper component
 }) => (WrappedComponent) => {
@@ -58,6 +59,7 @@ const withLoadMore = ({
     },
     destroyed () {
       window.removeEventListener('scroll', this.scrollLoad)
+      destroy && destroy(this.$props, this.$store)
     },
     methods: {
       fetchEntries () {
diff --git a/src/modules/users.js b/src/modules/users.js
index b2821a92..093af497 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -72,14 +72,20 @@ export const mutations = {
   },
   // Because frontend doesn't have a reason to keep these stuff in memory
   // outside of viewing someones user profile.
-  clearFriendsAndFollowers (state, userKey) {
-    const user = state.usersObject[userKey]
+  clearFriends (state, userId) {
+    const user = state.usersObject[userId]
     if (!user) {
       return
     }
     user.friends = []
-    user.followers = []
     user.friendsPage = 0
+  },
+  clearFollowers (state, userId) {
+    const user = state.usersObject[userId]
+    if (!user) {
+      return
+    }
+    user.followers = []
     user.followersPage = 0
   },
   addNewUsers (state, users) {
@@ -197,8 +203,11 @@ const users = {
           return followers
         })
     },
-    clearFriendsAndFollowers ({ commit }, userKey) {
-      commit('clearFriendsAndFollowers', userKey)
+    clearFriends ({ commit }, userId) {
+      commit('clearFriends', userId)
+    },
+    clearFollowers ({ commit }, userId) {
+      commit('clearFollowers', userId)
     },
     registerPushNotifications (store) {
       const token = store.state.currentUser.credentials