Skip to content

Commit

Permalink
perf: improve menu loading time
Browse files Browse the repository at this point in the history
  • Loading branch information
Guilhermeasper committed Sep 14, 2024
1 parent 6d5f24e commit 69efb1d
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 85 deletions.
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<ng-container *ngIf="loading; else mainContent"> Loading... </ng-container>
<ng-container *ngIf="loading; else mainContent"> </ng-container>
<ng-template #mainContent>
<header>
<svg
Expand Down
6 changes: 6 additions & 0 deletions src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@
align-items: center;
background-color: var(--sertao-light);
}

.loading-message {
font-size: 1.5rem;
color: var(--sertao-dark);
font-family: "Ultra", sans-serif;
}
}
62 changes: 8 additions & 54 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { Subject, debounce, fromEvent, interval } from 'rxjs';
import { SBMenuSectionComponent } from '@sertao-bar/components/menu-section/menu-section.component';
import { SBMenuItem } from '@sertao-bar/models/menu-item';
import { SpreadsheetService } from '@sertao-bar/services/spreadsheet/spreadsheet.service';
import { MenuService } from '@sertao-bar/services/menu/menu.service';

@Component({
selector: 'sb-root',
Expand All @@ -20,9 +20,7 @@ export class AppComponent implements OnInit {
selectedSection = '';
title = 'Cardápio Sertão Bar';
sections: string[] = [];
sectionsSubject = new Subject<string[]>();
items: Map<string, SBMenuItem[]> = new Map<string, SBMenuItem[]>();
itemsSubject = new Subject<Map<string, SBMenuItem[]>>();
headerScrollShadow = false;
categoryListScrollShadow = true;

Expand All @@ -31,21 +29,16 @@ export class AppComponent implements OnInit {

@HostBinding('class.loading') loading = true;

constructor(private spreadSheetService: SpreadsheetService) {}
constructor(private menuService: MenuService) {}

ngOnInit(): void {
this.sectionsSubject.subscribe((sections) => {
this.sections = sections;
this.selectedSection = this.sections[0];
this._loadItems();
});

this.itemsSubject.subscribe((items) => {
this.items = items;
this.loading = false;
this.menuService.menuObservable.subscribe((menu) => {
if (menu) {
this.sections = Array.from(menu.keys());
this.items = menu;
this.loading = false;
}
});

this._loadSections();
fromEvent(window, 'scroll')
.pipe(debounce(() => interval(100)))
.subscribe(() => this._onScroll());
Expand Down Expand Up @@ -73,41 +66,6 @@ export class AppComponent implements OnInit {
});
}

private _loadSections(): void {
this.spreadSheetService.getSections().subscribe((sections) => {
this.sectionsSubject.next(sections.values[0]);
});
}

private _loadItems(): void {
this.spreadSheetService.getMenuItems().subscribe((items) => {
const itemsArray = items.values;
const sectionItemsMap = new Map<string, SBMenuItem[]>();
this.sections.forEach((section) => {
sectionItemsMap.set(
section,
this._parseItems(itemsArray.filter((item) => item[2] === section))
);
});
this.itemsSubject.next(sectionItemsMap);
});
}

private _parseItems(itemArray: string[][]): SBMenuItem[] {
const items: SBMenuItem[] = [];
itemArray.forEach((item) => {
items.push({
title: this._parseItem(item[0]),
price: this._parseItem(item[1]),
category: this._parseItem(item[2]),
type: this._parseItem(item[3]),
description: this._parseItem(item[4]),
image: this._parseItem(item[5]),
} as SBMenuItem);
});
return items;
}

/**
Handles the scroll event and updates the selected section based on the current scroll position.
@returns {void}
Expand Down Expand Up @@ -145,8 +103,4 @@ export class AppComponent implements OnInit {
}
}
}

private _parseItem(item: string): string | null {
return item != '-' ? item : null;
}
}
13 changes: 11 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { NgModule } from '@angular/core';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from '@sertao-bar/app/app.component';
import { SBSectionItemsPipe } from '@sertao-bar/pipes/section-items.pipe';
import { SBMenuSectionComponent } from '@sertao-bar/components/menu-section/menu-section.component';
import { SBCategoryListComponent } from '@sertao-bar/components/category-list/category-list.component';
import { MenuService } from '@sertao-bar/services/menu/menu.service';

@NgModule({
declarations: [AppComponent, SBSectionItemsPipe],
Expand All @@ -15,7 +16,15 @@ import { SBCategoryListComponent } from '@sertao-bar/components/category-list/ca
SBCategoryListComponent,
HttpClientModule,
],
providers: [{ provide: Window, useValue: window }],
providers: [
{ provide: Window, useValue: window },
{
provide: APP_INITIALIZER,
useFactory: () => () => {},
multi: true,
deps: [MenuService],
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { TestBed } from '@angular/core/testing';

import { SpreadsheetService } from './spreadsheet.service';
import { MenuService } from './menu.service';

describe('SpreadsheetService', () => {
let service: SpreadsheetService;
let service: MenuService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(SpreadsheetService);
service = TestBed.inject(MenuService);
});

it('should be created', () => {
Expand Down
64 changes: 64 additions & 0 deletions src/services/menu/menu.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, firstValueFrom, Observable, of } from 'rxjs';
import { SBSpreadsheetResponse } from '@sertao-bar/models/spreadsheet-response';
import { environment } from '@sertao-bar/environments/environment';
import { SBMenuItem } from '@sertao-bar/models/menu-item';

@Injectable({
providedIn: 'root',
})
export class MenuService {
menuObservable: Observable<Map<string, SBMenuItem[]> | null>;
private menuSubject: BehaviorSubject<Map<string, SBMenuItem[]> | null> =
new BehaviorSubject<Map<string, SBMenuItem[]> | null>(null);
apiUrl: string = environment.api_url;
apiKey: string = environment.api_key;

constructor(private http: HttpClient) {
this.menuObservable = this.menuSubject.asObservable();
this.loadMenu();
}

getSections(): Observable<SBSpreadsheetResponse> {
const requestUrl = `${this.apiUrl}sections?alt=json&key=${this.apiKey}`;
return this.http.get<SBSpreadsheetResponse>(requestUrl);
}

getMenuItems(): Observable<SBSpreadsheetResponse> {
const requestUrl = `${this.apiUrl}data?alt=json&key=${this.apiKey}`;
return this.http.get<SBSpreadsheetResponse>(requestUrl);
}

async loadMenu(): Promise<void> {
const sections = (await firstValueFrom(this.getSections())).values[0];
const menuItems = (await firstValueFrom(this.getMenuItems())).values;
const sectionItemsMap = new Map<string, SBMenuItem[]>();
sections.forEach((section) => {
sectionItemsMap.set(
section,
this._parseItems(menuItems.filter((item) => item[2] === section))
);
});
this.menuSubject.next(sectionItemsMap);
}

private _parseItems(itemArray: string[][]): SBMenuItem[] {
const items: SBMenuItem[] = [];
itemArray.forEach((item) => {
items.push({
title: this._parseItem(item[0]),
price: this._parseItem(item[1]),
category: this._parseItem(item[2]),
type: this._parseItem(item[3]),
description: this._parseItem(item[4]),
image: this._parseItem(item[5]),
} as SBMenuItem);
});
return items;
}

private _parseItem(item: string): string | null {
return item != '-' ? item : null;
}
}
25 changes: 0 additions & 25 deletions src/services/spreadsheet/spreadsheet.service.ts

This file was deleted.

0 comments on commit 69efb1d

Please sign in to comment.