A quick vibe-coded site to test response times of PLC.directory mirrors (over 3 attempts)

feat: prevent browser cache & use PerformanceObserver

Changed files
+191 -102
src
components
pages
utils
+67 -44
src/components/BenchmarkTable.tsx
···
const allSuccessfulAttempts = sortedResults.flatMap((r) =>
r.attempts.filter((a) => a.status === "success")
);
-
const overallAvg =
-
allSuccessfulAttempts.length > 0
-
? allSuccessfulAttempts.reduce((sum, a) => sum + a.responseTime, 0) /
-
allSuccessfulAttempts.length
-
: 0;
+
const overallAvg = allSuccessfulAttempts.length > 0
+
? allSuccessfulAttempts.reduce((sum, a) => sum + a.responseTime, 0) /
+
allSuccessfulAttempts.length
+
: 0;
return (
<div className="space-y-4">
···
<TableRow className="bg-muted/50">
<TableHead className="font-semibold">URL</TableHead>
<TableHead className="font-semibold">Implementation</TableHead>
-
<TableHead className="font-semibold text-center">Attempt 1</TableHead>
-
<TableHead className="font-semibold text-center">Attempt 2</TableHead>
-
<TableHead className="font-semibold text-center">Attempt 3</TableHead>
-
<TableHead className="font-semibold text-center">Average</TableHead>
+
<TableHead className="font-semibold text-center">
+
#1
+
</TableHead>
+
<TableHead className="font-semibold text-center">
+
#2
+
</TableHead>
+
<TableHead className="font-semibold text-center">
+
#3
+
</TableHead>
+
<TableHead className="font-semibold text-center">
+
#4
+
</TableHead>
+
<TableHead className="font-semibold text-center">
+
#5
+
</TableHead>
+
<TableHead className="font-semibold text-center">
+
Average
+
</TableHead>
<TableHead className="font-semibold">Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{sortedResults.map((result, index) => (
-
<TableRow key={index} className="hover:bg-muted/30 transition-colors">
+
<TableRow
+
key={index}
+
className="hover:bg-muted/30 transition-colors"
+
>
<TableCell className="font-mono text-sm text-muted-foreground">
{result.mirrorUrl}
</TableCell>
···
{result.implementation}
</TableCell>
{result.attempts.map((attempt, attemptIndex) => (
-
<TableCell key={attemptIndex} className="text-center font-mono text-sm">
-
{attempt.status === "success" ? (
-
<span className="text-foreground">
-
{attempt.responseTime.toFixed(0)}ms
-
</span>
-
) : (
-
<span className="text-destructive">
-
<XCircle className="w-4 h-4 inline" />
-
</span>
-
)}
+
<TableCell
+
key={attemptIndex}
+
className="text-center font-mono text-sm"
+
>
+
{attempt.status === "success"
+
? (
+
<span className="text-foreground">
+
{attempt.responseTime.toFixed(0)}ms
+
</span>
+
)
+
: (
+
<span className="text-destructive">
+
<XCircle className="w-4 h-4 inline" />
+
</span>
+
)}
</TableCell>
))}
<TableCell className="text-center font-mono text-sm">
-
{result.status === "success" ? (
-
<span className="font-bold text-primary text-base">
-
{result.avgResponseTime.toFixed(0)}ms
-
</span>
-
) : (
-
<span className="text-muted-foreground">—</span>
-
)}
+
{result.status === "success"
+
? (
+
<span className="font-bold text-primary text-base">
+
{result.avgResponseTime.toFixed(0)}ms
+
</span>
+
)
+
: <span className="text-muted-foreground">—</span>}
</TableCell>
<TableCell>
-
{result.status === "success" ? (
-
<Badge
-
variant="outline"
-
className="bg-success/10 text-success border-success/20 gap-1"
-
>
-
<CheckCircle2 className="w-3 h-3" />
-
Success
-
</Badge>
-
) : (
-
<Badge
-
variant="outline"
-
className="bg-destructive/10 text-destructive border-destructive/20 gap-1"
-
>
-
<XCircle className="w-3 h-3" />
-
Error
-
</Badge>
-
)}
+
{result.status === "success"
+
? (
+
<Badge
+
variant="outline"
+
className="bg-success/10 text-success border-success/20 gap-1"
+
>
+
<CheckCircle2 className="w-3 h-3" />
+
Success
+
</Badge>
+
)
+
: (
+
<Badge
+
variant="outline"
+
className="bg-destructive/10 text-destructive border-destructive/20 gap-1"
+
>
+
<XCircle className="w-3 h-3" />
+
Error
+
</Badge>
+
)}
</TableCell>
</TableRow>
))}
+42 -21
src/pages/Index.tsx
···
const resolveHandle = async (handle: string): Promise<string | null> => {
try {
const response = await fetch(
-
`https://quickdid.smokesignal.tools/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`
+
`https://quickdid.smokesignal.tools/xrpc/com.atproto.identity.resolveHandle?handle=${
+
encodeURIComponent(handle)
+
}`,
);
const data = await response.json();
-
+
if (data.error) {
-
toast.error(`Unable to resolve handle: ${data.message || "Invalid handle"}`);
+
toast.error(
+
`Unable to resolve handle: ${data.message || "Invalid handle"}`,
+
);
return null;
}
-
+
return data.did;
} catch (error) {
toast.error("Failed to resolve handle");
···
try {
let resolvedDid = did.trim();
-
+
// If input doesn't start with "did:plc", treat it as a handle
if (!resolvedDid.startsWith("did:plc")) {
const resolved = await resolveHandle(resolvedDid);
···
const benchmarkResults = await benchmarkAllMirrors(mirrors, resolvedDid);
setResults(benchmarkResults);
-
-
const successCount = benchmarkResults.filter(r => r.status === "success").length;
-
toast.success(`Benchmark complete! ${successCount}/${benchmarkResults.length} mirrors responded`);
+
+
const successCount = benchmarkResults.filter((r) =>
+
r.status === "success"
+
).length;
+
toast.success(
+
`Benchmark complete! ${successCount}/${benchmarkResults.length} mirrors responded`,
+
);
} catch (error) {
toast.error("Failed to run benchmark");
console.error(error);
···
<h1 className="text-4xl font-bold">PLC Mirror Benchmark</h1>
</div>
<p className="text-muted-foreground text-lg max-w-2xl mx-auto">
-
Test and compare response times across different PLC.directory mirrors
+
Test and compare response times across different PLC.directory
+
mirrors
</p>
</header>
···
<div className="bg-card border border-border rounded-lg p-6 shadow-sm">
<div className="space-y-4">
<div>
-
<label htmlFor="did-input" className="block text-sm font-medium mb-2">
+
<label
+
htmlFor="did-input"
+
className="block text-sm font-medium mb-2"
+
>
ATProto DID or Handle
</label>
<div className="flex gap-3">
···
</div>
</div>
<div className="text-sm text-muted-foreground">
-
Testing {mirrors.length} mirrors with 3 attempts each
+
Testing {mirrors.length} mirrors with 5 attempts each
</div>
</div>
</div>
···
{(results.length > 0 || loading) && (
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Results</h2>
-
{loading ? (
-
<div className="bg-card border border-border rounded-lg p-12 text-center">
-
<div className="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-primary mb-4"></div>
-
<p className="text-muted-foreground">Benchmarking mirrors...</p>
-
</div>
-
) : (
-
<BenchmarkTable results={results} />
-
)}
+
{loading
+
? (
+
<div className="bg-card border border-border rounded-lg p-12 text-center">
+
<div className="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-primary mb-4">
+
</div>
+
<p className="text-muted-foreground">
+
Benchmarking mirrors...
+
</p>
+
</div>
+
)
+
: <BenchmarkTable results={results} />}
</div>
)}
···
<div className="bg-muted/30 border border-border rounded-lg p-6">
<h3 className="font-semibold mb-2">How to use:</h3>
<ol className="list-decimal list-inside space-y-1 text-sm text-muted-foreground">
-
<li>Enter an ATProto DID or handle (e.g., did:plc:z72i7hdynmk6r22z27h6tvur or handle.bsky.social)</li>
+
<li>
+
Enter an ATProto DID or handle (e.g.,
+
did:plc:z72i7hdynmk6r22z27h6tvur or handle.bsky.social)
+
</li>
<li>Click "Run Benchmark" or press Enter</li>
<li>View response times and status for each mirror</li>
</ol>
<div className="mt-4 pt-4 border-t border-border">
<p className="text-sm text-muted-foreground">
-
Mirrors can be configured in <code className="bg-background px-2 py-1 rounded text-mono">src/config/mirrors.ts</code>
+
Mirrors can be configured in{" "}
+
<code className="bg-background px-2 py-1 rounded text-mono">
+
src/config/mirrors.ts
+
</code>
</p>
</div>
</div>
+82 -37
src/utils/benchmark.ts
···
import { Mirror } from "@/config/mirrors";
-
import { BenchmarkResult, BenchmarkAttempt } from "@/types/benchmark";
+
import { BenchmarkAttempt, BenchmarkResult } from "@/types/benchmark";
-
const ATTEMPTS_PER_MIRROR = 3;
+
const ATTEMPTS_PER_MIRROR = 5;
const singleAttempt = async (
url: string,
-
did: string
+
did: string,
): Promise<BenchmarkAttempt> => {
const fullUrl = `${url}/${did}`;
-
const startTime = performance.now();
+
const uniqueUrl = `${fullUrl}?i=${Date.now()}`;
-
try {
-
const response = await fetch(fullUrl);
-
const endTime = performance.now();
-
const responseTime = endTime - startTime;
+
return new Promise((resolve) => {
+
const observer = new PerformanceObserver((list) => {
+
const entries = list.getEntries();
+
const entry = entries.find(
+
(e) => e.entryType === "resource" && e.name === uniqueUrl,
+
) as PerformanceResourceTiming | undefined;
-
if (!response.ok) {
-
return {
-
responseTime,
-
status: "error",
-
statusCode: response.status,
-
error: `HTTP ${response.status}`,
-
};
-
}
+
if (entry) {
+
observer.disconnect();
-
await response.json(); // Consume the response
+
// Use duration for total time, or calculate from start/response
+
const responseTime = entry.duration ||
+
(entry.responseEnd - entry.startTime);
+
+
resolve({
+
responseTime,
+
status: "success",
+
statusCode: 200, // PerformanceResourceTiming doesn't provide status code
+
});
+
}
+
});
+
+
observer.observe({ entryTypes: ["resource"] });
+
+
// Start the fetch
+
fetch(uniqueUrl, {
+
cache: "no-store",
+
})
+
.then(async (response) => {
+
if (!response.ok) {
+
observer.disconnect();
+
resolve({
+
responseTime: 0,
+
status: "error",
+
statusCode: response.status,
+
error: `HTTP ${response.status}`,
+
});
+
return;
+
}
+
+
await response.json(); // Consume the response
-
return {
-
responseTime,
-
status: "success",
-
statusCode: response.status,
-
};
-
} catch (error) {
-
const endTime = performance.now();
-
return {
-
responseTime: endTime - startTime,
-
status: "error",
-
error: error instanceof Error ? error.message : "Unknown error",
-
};
-
}
+
// Wait briefly for PerformanceObserver to capture the entry
+
setTimeout(() => {
+
const entries = performance.getEntriesByName(uniqueUrl, "resource");
+
if (entries.length > 0) {
+
const entry = entries[0] as PerformanceResourceTiming;
+
const responseTime = entry.duration ||
+
(entry.responseEnd - entry.startTime);
+
observer.disconnect();
+
resolve({
+
responseTime,
+
status: "success",
+
statusCode: response.status,
+
});
+
} else {
+
// Fallback if entry not found
+
observer.disconnect();
+
resolve({
+
responseTime: 0,
+
status: "error",
+
error: "Performance entry not found",
+
});
+
}
+
}, 100);
+
})
+
.catch((error) => {
+
observer.disconnect();
+
resolve({
+
responseTime: 0,
+
status: "error",
+
error: error instanceof Error ? error.message : "Unknown error",
+
});
+
});
+
});
};
export const benchmarkMirror = async (
mirror: Mirror,
-
did: string
+
did: string,
): Promise<BenchmarkResult> => {
const attempts: BenchmarkAttempt[] = [];
···
}
const successfulAttempts = attempts.filter((a) => a.status === "success");
-
const avgResponseTime =
-
successfulAttempts.length > 0
-
? successfulAttempts.reduce((sum, a) => sum + a.responseTime, 0) /
-
successfulAttempts.length
-
: 0;
+
const avgResponseTime = successfulAttempts.length > 0
+
? successfulAttempts.reduce((sum, a) => sum + a.responseTime, 0) /
+
successfulAttempts.length
+
: 0;
return {
mirrorUrl: mirror.url,
···
export const benchmarkAllMirrors = async (
mirrors: Mirror[],
-
did: string
+
did: string,
): Promise<BenchmarkResult[]> => {
const promises = mirrors.map((mirror) => benchmarkMirror(mirror, did));
return Promise.all(promises);