mirror of
https://github.com/apricote/Listory.git
synced 2026-01-13 21:21:02 +00:00
feat: improve listens report response time
Reduce response time for larger intervals (e.g. all time) from 9 seconds to 150ms in my tests.
This commit is contained in:
parent
26087e4e6d
commit
89440daf7b
2 changed files with 19 additions and 13 deletions
|
|
@ -77,7 +77,7 @@ export const ReportListens: React.FC = () => {
|
||||||
{isLoading && <Spinner className="m-8" />}
|
{isLoading && <Spinner className="m-8" />}
|
||||||
{!reportHasItems && !isLoading && (
|
{!reportHasItems && !isLoading && (
|
||||||
<div>
|
<div>
|
||||||
<p>Report is emtpy! :(</p>
|
<p>Report is empty! :(</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{reportHasItems && (
|
{reportHasItems && (
|
||||||
|
|
@ -128,7 +128,7 @@ const ReportGraph: React.FC<{
|
||||||
<AreaChart
|
<AreaChart
|
||||||
data={dataLocal}
|
data={dataLocal}
|
||||||
margin={{
|
margin={{
|
||||||
left: -20,
|
left: -5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<defs>
|
<defs>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import {
|
||||||
isSameMonth,
|
isSameMonth,
|
||||||
isSameWeek,
|
isSameWeek,
|
||||||
isSameYear,
|
isSameYear,
|
||||||
min,
|
|
||||||
parseJSON,
|
parseJSON,
|
||||||
startOfDay,
|
startOfDay,
|
||||||
sub,
|
sub,
|
||||||
|
|
@ -73,7 +72,13 @@ export class ReportsService {
|
||||||
async getListens(options: GetListenReportDto): Promise<ListenReportDto> {
|
async getListens(options: GetListenReportDto): Promise<ListenReportDto> {
|
||||||
const { timeFrame, time: timePreset } = options;
|
const { timeFrame, time: timePreset } = options;
|
||||||
|
|
||||||
const listens = await this.getListensQueryFromOptions(options).getMany();
|
const results = await this.getListensQueryFromOptions(options)
|
||||||
|
.select(`count(*) as "listenCount"`)
|
||||||
|
.addSelect(`date_trunc(:timeFrame, "playedAt") as date`)
|
||||||
|
.groupBy("date")
|
||||||
|
.orderBy("date")
|
||||||
|
.setParameter("timeFrame", timeFrame)
|
||||||
|
.getRawMany<{ listenCount: string; date: Date }>();
|
||||||
|
|
||||||
const interval = this.getIntervalFromPreset(timePreset);
|
const interval = this.getIntervalFromPreset(timePreset);
|
||||||
const { eachOfInterval, isSame } = timeframeToDateFns[timeFrame];
|
const { eachOfInterval, isSame } = timeframeToDateFns[timeFrame];
|
||||||
|
|
@ -81,18 +86,19 @@ export class ReportsService {
|
||||||
// Optimize performance for ALL_TIME by skipping eachOfInterval for time
|
// Optimize performance for ALL_TIME by skipping eachOfInterval for time
|
||||||
// between 1970 and first listen
|
// between 1970 and first listen
|
||||||
if (timePreset.timePreset === TimePreset.ALL_TIME) {
|
if (timePreset.timePreset === TimePreset.ALL_TIME) {
|
||||||
let firstListen = min(listens.map(({ playedAt }) => playedAt));
|
interval.start = startOfDay(results[0].date);
|
||||||
interval.start = startOfDay(firstListen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This code blocks the eventloop for multiple seconds if running for
|
|
||||||
// a large interval and with many listens. Refactor to make this more
|
|
||||||
// efficient or make pauses for event loop.
|
|
||||||
const reportItems = eachOfInterval(interval).map((date) => {
|
const reportItems = eachOfInterval(interval).map((date) => {
|
||||||
const count = listens.filter((listen) =>
|
const dayResults = results.find((listen) => isSame(date, listen.date));
|
||||||
isSame(date, listen.playedAt),
|
|
||||||
).length;
|
return {
|
||||||
return { date: formatISO(date), count };
|
date: formatISO(date),
|
||||||
|
count:
|
||||||
|
dayResults && dayResults.listenCount
|
||||||
|
? Number.parseInt(dayResults.listenCount)
|
||||||
|
: 0,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return { items: reportItems };
|
return { items: reportItems };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue