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:
parent
89eec15dd9
commit
076eaad743
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue