Background inbox sync re-sends and re-renders every loaded message every 30 s, freezing the tab with several accounts
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 56/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, php
- Domain
- backend, frontend, performance
Research direction
Start with lib/Service/Sync/SyncService.php around the findChanged TODO and src/store/mainStore/actions.js around updateEnvelopeMutation; also inspect src/App.vue where syncInboxes() runs. Check existing sync tests and run the relevant server and client tests. Done means unchanged messages are not repeatedly returned or trigger list re-renders, while real flag or tag changes still update correctly.
Written by the indexing model from the issue text.
Description
Steps to reproduce
- Add several IMAP accounts to one user (I have 7, all on the same Dovecot server).
- Open Mail in the browser and leave it open (worse on "All inboxes" or after scrolling back through a list).
- Watch the tab every 30 seconds while the background inbox sync runs.
Expected behavior
When nothing changed on the server, the periodic background sync should send back (almost) nothing, and the UI should not re-render the message list.
Actual behavior
Every 30 s the tab freezes for a moment (the browser's loading indicator shows) and becomes responsive again as soon as the sync finishes.
The server side is fast. I logged the requests at the reverse proxy: every 30 s there is one POST /apps/mail/api/mailboxes/{id}/sync per account inbox, all fired at once, each answered in 0.2–0.6 s. However, every response for a given inbox has the same size on every poll (1.6–4.7 KB gzipped), even when nothing changed.
The cause seems to be in the code:
-
Server: every known message is always returned as "changed".
lib/Service/Sync/SyncService.phpL146–L150// TODO: $changed = $this->messageMapper->findChanged($account, $mailbox, $uids); ... $changedIds = $knownIds;So
changedMessagescontains every envelope the client already has loaded, on every sync. -
Client: each "changed" envelope gets new
flags/tagsobjects, even when they are identical.
src/store/mainStore/actions.jsL955 and L2111updateEnvelopeMutation({ envelope }) { ... Vue.set(existing, 'flags', envelope.flags) Vue.set(existing, 'tags', envelope.tags) }Because these are always new objects, Vue sends change notifications for every loaded envelope and re-renders the list.
-
This runs for every account inbox every 30 s (
src/App.vueL98,syncInboxes()). So the work grows with (number of accounts × loaded envelopes), and with several accounts the main thread blocks noticeably on every poll.
Suggested fix
- Server: implement the
findChangedTODO (e.g. use the CONDSTORE/flag-change UIDs the IMAP sync already gets) so only messages that really changed are returned. - Client (cheap, independent): in
updateEnvelopeMutation, skip theVue.setcalls whenflags/tagsare unchanged. Comparing them first (e.g.JSON.stringify(old) !== JSON.stringify(new), sincetagsare already normalized to ID arrays) avoids re-rendering envelopes that did not change.
Possibly related: #13692 (memory blow-up on initial load). This report is about the steady-state 30 s poll after the app has loaded.
Mail app version
5.12.3
Nextcloud version
35.0.0 (Nextcloud All-in-One)
Mailserver or service
Dovecot 2.3.21 (mailcow)
Operating system
Linux (Debian 13)
PHP engine version
PHP 8.x (AIO image)
Web server
Apache (AIO) behind Caddy
Database
PostgreSQL
Additional info
The freezes stop as soon as each sync round finishes. Fewer accounts makes them shorter.
- Dominant language
- JavaScript
- Stars
- 1k
- Forks
- 363
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 81
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nextcloud/mail
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
nextcloud/mail#13841 · 1 comment ·
Maintainers usually reply within 1 day
-
0. to triage enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
Show email next to name in Search dropdownPossibly taken @vansh-nagar claimed this 16 days ago. Open1. to develop enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
nextcloud/mail#13703 · 1 comment ·
Maintainers usually reply within 1 day
-
ISO-2022-JP emails are garbled in Mail 5.10.12 [Minimal fix available]Possibly taken @neconohitomi claimed this 36 days ago. Open1. to develop bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
nextcloud/mail#13472 · 1 comment ·
Maintainers usually reply within 1 day
-
1. to develop technical debt
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
Similar issues
-
Harden bayesian-waves-bg.js: add prefers-reduced-motion, pointer-events guard, and hidden-tab pauseOpen
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
njitacm/njit-acm-website#109 ·
-
type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
blamechris/chroxy#8579 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
modusensus/dsh-mneme#411 ·
-
Flaky (suspected): VideoTimelineEditor bed audio test sees 600px instead of 120px under CI loadOpen
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day