mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
perf: bound concurrency in authService profile hydration
Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
216361ed77
commit
69c1528ac0
5 files changed
+78
-16
No files matched your search
+25
-3
@@ -1,3 +1,25 @@
|
|||||||
Node Version: v22.22.0
|
# CONTEXT - bitvid-perf-agent
|
||||||
NPM Version: 11.7.0
|
|
||||||
Date: Thu Feb 12 14:32:45 UTC 2026
|
## Goal
|
||||||
|
Daily, measurable improvement of app responsiveness by identifying and remediating background CPU/network work that degrades UX — while also ensuring user-facing docs (/content) reflect the actual runtime behavior of upload/contribution flows.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
- Repo: `PR0M3TH3AN/bitvid` (unstable branch).
|
||||||
|
- Focus Areas:
|
||||||
|
- P0: Login/auth, relay initialization, decryption (hashtags, subscriptions, blocks, watch history).
|
||||||
|
- P1: Initial UI responsiveness (profile cache, relay load).
|
||||||
|
- P2: User-initiated background features (WebTorrent).
|
||||||
|
- Docs: `/content` (user-facing docs), ensuring upload/contribution docs match code.
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
- Never invent files, APIs, libraries, or behaviors.
|
||||||
|
- Prefer minimal incremental changes.
|
||||||
|
- Keep build/tests green.
|
||||||
|
- Preserve repo style and architecture.
|
||||||
|
- Security-critical changes require human signoff.
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
- Performance issues identified and fixed with small, safe PRs.
|
||||||
|
- Docs in `/content` matched to code.
|
||||||
|
- `daily-perf-report` generated.
|
||||||
|
- Artifacts (`TODO.md`, `DECISIONS.md`, `TEST_LOG.md`) updated.
|
||||||
@@ -23,3 +23,14 @@ Ran a daily dependency audit. Found `esbuild` (0.27.2 -> 0.27.3) as a safe candi
|
|||||||
- **Outcome:** BLOCKED (Major Version).
|
- **Outcome:** BLOCKED (Major Version).
|
||||||
- **Reason:** Major version bump (v3 -> v4) carries significant risk of breaking changes.
|
- **Reason:** Major version bump (v3 -> v4) carries significant risk of breaking changes.
|
||||||
- **Action:** Existing issue `issues/upgrade-tailwindcss.md` is sufficient.
|
- **Action:** Existing issue `issues/upgrade-tailwindcss.md` is sufficient.
|
||||||
|
|
||||||
|
## 2026-02-18: Performance - Bounded Concurrency in AuthService
|
||||||
|
|
||||||
|
### Context
|
||||||
|
`loadOwnProfile` in `js/services/authService.js` was using `Promise.allSettled` on all background relays simultaneously. For users with many relays (e.g., 50+), this caused a massive spike in network requests and CPU usage during login/startup.
|
||||||
|
|
||||||
|
### Decision: Use `pMap` with Concurrency Limit
|
||||||
|
- **Proposal:** Replace `Promise.allSettled` with `pMap` for background relays.
|
||||||
|
- **Outcome:** IMPLEMENTED.
|
||||||
|
- **Reason:** To prevent network saturation and UI freeze.
|
||||||
|
- **Details:** Used `RELAY_BACKGROUND_CONCURRENCY` (3) to limit concurrent background requests. Fast relays (top 3) are still fetched in parallel (unbounded, but small set).
|
||||||
@@ -9,3 +9,6 @@
|
|||||||
|
|
||||||
## Priority: Low (Maintenance)
|
## Priority: Low (Maintenance)
|
||||||
- [ ] Batch upgrade dev dependencies (`stylelint`, `postcss-import`).
|
- [ ] Batch upgrade dev dependencies (`stylelint`, `postcss-import`).
|
||||||
|
|
||||||
|
## Priority: High (Performance)
|
||||||
|
- [x] Bound concurrency in `authService.js` for profile hydration (P0).
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Daily Performance Report - 2026-02-18
|
||||||
|
|
||||||
|
**Summary:** Bounded concurrency in `authService` profile hydration; verified upload docs.
|
||||||
|
|
||||||
|
## Findings & Fixes
|
||||||
|
- **P0 Fix:** `js/services/authService.js` was launching unbounded concurrent requests for profile hydration.
|
||||||
|
- **Fix:** Implemented `pMap` with `RELAY_BACKGROUND_CONCURRENCY` (3) for background relays.
|
||||||
|
- **Impact:** Prevents network saturation for users with many relays.
|
||||||
|
- **Docs Audit:** Verified `content/docs/guides/upload-content.md` correctly specifies port 3000 for CORS. No changes needed.
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
- **Tests:** `tests/authService.test.mjs` and `tests/auth-service.test.mjs` passed.
|
||||||
|
|
||||||
|
## Artifacts
|
||||||
|
- Updated `CONTEXT.md`, `TODO.md`, `DECISIONS.md`, `TEST_LOG.md`.
|
||||||
+24
-13
@@ -43,6 +43,8 @@ import {
|
|||||||
normalizeProviderId,
|
normalizeProviderId,
|
||||||
normalizeAuthType,
|
normalizeAuthType,
|
||||||
} from "./authUtils.js";
|
} from "./authUtils.js";
|
||||||
|
import { pMap } from "../utils/asyncUtils.js";
|
||||||
|
import { RELAY_BACKGROUND_CONCURRENCY } from "../nostr/relayConstants.js";
|
||||||
|
|
||||||
export default class AuthService {
|
export default class AuthService {
|
||||||
constructor({
|
constructor({
|
||||||
@@ -1146,21 +1148,30 @@ export default class AuthService {
|
|||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const backgroundPromises = backgroundRelays.map((relayUrl) =>
|
|
||||||
this.fetchProfileFromRelay(
|
|
||||||
relayUrl,
|
|
||||||
filter,
|
|
||||||
normalized,
|
|
||||||
BACKGROUND_PROFILE_TIMEOUT_MS,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const background = Promise.allSettled([
|
const background = Promise.all([
|
||||||
...fastPromises,
|
Promise.allSettled(fastPromises),
|
||||||
...backgroundPromises,
|
pMap(
|
||||||
|
backgroundRelays,
|
||||||
|
async (relayUrl) => {
|
||||||
|
try {
|
||||||
|
const value = await this.fetchProfileFromRelay(
|
||||||
|
relayUrl,
|
||||||
|
filter,
|
||||||
|
normalized,
|
||||||
|
BACKGROUND_PROFILE_TIMEOUT_MS,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
return { status: "fulfilled", value };
|
||||||
|
} catch (reason) {
|
||||||
|
return { status: "rejected", reason };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ concurrency: RELAY_BACKGROUND_CONCURRENCY },
|
||||||
|
),
|
||||||
])
|
])
|
||||||
.then((outcomes) => {
|
.then(([fastOutcomes, backgroundOutcomes]) => {
|
||||||
|
const outcomes = [...fastOutcomes, ...backgroundOutcomes];
|
||||||
const aggregated = [];
|
const aggregated = [];
|
||||||
outcomes.forEach((outcome) => {
|
outcomes.forEach((outcome) => {
|
||||||
if (outcome.status === "fulfilled") {
|
if (outcome.status === "fulfilled") {
|
||||||
|
|||||||
Reference in new issue
Block a user