Skip to content

Commit dbc8307

Browse files
committed
Use optimistic state and skeletons for loading
1 parent b8739ba commit dbc8307

File tree

3 files changed

+153
-123
lines changed

3 files changed

+153
-123
lines changed

frigate/stats/emitter.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
logger = logging.getLogger(__name__)
1717

1818

19-
MAX_STATS_POINTS = 120
19+
MAX_STATS_POINTS = 80
20+
FREQUENCY_STATS_POINTS = 15
2021

2122

2223
class StatsEmitter(threading.Thread):
@@ -70,9 +71,9 @@ def get_stats_history(
7071
def run(self) -> None:
7172
time.sleep(10)
7273
for counter in itertools.cycle(
73-
range(int(self.config.mqtt.stats_interval / 10))
74+
range(int(self.config.mqtt.stats_interval / FREQUENCY_STATS_POINTS))
7475
):
75-
if self.stop_event.wait(10):
76+
if self.stop_event.wait(FREQUENCY_STATS_POINTS):
7677
break
7778

7879
logger.debug("Starting stats collection")

web/src/components/graph/SystemGraph.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ export function ThresholdBarGraph({
8787
tooltip: {
8888
theme: systemTheme || theme,
8989
},
90+
markers: {
91+
size: 0,
92+
},
9093
xaxis: {
9194
tickAmount: 4,
9295
tickPlacement: "on",
@@ -105,7 +108,7 @@ export function ThresholdBarGraph({
105108
min: 0,
106109
max: threshold.warning + 10,
107110
},
108-
};
111+
} as ApexCharts.ApexOptions;
109112
}, [graphId, threshold, systemTheme, theme, formatTime]);
110113

111114
useEffect(() => {

web/src/views/system/GeneralMetrics.tsx

Lines changed: 145 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
import { Button } from "@/components/ui/button";
1313
import VainfoDialog from "@/components/overlay/VainfoDialog";
1414
import { ThresholdBarGraph } from "@/components/graph/SystemGraph";
15+
import { Skeleton } from "@/components/ui/skeleton";
1516

1617
type GeneralMetricsProps = {
1718
lastUpdated: number;
@@ -264,10 +265,6 @@ export default function GeneralMetrics({
264265
return Object.values(series);
265266
}, [statsHistory]);
266267

267-
if (statsHistory.length == 0) {
268-
return;
269-
}
270-
271268
return (
272269
<>
273270
<VainfoDialog showVainfo={showVainfo} setShowVainfo={setShowVainfo} />
@@ -276,102 +273,123 @@ export default function GeneralMetrics({
276273
<div className="text-muted-foreground text-sm font-medium">
277274
Detectors
278275
</div>
279-
<div className="mt-4 grid grid-cols-1 sm:grid-cols-3 gap-2">
280-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
281-
<div className="mb-5">Detector Inference Speed</div>
282-
{detInferenceTimeSeries.map((series) => (
283-
<ThresholdBarGraph
284-
key={series.name}
285-
graphId={`${series.name}-inference`}
286-
name={series.name}
287-
unit="ms"
288-
threshold={InferenceThreshold}
289-
updateTimes={updateTimes}
290-
data={[series]}
291-
/>
292-
))}
293-
</div>
294-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
295-
<div className="mb-5">Detector CPU Usage</div>
296-
{detCpuSeries.map((series) => (
297-
<ThresholdBarGraph
298-
key={series.name}
299-
graphId={`${series.name}-cpu`}
300-
unit="%"
301-
name={series.name}
302-
threshold={DetectorCpuThreshold}
303-
updateTimes={updateTimes}
304-
data={[series]}
305-
/>
306-
))}
307-
</div>
308-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
309-
<div className="mb-5">Detector Memory Usage</div>
310-
{detMemSeries.map((series) => (
311-
<ThresholdBarGraph
312-
key={series.name}
313-
graphId={`${series.name}-mem`}
314-
unit="%"
315-
name={series.name}
316-
threshold={DetectorMemThreshold}
317-
updateTimes={updateTimes}
318-
data={[series]}
319-
/>
320-
))}
321-
</div>
276+
<div className="w-full mt-4 grid grid-cols-1 sm:grid-cols-3 gap-2">
277+
{detInferenceTimeSeries.length != 0 ? (
278+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
279+
<div className="mb-5">Detector Inference Speed</div>
280+
{detInferenceTimeSeries.map((series) => (
281+
<ThresholdBarGraph
282+
key={series.name}
283+
graphId={`${series.name}-inference`}
284+
name={series.name}
285+
unit="ms"
286+
threshold={InferenceThreshold}
287+
updateTimes={updateTimes}
288+
data={[series]}
289+
/>
290+
))}
291+
</div>
292+
) : (
293+
<Skeleton className="w-full aspect-video" />
294+
)}
295+
{statsHistory.length != 0 ? (
296+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
297+
<div className="mb-5">Detector CPU Usage</div>
298+
{detCpuSeries.map((series) => (
299+
<ThresholdBarGraph
300+
key={series.name}
301+
graphId={`${series.name}-cpu`}
302+
unit="%"
303+
name={series.name}
304+
threshold={DetectorCpuThreshold}
305+
updateTimes={updateTimes}
306+
data={[series]}
307+
/>
308+
))}
309+
</div>
310+
) : (
311+
<Skeleton className="w-full aspect-video" />
312+
)}
313+
{statsHistory.length != 0 ? (
314+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
315+
<div className="mb-5">Detector Memory Usage</div>
316+
{detMemSeries.map((series) => (
317+
<ThresholdBarGraph
318+
key={series.name}
319+
graphId={`${series.name}-mem`}
320+
unit="%"
321+
name={series.name}
322+
threshold={DetectorMemThreshold}
323+
updateTimes={updateTimes}
324+
data={[series]}
325+
/>
326+
))}
327+
</div>
328+
) : (
329+
<Skeleton className="w-full aspect-video" />
330+
)}
322331
</div>
323332

324-
{statsHistory.length > 0 && statsHistory[0].gpu_usages && (
333+
{(statsHistory.length == 0 || statsHistory[0].gpu_usages) && (
325334
<>
326335
<div className="mt-4 flex items-center justify-between">
327336
<div className="text-muted-foreground text-sm font-medium">
328337
GPUs
329338
</div>
330-
{Object.keys(statsHistory[0].gpu_usages).filter(
331-
(key) =>
332-
key == "amd-vaapi" ||
333-
key == "intel-vaapi" ||
334-
key == "intel-qsv",
335-
).length > 0 && (
336-
<Button
337-
className="cursor-pointer"
338-
variant="secondary"
339-
size="sm"
340-
onClick={() => setShowVainfo(true)}
341-
>
342-
Hardware Info
343-
</Button>
344-
)}
339+
{statsHistory.length > 0 &&
340+
Object.keys(statsHistory[0].gpu_usages ?? {}).filter(
341+
(key) =>
342+
key == "amd-vaapi" ||
343+
key == "intel-vaapi" ||
344+
key == "intel-qsv",
345+
).length > 0 && (
346+
<Button
347+
className="cursor-pointer"
348+
variant="secondary"
349+
size="sm"
350+
onClick={() => setShowVainfo(true)}
351+
>
352+
Hardware Info
353+
</Button>
354+
)}
345355
</div>
346356
<div className=" mt-4 grid grid-cols-1 sm:grid-cols-2 gap-2">
347-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
348-
<div className="mb-5">GPU Usage</div>
349-
{gpuSeries.map((series) => (
350-
<ThresholdBarGraph
351-
key={series.name}
352-
graphId={`${series.name}-gpu`}
353-
name={series.name}
354-
unit=""
355-
threshold={GPUUsageThreshold}
356-
updateTimes={updateTimes}
357-
data={[series]}
358-
/>
359-
))}
360-
</div>
361-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
362-
<div className="mb-5">GPU Memory</div>
363-
{gpuMemSeries.map((series) => (
364-
<ThresholdBarGraph
365-
key={series.name}
366-
graphId={`${series.name}-mem`}
367-
unit=""
368-
name={series.name}
369-
threshold={GPUMemThreshold}
370-
updateTimes={updateTimes}
371-
data={[series]}
372-
/>
373-
))}
374-
</div>
357+
{statsHistory.length != 0 ? (
358+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
359+
<div className="mb-5">GPU Usage</div>
360+
{gpuSeries.map((series) => (
361+
<ThresholdBarGraph
362+
key={series.name}
363+
graphId={`${series.name}-gpu`}
364+
name={series.name}
365+
unit=""
366+
threshold={GPUUsageThreshold}
367+
updateTimes={updateTimes}
368+
data={[series]}
369+
/>
370+
))}
371+
</div>
372+
) : (
373+
<Skeleton className="w-full aspect-video" />
374+
)}
375+
{statsHistory.length != 0 ? (
376+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
377+
<div className="mb-5">GPU Memory</div>
378+
{gpuMemSeries.map((series) => (
379+
<ThresholdBarGraph
380+
key={series.name}
381+
graphId={`${series.name}-mem`}
382+
unit=""
383+
name={series.name}
384+
threshold={GPUMemThreshold}
385+
updateTimes={updateTimes}
386+
data={[series]}
387+
/>
388+
))}
389+
</div>
390+
) : (
391+
<Skeleton className="w-full aspect-video" />
392+
)}
375393
</div>
376394
</>
377395
)}
@@ -380,34 +398,42 @@ export default function GeneralMetrics({
380398
Other Processes
381399
</div>
382400
<div className="mt-4 grid grid-cols-1 sm:grid-cols-2 gap-2">
383-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
384-
<div className="mb-5">Process CPU Usage</div>
385-
{otherProcessCpuSeries.map((series) => (
386-
<ThresholdBarGraph
387-
key={series.name}
388-
graphId={`${series.name}-cpu`}
389-
name={series.name.replaceAll("_", " ")}
390-
unit="%"
391-
threshold={DetectorCpuThreshold}
392-
updateTimes={updateTimes}
393-
data={[series]}
394-
/>
395-
))}
396-
</div>
397-
<div className="p-2.5 bg-primary rounded-2xl flex-col">
398-
<div className="mb-5">Process Memory Usage</div>
399-
{otherProcessMemSeries.map((series) => (
400-
<ThresholdBarGraph
401-
key={series.name}
402-
graphId={`${series.name}-mem`}
403-
unit="%"
404-
name={series.name.replaceAll("_", " ")}
405-
threshold={DetectorMemThreshold}
406-
updateTimes={updateTimes}
407-
data={[series]}
408-
/>
409-
))}
410-
</div>
401+
{statsHistory.length != 0 ? (
402+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
403+
<div className="mb-5">Process CPU Usage</div>
404+
{otherProcessCpuSeries.map((series) => (
405+
<ThresholdBarGraph
406+
key={series.name}
407+
graphId={`${series.name}-cpu`}
408+
name={series.name.replaceAll("_", " ")}
409+
unit="%"
410+
threshold={DetectorCpuThreshold}
411+
updateTimes={updateTimes}
412+
data={[series]}
413+
/>
414+
))}
415+
</div>
416+
) : (
417+
<Skeleton className="w-full aspect-tall" />
418+
)}
419+
{statsHistory.length != 0 ? (
420+
<div className="p-2.5 bg-primary rounded-2xl flex-col">
421+
<div className="mb-5">Process Memory Usage</div>
422+
{otherProcessMemSeries.map((series) => (
423+
<ThresholdBarGraph
424+
key={series.name}
425+
graphId={`${series.name}-mem`}
426+
unit="%"
427+
name={series.name.replaceAll("_", " ")}
428+
threshold={DetectorMemThreshold}
429+
updateTimes={updateTimes}
430+
data={[series]}
431+
/>
432+
))}
433+
</div>
434+
) : (
435+
<Skeleton className="w-full aspect-tall" />
436+
)}
411437
</div>
412438
</div>
413439
</>

0 commit comments

Comments
 (0)