Skip to content

Pre-warm cipher decryption on desktop to remove vault search lag#20482

Open
mikolajbuczak wants to merge 1 commit intobitwarden:mainfrom
mikolajbuczak:fix/desktop-prewarm-cipher-list-views
Open

Pre-warm cipher decryption on desktop to remove vault search lag#20482
mikolajbuczak wants to merge 1 commit intobitwarden:mainfrom
mikolajbuczak:fix/desktop-prewarm-cipher-list-views

Conversation

@mikolajbuczak
Copy link
Copy Markdown

🎟️ Tracking

Community contribution. No Jira ticket.

📔 Objective

After signing in to the desktop app, typing in the vault search bar produces no
filtered results for the first few seconds (~3s on a typical vault). The lag
scales with vault size.

The vault component composes its filtered list as
combineLatest([cipherListViews$, filter$, searchText$]) (see
apps/desktop/src/vault/app/vault-v3/vault.component.ts:397-419). The first
subscription to cipherListViews$ is what triggers SDK decryption of the
entire vault, and that only happens when the user navigates to the vault page.
Until decryption completes, combineLatest does not fire, so the search input
appears unresponsive.

This change adds a pre-warm subscription to cipherListViews$ in
AppComponent for the active user. Because cipherListViews$ is wrapped in a
per-user shareReplay (libs/common/src/vault/utils/observable-utilities.ts),
by the time the vault page mounts the cache is hot and basic search is
instantaneous.

switchMap(account => account?.id ? cipherListViews$(account.id) : EMPTY)
handles login/logout/account switches automatically; takeUntil(this.destroy$)
matches the existing teardown pattern in this file.

Verification

Two new specs in libs/common/src/vault/services/:

  • search.service.perf.spec.ts benchmarks basic search across
    100/1000/5000/10000 ciphers. Median for 10000 ciphers: 5.97ms — confirms
    SearchService itself is not the bottleneck.
  • vault-search-pipeline.lag.spec.ts reproduces the multi-second lag in a
    unit test by simulating a delayed cipherListViews$ first emission, and
    asserts that pre-warming reduces user-visible latency from ~3010ms to <200ms
    (observed 9ms locally).

All 642 specs in libs/common/src/vault/ pass. ESLint and Prettier pass on
the modified files.

📸 Screenshots

N/A — no UI changes.

`cipherListViews$` is a per-user `shareReplay`-cached observable whose
first subscription triggers SDK decryption of the entire vault. The
desktop vault component subscribes to it on mount, so users hit a
multi-second delay between typing in the search input and seeing
filtered results immediately after login.

Subscribe to `cipherListViews$` in `AppComponent` for the active user
so the cache is hot by the time the vault page renders. `switchMap`
swaps the subscription on account changes; `takeUntil(this.destroy$)`
matches the existing teardown pattern in this file.

Add specs in `libs/common/src/vault/services/`:
- `search.service.perf.spec.ts` baselines basic search performance
  (median 6ms for 10000 ciphers).
- `vault-search-pipeline.lag.spec.ts` reproduces the lag (~3000ms)
  and verifies the pre-warm pattern eliminates it (<200ms, observed 9ms).
@mikolajbuczak mikolajbuczak requested a review from a team as a code owner May 3, 2026 15:53
@mikolajbuczak mikolajbuczak requested a review from nikwithak May 3, 2026 15:53
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 3, 2026

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@bitwarden-bot
Copy link
Copy Markdown

Thank you for your contribution! We've added this to our internal tracking system for review.
ID: PM-36444
Link: https://bitwarden.atlassian.net/browse/PM-36444

Details on our contribution process can be found here: https://contributing.bitwarden.com/contributing/pull-requests/community-pr-process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants