perf: performance improvements 1
This commit is contained in:
@@ -78,6 +78,12 @@ This area does **not** own:
|
||||
- Transfers are between connected peers only (no server CDN).
|
||||
- Receive strategy is decided once at request time by `canReceiveAttachment` (`attachment.logic.ts`): ≤ 10 MB assembles in memory everywhere; > 10 MB streams to disk on Electron/Capacitor, assembles in memory on the browser up to its 50 MB persist cap, and is rejected with a visible `fileTooLarge` error beyond that. `handleFileChunk` must accept whatever the request gate admitted — a stricter chunk-time size cap silently drops chunks and stalls the transfer.
|
||||
- Visibility-based blob lifecycle on desktop: revoke `blob:` URLs when messages scroll off-screen if disk can rehydrate.
|
||||
- Display-blob memory invariants (added 2026-07-14, RAM investigation):
|
||||
- Inline hydration (`chat-message-item` effect) only runs for messages that are visible or within the `IntersectionObserver` root margin — gated by `attachment-hydration-visibility.rules.ts`. Off-screen rows never load blobs.
|
||||
- Disk-hydrated blobs are **not** duplicated into `AttachmentRuntimeStore.originalFiles`; peer requests are served from the disk path (`streamRequestedFile` prefers `resolveExistingPath`). `originalFiles` only holds uploads/downloads that have no disk copy yet.
|
||||
- `revokeAttachmentDisplayBlob` also drops the `originalFiles` entry when `savedPath` exists, so revocation actually frees the bytes.
|
||||
- Message rows always revoke their display blobs on destroy (pins are respected), not only when they were visible.
|
||||
- Room switch sweeps display blobs of all other rooms (`releaseDisplayBlobsForInactiveRooms`, driven by `collectMessageIdsForInactiveRoomBlobRelease`). Messages with unknown room mapping are left alone.
|
||||
- "Shared from your device" badge only when bytes are local to the viewing user.
|
||||
|
||||
---
|
||||
@@ -114,5 +120,6 @@ This area does **not** own:
|
||||
|
||||
| Date | Change |
|
||||
|------|--------|
|
||||
| 2026-07-14 | Blob-memory invariants: visibility-gated hydration, no `originalFiles` duplication for disk-backed blobs, revoke-on-destroy, inactive-room blob sweep |
|
||||
| 2026-07-13 | Capacitor download/export to public `Documents` via `CapacitorAttachmentExportService` |
|
||||
| 2026-07-05 | Expanded to full contract style |
|
||||
|
||||
@@ -95,8 +95,9 @@ Rules (`message-sync.rules.ts`, `message-integrity.rules.ts`):
|
||||
|
||||
- Merges are **additive** — sparser peers never wipe richer local history.
|
||||
- `findMissingIds` compares remote inventory to local `revision` / `headHash` (and legacy `ts` / `rc` / `ac`).
|
||||
- `INVENTORY_LIMIT` = 1_000_000 (safety ceiling for pathological rooms).
|
||||
- `INVENTORY_LIMIT` = `FULL_SYNC_LIMIT` = **20_000** (2026-07-14, RAM investigation; previously 1_000_000). Building an inventory or full-sync batch loads full message rows into memory, so the ceiling must stay bounded. Only the most recent 20k messages per room are reconciled peer-to-peer; older messages stay local-only. `ACCOUNT_SYNC_MESSAGE_LIMIT` follows `FULL_SYNC_LIMIT`.
|
||||
- Sync polling: 10 s when catching up, 15 min after a clean cycle (`SYNC_POLL_FAST_MS` / `SYNC_POLL_SLOW_MS`).
|
||||
- NgRx store retention: on room switch, inactive rooms are pruned to the most recent `CACHED_INACTIVE_ROOM_MESSAGE_LIMIT` = **100** messages each (`messages.reducer.ts`), keeping return-visit rendering instant while bounding store growth across many rooms. The active room is never pruned; the local DB keeps full history.
|
||||
|
||||
---
|
||||
|
||||
@@ -204,6 +205,7 @@ Deletes keep tombstone semantics (`isDeleted`, empty `content`) so inventory syn
|
||||
|
||||
| Date | Change |
|
||||
|------|--------|
|
||||
| 2026-07-14 | RAM bounds: `INVENTORY_LIMIT`/`FULL_SYNC_LIMIT` lowered to 20k (most recent messages reconcile); NgRx prunes inactive rooms to 100 cached messages on room switch |
|
||||
| 2026-07-13 | Incoming DMs raise system notifications through the notifications domain (previously unread-badge only) |
|
||||
| 2026-07-13 | Recipient matching for DM and `direct-call` events must span all local identity aliases (provisioned actor ids included) |
|
||||
| 2026-07-05 | Initial comprehensive messaging contract (replaces thin direct-messaging summary) |
|
||||
|
||||
@@ -40,7 +40,14 @@ Relay rules: RTC messages require shared server membership (except DM-specific t
|
||||
|
||||
## P2P data channel
|
||||
|
||||
Carries voice/screen control messages, chat, attachments, and state sync — not server-relayed. Data-channel failure triggers peer renegotiation or full rebuild (see realtime README).
|
||||
Carries voice/screen control messages, chat, attachments, and state sync — not server-relayed. Data-channel failure triggers peer renegotiation or full rebuild (see realtime README). When a failed control channel is replaced (`replaceDataChannel`), the old channel is closed first so its SCTP resources are released.
|
||||
|
||||
## Media memory invariants (2026-07-14, RAM investigation)
|
||||
|
||||
- `removePeer` / `closeAllPeers` clear **all four** remote stream maps, including `remotePeerCameraStreams` (previously leaked per departed peer).
|
||||
- Video tiles (`voice-workspace-stream-tile`) pause and null `srcObject` in `ngOnDestroy` (`voice-workspace-stream-video.rules.ts`) so Chromium releases decoder/frame buffers immediately.
|
||||
- `debug-network-metrics` drops a peer's entry when the peer is fully removed and caps the store at `MAX_TRACKED_DEBUG_NETWORK_PEERS` = 200 (oldest evicted).
|
||||
- Electron registers `setDisplayMediaRequestHandler` once per app run (guarded in `create-window.ts`), not on every window recreation.
|
||||
|
||||
## Mobile / Capacitor
|
||||
|
||||
@@ -57,4 +64,5 @@ Background voice uses Android foreground service + iOS audio/CallKit bridges —
|
||||
|
||||
| Date | Change |
|
||||
|------|--------|
|
||||
| 2026-07-14 | Media memory invariants: camera-stream map cleanup, tile `srcObject` release, debug-metrics cap, single display-media handler registration, replaced data channels closed |
|
||||
| 2026-07-05 | Initial cross-context voice/WebRTC contract |
|
||||
|
||||
Reference in New Issue
Block a user