Skip to content

Commit

Permalink
chore: performance improvements
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Nov 30, 2024
1 parent 37a08ab commit 1a9dac1
Show file tree
Hide file tree
Showing 16 changed files with 415 additions and 354 deletions.
255 changes: 125 additions & 130 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion data/licenses-npm.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/routes/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl EventApi {
let events = events.clone();

// run the event processing in the background
let _ = tokio::task::spawn_blocking(move || {
tokio::task::spawn_blocking(move || {
if let Err(e) = process_event(app, events, event, url, ip, user_agent) {
tracing::error!("Failed to process event: {:?}", e);
}
Expand Down
3 changes: 2 additions & 1 deletion web/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export default defineConfig({
template: (dependencies) => JSON.stringify(dependencies),
},
},
}),
// biome-ignore lint/suspicious/noExplicitAny: wrong type
}) as any,
],
},
integrations: [react()],
Expand Down
Binary file modified web/bun.lockb
Binary file not shown.
27 changes: 17 additions & 10 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"typecheck": "bun run --bun tsc --noEmit"
},
"dependencies": {
"@astrojs/react": "^3.6.3",
"@astrojs/react": "4.0.0-beta.2",
"@explodingcamera/css": "^0.0.4",
"@fontsource-variable/outfit": "^5.1.0",
"@icons-pack/react-simple-icons": "^10.2.0",
Expand All @@ -18,37 +18,44 @@
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.1",
"@tanstack/react-query": "^5.61.3",
"@uidotdev/usehooks": "^2.4.1",
"@tanstack/react-query": "^5.62.0",
"d3-array": "^3.2.4",
"d3-ease": "^3.0.1",
"d3-geo": "^3.1.1",
"d3-scale": "^4.0.2",
"d3-selection": "^3.0.0",
"d3-shape": "^3.2.0",
"d3-zoom": "^3.0.0",
"date-fns": "^4.1.0",
"fets": "^0.8.4",
"fuzzysort": "^3.1.0",
"geojson": "^0.5.0",
"little-date": "^1.0.0",
"lucide-react": "0.461.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"lucide-react": "0.462.0",
"react": "19.0.0-rc.1",
"react-dom": "19.0.0-rc.1",
"react-tag-autocomplete": "^7.4.0",
"react-tooltip": "^5.28.0",
"topojson-client": "^3.1.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/bun": "^1.1.13",
"@million/lint": "^1.0.13",
"@types/bun": "^1.1.14",
"@types/d3-array": "^3.2.1",
"@types/d3-ease": "^3.0.2",
"@types/d3-geo": "^3.1.0",
"@types/d3-scale": "^4.0.8",
"@types/d3-selection": "^3.0.11",
"@types/d3-shape": "^3.1.6",
"@types/d3-zoom": "^3.0.8",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/topojson-client": "^3.1.5",
"@types/topojson-specification": "^1.0.5",
"astro": "^4.16.14",
"astro": "5.0.0-beta.12",
"rollup-plugin-license": "^3.5.3",
"typescript": "^5.7.2"
},
"packageManager": "bun@1.1.36",
"packageManager": "bun@1.1.38",
"trustedDependencies": ["@biomejs/biome", "esbuild", "sharp"]
}
2 changes: 1 addition & 1 deletion web/src/api/dashboard.ts

Large diffs are not rendered by default.

95 changes: 50 additions & 45 deletions web/src/api/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useMemo } from "react";
import { toDataPoints } from "../components/graph";
import type { Dimension, DimensionFilter, DimensionTableRow, Metric, ProjectResponse } from "./types";

import { api } from ".";
import { api } from "./client";
import { queryClient, useQuery } from "./query";
import type { DateRange } from "./ranges";

Expand Down Expand Up @@ -96,19 +96,20 @@ export const useDimension = ({
.json(),
});

const biggest = useMemo(() => data?.data?.reduce((acc, d) => Math.max(acc, d.value), 0) ?? 0, [data]);
const order = useMemo(() => data?.data?.sort((a, b) => b.value - a.value).map((d) => d.dimensionValue), [data]);

return { data: data?.data, biggest, order, isLoading, error };
return useMemo(() => {
const biggest = data?.data?.reduce((acc, d) => Math.max(acc, d.value), 0) ?? 0;
const order = data?.data?.sort((a, b) => b.value - a.value).map((d) => d.dimensionValue);
return { data: data?.data, biggest, order, isLoading, error };
}, [data, isLoading, error]);
};

export const useProjectData = ({
project,
export const useProjectGraph = ({
projectId,
metric,
range,
filters = [],
}: {
project?: ProjectResponse;
projectId?: string;
metric: Metric;
range: DateRange;
filters?: DimensionFilter[];
Expand All @@ -122,61 +123,65 @@ export const useProjectData = ({
const dataPoints = range.getGraphDataPoints();

const {
data: stats,
isError: isErrorStats,
isLoading: isLoadingStats,
data: graph,
isError,
isLoading,
} = useQuery({
refetchInterval,
staleTime,
queryKey: ["project_stats", project?.id, range.cacheKey(), metric, filters],

enabled: project !== undefined,
enabled: projectId !== undefined,
queryKey: ["project_graph", projectId, range.cacheKey(), metric, filters, dataPoints],
queryFn: () =>
api["/api/dashboard/project/{project_id}/stats"]
.post({ json: { range: range.toAPI(), filters }, params: { project_id: project?.id ?? "" } })
.json(),
api["/api/dashboard/project/{project_id}/graph"]
.post({
json: { range: range.toAPI(), metric, dataPoints, filters },
params: { project_id: projectId ?? "" },
})
.json()
.then(({ data }) => toDataPoints(data, range, metric)),
placeholderData: (prev) => prev,
});

return {
graph,
isLoading,
isError,
};
};

export const useProjectStats = ({
projectId,
metric,
range,
filters = [],
}: {
projectId?: string;
metric: Metric;
range: DateRange;
filters?: DimensionFilter[];
}) => {
const {
data: graph,
isError: isErrorGraph,
isLoading: isLoadingGraph,
data: stats,
isError,
isLoading,
} = useQuery({
refetchInterval,
staleTime,
enabled: project !== undefined,
queryKey: ["project_graph", project?.id, range.cacheKey(), metric, filters, dataPoints],
queryKey: ["project_stats", projectId, range.cacheKey(), metric, filters],

enabled: projectId !== undefined,
queryFn: () =>
api["/api/dashboard/project/{project_id}/graph"]
.post({
json: { range: range.toAPI(), metric, dataPoints, filters },
params: { project_id: project?.id ?? "" },
})
api["/api/dashboard/project/{project_id}/stats"]
.post({ json: { range: range.toAPI(), filters }, params: { project_id: projectId ?? "" } })
.json(),
placeholderData: (prev) => prev,
});

return {
stats: {
error: isErrorStats,
loading: isLoadingStats,
data: stats,
},
graph: {
error: isErrorGraph,
loading: isLoadingGraph,
range,
data: graph?.data ? toDataPoints(graph.data, range, metric) : [],
},
isLoading: isLoadingStats || isLoadingGraph,
isError: isErrorStats || isErrorGraph,
stats,
isLoading,
isError,
};
};

export type ProjectDataGraph = ReturnType<typeof useProjectData>["graph"];
export type ProjectDataStats = ReturnType<typeof useProjectData>["stats"];

export const invalidateProjects = () => queryClient.invalidateQueries({ queryKey: ["projects"] });
export const invalidateEntities = () => queryClient.invalidateQueries({ queryKey: ["entities"] });
export const invalidateUsers = () => queryClient.invalidateQueries({ queryKey: ["users"] });
8 changes: 4 additions & 4 deletions web/src/components/dimensions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export const DimensionTable = (props: DimensionProps) => {
</div>
)}
</div>
<DetailsModal {...props} />
<DetailsModal dimension={props.dimension} query={props.query} />
</>
);
};
Expand All @@ -174,7 +174,7 @@ const DimensionValueButton = ({
onSelect,
}: {
children: React.ReactNode;
onSelect: () => void;
onSelect?: () => void;
}) => (
<button type="button" className={styles.dimensionItemSelect} onClick={onSelect}>
{children}
Expand Down Expand Up @@ -307,8 +307,8 @@ export const DimensionLabel = ({
dimension,
value,
onSelect,
}: { dimension: Dimension; value: DimensionTableRow; onSelect: (value: DimensionTableRow) => void }) =>
dimensionLabels[dimension](value, () => onSelect(value));
}: { dimension: Dimension; value: DimensionTableRow; onSelect?: (value: DimensionTableRow) => void }) =>
dimensionLabels[dimension](value, () => onSelect?.(value));

export const DimensionValueBar = ({
value,
Expand Down
4 changes: 1 addition & 3 deletions web/src/components/dimensions/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import type { ProjectQuery } from "../project";
export const DetailsModal = ({
dimension,
query,
onSelect,
}: {
dimension: Dimension;
query: ProjectQuery;
onSelect: (value: DimensionTableRow, dimension: Dimension) => void;
}) => {
const { data, biggest, order, isLoading } = useDimension({ dimension, ...query });

Expand Down Expand Up @@ -64,7 +62,7 @@ export const DetailsModal = ({
className={styles.dimensionRow}
>
<DimensionValueBar value={d.value} biggest={biggest}>
<DimensionLabel dimension={dimension} value={d} onSelect={() => onSelect(d, dimension)} />
<DimensionLabel dimension={dimension} value={d} />
</DimensionValueBar>
<div>{formatMetricVal(d.value, query.metric)}</div>
</div>
Expand Down
12 changes: 8 additions & 4 deletions web/src/components/graph/graph.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from "react";
import { useCallback, useMemo } from "react";
import styles from "./graph.module.css";

import { ResponsiveLine, type SliceTooltipProps } from "@nivo/line";
Expand Down Expand Up @@ -54,10 +54,14 @@ export const LineGraph = ({
range: DateRange;
metric: Metric;
}) => {
const axisRange = range.getAxisRange();
const max = useMemo(() => Math.max(...data.map((d) => d.y)), [data]);
const yCount = 5;
const tooltip = useCallback(
(props: SliceTooltipProps) => <Tooltip {...props} title={title} range={range} metric={metric} />,
[title, range, metric],
);

const axisRange = range.getAxisRange();
const yCount = 5;
const size = useWindowSize();
let xCount = Math.min(data.length, 8);
if (size.width && size.width < 1000) {
Expand Down Expand Up @@ -100,7 +104,7 @@ export const LineGraph = ({
pointLabel="data.yFormatted"
pointLabelYOffset={-12}
enableSlices="x"
sliceTooltip={(props) => <Tooltip {...props} metric={metric} title={title} range={range} />}
sliceTooltip={tooltip}
defs={[
{
colors: [
Expand Down
5 changes: 5 additions & 0 deletions web/src/components/project.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
padding: 1rem 0 1rem 0.5rem;
}

.graphCard2 {
height: 20rem;
padding: 0 !important;
}

.geoCard.geoCard {
padding: 0;
grid-column: span 2;
Expand Down
Loading

0 comments on commit 1a9dac1

Please sign in to comment.