mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 01:34:27 +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,
 | 
							return
 | 
				
			||||||
				Error: err.Error(),
 | 
						}
 | 
				
			||||||
			})
 | 
					
 | 
				
			||||||
			return
 | 
						results := make([]*api.Repository, len(repos))
 | 
				
			||||||
		}
 | 
						for i, repo := range repos {
 | 
				
			||||||
		accessMode, err := models.AccessLevel(ctx.Doer, repo)
 | 
							results[i] = &api.Repository{
 | 
				
			||||||
		if err != nil {
 | 
								ID:       repo.ID,
 | 
				
			||||||
			ctx.JSON(http.StatusInternalServerError, api.SearchError{
 | 
								FullName: repo.FullName(),
 | 
				
			||||||
				OK:    false,
 | 
								Fork:     repo.IsFork,
 | 
				
			||||||
				Error: err.Error(),
 | 
								Private:  repo.IsPrivate,
 | 
				
			||||||
			})
 | 
								Template: repo.IsTemplate,
 | 
				
			||||||
		}
 | 
								Mirror:   repo.IsMirror,
 | 
				
			||||||
		results[i] = convert.ToRepo(repo, accessMode)
 | 
								Stars:    repo.NumStars,
 | 
				
			||||||
 | 
								HTMLURL:  repo.HTMLURL(),
 | 
				
			||||||
 | 
								Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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;
 | 
				
			||||||
          if (searchedURL === this.searchURL) {
 | 
					        try {
 | 
				
			||||||
            this.repos = result.data;
 | 
					          if (!this.reposTotalCount) {
 | 
				
			||||||
            const count = request.getResponseHeader('X-Total-Count');
 | 
					            const totalCountSearchURL = `${this.subUrl}/repo/search?count_only=1&uid=${this.uid}&team_id=${this.teamId}&q=&page=1&mode=`;
 | 
				
			||||||
            if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
 | 
					            response = await fetch(totalCountSearchURL);
 | 
				
			||||||
              this.reposTotalCount = count;
 | 
					            this.reposTotalCount = response.headers.get('X-Total-Count');
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count);
 | 
					 | 
				
			||||||
            this.finalPage = Math.ceil(count / this.searchLimit);
 | 
					 | 
				
			||||||
            this.updateHistory();
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }).always(() => {
 | 
					
 | 
				
			||||||
 | 
					          response = await fetch(searchedURL);
 | 
				
			||||||
 | 
					          json = await response.json();
 | 
				
			||||||
 | 
					        } catch {
 | 
				
			||||||
          if (searchedURL === this.searchURL) {
 | 
					          if (searchedURL === this.searchURL) {
 | 
				
			||||||
            this.isLoading = false;
 | 
					            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) {
 | 
					      repoIcon(repo) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user