Recommendations for a performing typescript web app
See original GitHub issueI take the liberty of opening this issue here too because perhaps you have already faced this problem and you could show me the right way.
And I could also create a PR for future people.
I’m building for the first time a new app in Typescript designing it with Proto files.
I’m having doubts about which is the best strategy to manage the many service clients in this web app.
“Best” in terms of a good compromise between user’s device RAM and Javascript execution speed (main thread ops).
This is what I’m doing right now, this is the main file:
- main.ts:
import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport';
import { PlayerServiceClient } from './grpc/generated/player.client';
import { TeamServiceClient } from './proto/team.client';
import { RefereeServiceClient } from './proto/referee.client';
import { FriendServiceClient } from './proto/friend.client';
import { PrizeServiceClient } from './proto/prize.client';
import { WinnerServiceClient } from './proto/winner.client';
import { CalendarServiceClient } from './proto/calendar.client';
const transport = new GrpcWebFetchTransport({ baseUrl: 'http://localhost:3000/api' });
let playerService: PlayerServiceClient;
export const getPlayerService = (): PlayerServiceClient =>
playerService || ((playerService = new PlayerServiceClient(transport)), playerService);
let teamService: TeamServiceClient;
export const getTeamService = (): TeamServiceClient =>
teamService || ((teamService = new TeamServiceClient(transport)), teamService);
let refereeService: RefereeServiceClient;
export const getRefereeService = (): RefereeServiceClient =>
refereeService || ((refereeService = new RefereeServiceClient(transport)), refereeService);
let friendService: FriendServiceClient;
export const getFriendService = (): FriendServiceClient =>
friendService || ((friendService = new FriendServiceClient(transport)), friendService);
let prizeService: PrizeServiceClient;
export const getPrizeService = (): PrizeServiceClient =>
prizeService || ((prizeService = new PrizeServiceClient(transport)), prizeService);
let winnerService: WinnerServiceClient;
export const getWinnerService = (): WinnerServiceClient =>
winnerService || ((winnerService = new WinnerServiceClient(transport)), winnerService);
let calendarService: CalendarServiceClient;
export const getCalendarService = (): CalendarServiceClient =>
calendarService || ((calendarService = new CalendarServiceClient(transport)), calendarService);
// and so on... a lot more...
As you can see there are many service clients.
I’m using this code because I thought it was better given my web app structure based on routes almost overlapping with client services:
I mean, if the player goes from /home
to /players
page I can use it like this:
import { getPlayerService } from 'main';
const players = async () => await getPlayerService().queryPlayers()
In this way, if the PlayerService
does not exist, it is created at the moment and returned, otherwise it returns the one created before.
Since the user switches pages frequently this way I can avoid the sudden creation and destruction of those clients, right?
But in this way I am using global variables which I don’t like to use.
What do you suggest me to do?
Is there a better way?
Can I refactor this code into only one class?
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (1 by maintainers)
Top GitHub Comments
Here’s a simple one that should work:
If the async getter gets too tiring for you, I would recommend having a
loadAuthClient
function instead that gets called before accessingauth
How we use this tool in our project, we have a
Connection
class which contains instances of each service needed by the application. We don’t use many services though, so we aren’t really taking advantage of lazy loading them. Although if we wanted to lazy load them then I would just have getters for the services that import only once.