mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Improve dashboard's repo list performance (#18963)
* Improve dashboard's repo list performance - Avoid a lot of database lookups for all the repo's, by adding a undocumented "minimal" mode for this specific task, which returns the data that's only needed by this list which doesn't require any database lookups. - Makes fetching these list faster. - Less CPU overhead when a user visits home page. * Refactor javascript code + fix Fork icon - Use async in the function so we can use `await`. - Remove `archivedFilter` check for count, as it doesn't make sense to show the count of repos when you can't even see them(as they are filited away). * Add `count_only` * Remove uncessary code * Improve comment Co-authored-by: delvh <dev.lh@web.de> * Update web_src/js/components/DashboardRepoList.js Co-authored-by: delvh <dev.lh@web.de> * Update web_src/js/components/DashboardRepoList.js Co-authored-by: delvh <dev.lh@web.de> * By default apply minimal mode * Remove `minimal` paramater * Refactor count header * Simplify init Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
		| @@ -218,7 +218,6 @@ func Search(ctx *context.APIContext) { | |||||||
| 		} | 		} | ||||||
| 		results[i] = convert.ToRepo(repo, accessMode) | 		results[i] = convert.ToRepo(repo, accessMode) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.SetLinkHeader(int(count), opts.PageSize) | 	ctx.SetLinkHeader(int(count), opts.PageSize) | ||||||
| 	ctx.SetTotalCountHeader(count) | 	ctx.SetTotalCountHeader(count) | ||||||
| 	ctx.JSON(http.StatusOK, api.SearchResults{ | 	ctx.JSON(http.StatusOK, api.SearchResults{ | ||||||
|   | |||||||
| @@ -590,26 +590,28 @@ func SearchRepo(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	results := make([]*api.Repository, len(repos)) | 	ctx.SetTotalCountHeader(count) | ||||||
| 	for i, repo := range repos { |  | ||||||
| 		if err = repo.GetOwner(ctx); err != nil { | 	// To improve performance when only the count is requested | ||||||
| 			ctx.JSON(http.StatusInternalServerError, api.SearchError{ | 	if ctx.FormBool("count_only") { | ||||||
| 				OK:    false, |  | ||||||
| 				Error: err.Error(), |  | ||||||
| 			}) |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 		accessMode, err := models.AccessLevel(ctx.Doer, repo) |  | ||||||
| 		if err != nil { | 	results := make([]*api.Repository, len(repos)) | ||||||
| 			ctx.JSON(http.StatusInternalServerError, api.SearchError{ | 	for i, repo := range repos { | ||||||
| 				OK:    false, | 		results[i] = &api.Repository{ | ||||||
| 				Error: err.Error(), | 			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, | ||||||
| 		} | 		} | ||||||
| 		results[i] = convert.ToRepo(repo, accessMode) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.SetTotalCountHeader(count) |  | ||||||
| 	ctx.JSON(http.StatusOK, api.SearchResults{ | 	ctx.JSON(http.StatusOK, api.SearchResults{ | ||||||
| 		OK:   true, | 		OK:   true, | ||||||
| 		Data: results, | 		Data: results, | ||||||
|   | |||||||
| @@ -298,36 +298,41 @@ function initVueComponents() { | |||||||
|         this.searchRepos(); |         this.searchRepos(); | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|       searchRepos() { |       async searchRepos() { | ||||||
|         this.isLoading = true; |         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 searchedMode = this.repoTypes[this.reposFilter].searchMode; | ||||||
|         const searchedURL = this.searchURL; |         const searchedURL = this.searchURL; | ||||||
|         const searchedQuery = this.searchQuery; |         const searchedQuery = this.searchQuery; | ||||||
|  |  | ||||||
|         $.getJSON(searchedURL, (result, _textStatus, request) => { |         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'); | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           response = await fetch(searchedURL); | ||||||
|  |           json = await response.json(); | ||||||
|  |         } catch { | ||||||
|           if (searchedURL === this.searchURL) { |           if (searchedURL === this.searchURL) { | ||||||
|             this.repos = result.data; |             this.isLoading = false; | ||||||
|             const count = request.getResponseHeader('X-Total-Count'); |           } | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (searchedURL === this.searchURL) { | ||||||
|  |           this.repos = json.data; | ||||||
|  |           const count = response.headers.get('X-Total-Count'); | ||||||
|           if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') { |           if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') { | ||||||
|             this.reposTotalCount = count; |             this.reposTotalCount = count; | ||||||
|           } |           } | ||||||
|           Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count); |           Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count); | ||||||
|           this.finalPage = Math.ceil(count / this.searchLimit); |           this.finalPage = Math.ceil(count / this.searchLimit); | ||||||
|           this.updateHistory(); |           this.updateHistory(); | ||||||
|           } |  | ||||||
|         }).always(() => { |  | ||||||
|           if (searchedURL === this.searchURL) { |  | ||||||
|           this.isLoading = false; |           this.isLoading = false; | ||||||
|         } |         } | ||||||
|         }); |  | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|       repoIcon(repo) { |       repoIcon(repo) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Gusted
					Gusted