diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 16942dd3ba..cec4c93d19 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -218,7 +218,6 @@ func Search(ctx *context.APIContext) {
 		}
 		results[i] = convert.ToRepo(repo, accessMode)
 	}
-
 	ctx.SetLinkHeader(int(count), opts.PageSize)
 	ctx.SetTotalCountHeader(count)
 	ctx.JSON(http.StatusOK, api.SearchResults{
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 60298121df..199651b2f1 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -590,26 +590,28 @@ func SearchRepo(ctx *context.Context) {
 		return
 	}
 
-	results := make([]*api.Repository, len(repos))
-	for i, repo := range repos {
-		if err = repo.GetOwner(ctx); err != nil {
-			ctx.JSON(http.StatusInternalServerError, api.SearchError{
-				OK:    false,
-				Error: err.Error(),
-			})
-			return
-		}
-		accessMode, err := models.AccessLevel(ctx.Doer, repo)
-		if err != nil {
-			ctx.JSON(http.StatusInternalServerError, api.SearchError{
-				OK:    false,
-				Error: err.Error(),
-			})
-		}
-		results[i] = convert.ToRepo(repo, accessMode)
+	ctx.SetTotalCountHeader(count)
+
+	// To improve performance when only the count is requested
+	if ctx.FormBool("count_only") {
+		return
+	}
+
+	results := make([]*api.Repository, len(repos))
+	for i, repo := range repos {
+		results[i] = &api.Repository{
+			ID:       repo.ID,
+			FullName: repo.FullName(),
+			Fork:     repo.IsFork,
+			Private:  repo.IsPrivate,
+			Template: repo.IsTemplate,
+			Mirror:   repo.IsMirror,
+			Stars:    repo.NumStars,
+			HTMLURL:  repo.HTMLURL(),
+			Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
+		}
 	}
 
-	ctx.SetTotalCountHeader(count)
 	ctx.JSON(http.StatusOK, api.SearchResults{
 		OK:   true,
 		Data: results,
diff --git a/web_src/js/components/DashboardRepoList.js b/web_src/js/components/DashboardRepoList.js
index e4847ec2f0..36caaf2f5b 100644
--- a/web_src/js/components/DashboardRepoList.js
+++ b/web_src/js/components/DashboardRepoList.js
@@ -298,36 +298,41 @@ function initVueComponents() {
         this.searchRepos();
       },
 
-      searchRepos() {
+      async searchRepos() {
         this.isLoading = true;
 
-        if (!this.reposTotalCount) {
-          const totalCountSearchURL = `${this.subUrl}/repo/search?sort=updated&order=desc&uid=${this.uid}&team_id=${this.teamId}&q=&page=1&mode=`;
-          $.getJSON(totalCountSearchURL, (_result, _textStatus, request) => {
-            this.reposTotalCount = request.getResponseHeader('X-Total-Count');
-          });
-        }
-
         const searchedMode = this.repoTypes[this.reposFilter].searchMode;
         const searchedURL = this.searchURL;
         const searchedQuery = this.searchQuery;
 
-        $.getJSON(searchedURL, (result, _textStatus, request) => {
-          if (searchedURL === this.searchURL) {
-            this.repos = result.data;
-            const count = request.getResponseHeader('X-Total-Count');
-            if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
-              this.reposTotalCount = count;
-            }
-            Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count);
-            this.finalPage = Math.ceil(count / this.searchLimit);
-            this.updateHistory();
+        let response, json;
+        try {
+          if (!this.reposTotalCount) {
+            const totalCountSearchURL = `${this.subUrl}/repo/search?count_only=1&uid=${this.uid}&team_id=${this.teamId}&q=&page=1&mode=`;
+            response = await fetch(totalCountSearchURL);
+            this.reposTotalCount = response.headers.get('X-Total-Count');
           }
-        }).always(() => {
+
+          response = await fetch(searchedURL);
+          json = await response.json();
+        } catch {
           if (searchedURL === this.searchURL) {
             this.isLoading = false;
           }
-        });
+          return;
+        }
+
+        if (searchedURL === this.searchURL) {
+          this.repos = json.data;
+          const count = response.headers.get('X-Total-Count');
+          if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
+            this.reposTotalCount = count;
+          }
+          Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count);
+          this.finalPage = Math.ceil(count / this.searchLimit);
+          this.updateHistory();
+          this.isLoading = false;
+        }
       },
 
       repoIcon(repo) {