mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 13:23:20 -07:00
perf(discover): ⚡ Improve the loading performance on the discover page
This commit is contained in:
parent
cfeee39978
commit
97d5167db6
7 changed files with 189 additions and 62 deletions
|
@ -5,13 +5,17 @@
|
|||
<mat-button-toggle id="{{id}}Tv" [ngClass]="{'button-active': discoverOptions === DiscoverOption.Tv}" value="{{DiscoverOption.Tv}}" class="discover-filter-button">{{'Discovery.Tv' | translate}}</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
@defer (when discoverResults.length > 0) {
|
||||
@defer (when discoverResults.length > 0; prefetch on idle) {
|
||||
<p-carousel #carousel [numVisible]="10" [numScroll]="10" [page]="0" [value]="discoverResults" [responsiveOptions]="responsiveOptions" (onPage)="newPage()">
|
||||
<ng-template let-result pTemplate="item">
|
||||
<discover-card [discoverType]="discoverType" [isAdmin]="isAdmin" [result]="result" [is4kEnabled]="is4kEnabled"></discover-card>
|
||||
</ng-template>
|
||||
</p-carousel>
|
||||
}
|
||||
@placeholder(minimum 500) {
|
||||
<p-skeleton width="100%" height="18rem"></p-skeleton>
|
||||
@placeholder(minimum 300) {
|
||||
<div class="row loading-container">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -105,6 +105,30 @@
|
|||
padding: 5px;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding: 0 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.loading-container .col-2 {
|
||||
flex: 0 0 auto;
|
||||
width: calc(10% - 9px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.loading-container .col-2 {
|
||||
width: calc(50% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.loading-container .col-2 {
|
||||
width: calc(100% - 0px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:755px){
|
||||
::ng-deep .p-carousel-item{
|
||||
flex: 1 0 200px !important;
|
||||
|
|
|
@ -43,7 +43,7 @@ export class CarouselListComponent implements OnInit {
|
|||
get mediaTypeStorageKey() {
|
||||
return "DiscoverOptions" + this.discoverType.toString();
|
||||
};
|
||||
private amountToLoad = 17;
|
||||
private amountToLoad = 10;
|
||||
private currentlyLoaded = 0;
|
||||
private baseUrl: string = "";
|
||||
|
||||
|
@ -148,6 +148,7 @@ export class CarouselListComponent implements OnInit {
|
|||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
|
||||
this.is4kEnabled = this.featureFacade.is4kEnabled();
|
||||
this.currentlyLoaded = 0;
|
||||
const localDiscoverOptions = +this.storageService.get(this.mediaTypeStorageKey);
|
||||
|
@ -155,11 +156,15 @@ export class CarouselListComponent implements OnInit {
|
|||
this.discoverOptions = DiscoverOption[DiscoverOption[localDiscoverOptions]];
|
||||
}
|
||||
|
||||
let currentIteration = 0;
|
||||
while (this.discoverResults.length <= 14 && currentIteration <= 3) {
|
||||
currentIteration++;
|
||||
// Load initial data - just enough to fill the first carousel page
|
||||
// This reduces initial API calls and improves loading performance
|
||||
await this.loadData(false);
|
||||
|
||||
// If we don't have enough results to fill the carousel, load one more batch
|
||||
if (this.discoverResults.length < 10) {
|
||||
await this.loadData(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async toggleChanged(event: MatButtonToggleChange) {
|
||||
|
|
|
@ -1,46 +1,108 @@
|
|||
<div class="small-middle-container">
|
||||
<div class="section">
|
||||
<h2 id="genreHeading" data-toggle="collapse" href="#genreCollapse" role="button">{{ 'Discovery.Genres' | translate }}</h2>
|
||||
<genre-button-select class="collapse show" id="genreCollapse"></genre-button-select>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.RecentlyRequestedTab' | translate }}</h2>
|
||||
<div>
|
||||
<ombi-recently-list [id]="'recentlyRequested'"></ombi-recently-list>
|
||||
@defer (on viewport; prefetch on idle) {
|
||||
<div class="section">
|
||||
<h2 id="genreHeading" data-toggle="collapse" href="#genreCollapse" role="button">{{ 'Discovery.Genres' | translate }}</h2>
|
||||
<genre-button-select class="collapse show" id="genreCollapse"></genre-button-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="section" [hidden]="!showSeasonal">
|
||||
<h2>{{ 'Discovery.SeasonalTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list
|
||||
[id]="'seasonal'"
|
||||
[isAdmin]="isAdmin"
|
||||
[discoverType]="DiscoverType.Seasonal"
|
||||
(movieCount)="setSeasonalMovieCount($event)"
|
||||
></carousel-list>
|
||||
} @placeholder(minimum 300) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.Genres' | translate }}</h2>
|
||||
<p-skeleton width="100%" height="60px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.PopularTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list [id]="'popular'" [isAdmin]="isAdmin" [discoverType]="DiscoverType.Popular"></carousel-list>
|
||||
@defer (on viewport; prefetch on idle) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.RecentlyRequestedTab' | translate }}</h2>
|
||||
<div>
|
||||
<ombi-recently-list [id]="'recentlyRequested'"></ombi-recently-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @placeholder(minimum 300) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.RecentlyRequestedTab' | translate }}</h2>
|
||||
<div class="row loading-container">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.TrendingTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list [id]="'trending'" [isAdmin]="isAdmin" [discoverType]="DiscoverType.Trending"></carousel-list>
|
||||
@defer (on viewport; prefetch on idle) {
|
||||
<div class="section" [hidden]="!showSeasonal">
|
||||
<h2>{{ 'Discovery.SeasonalTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list
|
||||
[id]="'seasonal'"
|
||||
[isAdmin]="isAdmin"
|
||||
[discoverType]="DiscoverType.Seasonal"
|
||||
(movieCount)="setSeasonalMovieCount($event)"
|
||||
></carousel-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @placeholder(minimum 300) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.SeasonalTab' | translate }}</h2>
|
||||
<div class="row loading-container">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.UpcomingTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list [id]="'upcoming'" [isAdmin]="isAdmin" [discoverType]="DiscoverType.Upcoming"></carousel-list>
|
||||
@defer (on viewport; prefetch on idle) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.PopularTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list [id]="'popular'" [isAdmin]="isAdmin" [discoverType]="DiscoverType.Popular"></carousel-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @placeholder(minimum 300) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.PopularTab' | translate }}</h2>
|
||||
<div class="row loading-container">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@defer (on viewport; prefetch on idle) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.TrendingTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list [id]="'trending'" [isAdmin]="isAdmin" [discoverType]="DiscoverType.Trending"></carousel-list>
|
||||
</div>
|
||||
</div>
|
||||
} @placeholder(minimum 300) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.TrendingTab' | translate }}</h2>
|
||||
<div class="row loading-container">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@defer (on viewport; prefetch on idle) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.UpcomingTab' | translate }}</h2>
|
||||
<div>
|
||||
<carousel-list [id]="'upcoming'" [isAdmin]="isAdmin" [discoverType]="DiscoverType.Upcoming"></carousel-list>
|
||||
</div>
|
||||
</div>
|
||||
} @placeholder(minimum 300) {
|
||||
<div class="section">
|
||||
<h2>{{ 'Discovery.UpcomingTab' | translate }}</h2>
|
||||
<div class="row loading-container">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -10,3 +10,27 @@ h2{
|
|||
margin-left:40px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding: 0 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.loading-container .col-2 {
|
||||
flex: 0 0 auto;
|
||||
width: calc(10% - 9px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.loading-container .col-2 {
|
||||
width: calc(50% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.loading-container .col-2 {
|
||||
width: calc(100% - 0px);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
@defer (when requests()) {
|
||||
@defer (when requests(); prefetch on idle) {
|
||||
<div *ngIf="requests().length > 0">
|
||||
<p-carousel #carousel [value]="requests()" [numVisible]="3" [numScroll]="1"
|
||||
[responsiveOptions]="responsiveOptions" [page]="0">
|
||||
|
@ -13,21 +13,9 @@
|
|||
</ng-template>
|
||||
</p-carousel>
|
||||
</div>
|
||||
}@placeholder(minimum 500) {
|
||||
}@placeholder(minimum 300) {
|
||||
<div class="row loading-container">
|
||||
<div class="col-2">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="col-2" *ngFor="let item of [1,2,3,4,5]">
|
||||
<p-skeleton width="100%" height="270px"></p-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -105,12 +105,32 @@
|
|||
padding: 5px;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding: 0 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.loading-container .col-2 {
|
||||
flex: 0 0 auto;
|
||||
width: calc(20% - 8px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.loading-container .col-2 {
|
||||
width: calc(50% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.loading-container .col-2 {
|
||||
width: calc(100% - 0px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:755px){
|
||||
::ng-deep .p-carousel-item{
|
||||
flex: 1 0 200px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
margin-left: 10rem;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue