From 7847a9e78197435a665be2f5a1f4528d424dd043 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Thu, 21 Apr 2022 01:00:08 -0500 Subject: [PATCH] Track latency of feed and portfolio page. --- common/tracking.ts | 6 ++++++ firestore.rules | 4 ++++ web/components/bets-list.tsx | 10 ++++++++++ web/hooks/use-algo-feed.ts | 6 ++++++ web/hooks/use-time-since-first-render.ts | 13 +++++++++++++ web/lib/firebase/tracking.ts | 18 +++++++++++++++++- 6 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 web/hooks/use-time-since-first-render.ts diff --git a/common/tracking.ts b/common/tracking.ts index 29a1365c..bf06b6e3 100644 --- a/common/tracking.ts +++ b/common/tracking.ts @@ -10,3 +10,9 @@ export type ClickEvent = { contractId: string timestamp: number } + +export type LatencyEvent = { + type: 'feed' | 'portfolio' + latency: number + timestamp: number +} diff --git a/firestore.rules b/firestore.rules index 542bd5ec..09d65aac 100644 --- a/firestore.rules +++ b/firestore.rules @@ -30,6 +30,10 @@ service cloud.firestore { allow create: if userId == request.auth.uid; } + match /private-users/{userId}/latency/{loadTimeId} { + allow create: if userId == request.auth.uid; + } + match /contracts/{contractId} { allow read; allow update: if request.resource.data.diff(resource.data).affectedKeys() diff --git a/web/components/bets-list.tsx b/web/components/bets-list.tsx index 35e0b3d9..63cbfd57 100644 --- a/web/components/bets-list.tsx +++ b/web/components/bets-list.tsx @@ -37,6 +37,8 @@ import { resolvedPayout, getContractBetNullMetrics, } from '../../common/calculate' +import { useTimeSinceFirstRender } from '../hooks/use-time-since-first-render' +import { trackLatency } from '../lib/firebase/tracking' type BetSort = 'newest' | 'profit' | 'closeTime' | 'value' type BetFilter = 'open' | 'closed' | 'resolved' | 'all' @@ -67,6 +69,14 @@ export function BetsList(props: { user: User }) { } }, [bets]) + const getTime = useTimeSinceFirstRender() + useEffect(() => { + if (bets && contracts) { + trackLatency('portfolio', getTime()) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [!!bets, !!contracts]) + if (!bets || !contracts) { return } diff --git a/web/hooks/use-algo-feed.ts b/web/hooks/use-algo-feed.ts index f27a1870..543f484b 100644 --- a/web/hooks/use-algo-feed.ts +++ b/web/hooks/use-algo-feed.ts @@ -14,6 +14,8 @@ import { getOutcomeProbability, getTopAnswer, } from '../../common/calculate' +import { useTimeSinceFirstRender } from './use-time-since-first-render' +import { trackLatency } from '../lib/firebase/tracking' const MAX_FEED_CONTRACTS = 75 @@ -35,6 +37,8 @@ export const useAlgoFeed = ( const [algoFeed, setAlgoFeed] = useState([]) + const getTime = useTimeSinceFirstRender() + useEffect(() => { if ( initialContracts && @@ -53,6 +57,7 @@ export const useAlgoFeed = ( seenContracts ) setAlgoFeed(contracts) + trackLatency('feed', getTime()) } }, [ initialBets, @@ -60,6 +65,7 @@ export const useAlgoFeed = ( initialContracts, seenContracts, yourBetContractIds, + getTime, ]) return algoFeed diff --git a/web/hooks/use-time-since-first-render.ts b/web/hooks/use-time-since-first-render.ts new file mode 100644 index 00000000..da132146 --- /dev/null +++ b/web/hooks/use-time-since-first-render.ts @@ -0,0 +1,13 @@ +import { useCallback, useEffect, useRef } from 'react' + +export function useTimeSinceFirstRender() { + const startTimeRef = useRef(0) + useEffect(() => { + startTimeRef.current = Date.now() + }, []) + + return useCallback(() => { + if (!startTimeRef.current) return 0 + return Date.now() - startTimeRef.current + }, []) +} diff --git a/web/lib/firebase/tracking.ts b/web/lib/firebase/tracking.ts index 4d609f68..034ad09d 100644 --- a/web/lib/firebase/tracking.ts +++ b/web/lib/firebase/tracking.ts @@ -2,7 +2,7 @@ import { doc, collection, setDoc } from 'firebase/firestore' import _ from 'lodash' import { db } from './init' -import { ClickEvent, View } from '../../../common/tracking' +import { ClickEvent, LatencyEvent, View } from '../../../common/tracking' import { listenForLogin, User } from './users' let user: User | null = null @@ -34,3 +34,19 @@ export async function trackClick(contractId: string) { return await setDoc(ref, clickEvent) } + +export async function trackLatency( + type: 'feed' | 'portfolio', + latency: number +) { + if (!user) return + const ref = doc(collection(db, 'private-users', user.id, 'latency')) + + const latencyEvent: LatencyEvent = { + type, + latency, + timestamp: Date.now(), + } + + return await setDoc(ref, latencyEvent) +}