Background inbox sync re-sends and re-renders every loaded message every 30 s, freezing the tab with several accounts
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 56/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, php
- 領域
- backend, frontend, performance
調査の方向性
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.
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- JavaScript
- スター
- 1.1k
- フォーク
- 378
- 平均マージ
- 1日 12時間
- マージ済み PR(30日)
- 116
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
nextcloud/mail のほかの issue
-
Global Mail search fails for Message-IDs containing '/' when generating deep links対応中かも @SoleroTG が 1 日前に担当しました。 オープン1. to develop bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
nextcloud/mail#13970 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
1. to develop bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
nextcloud/mail#13950 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
1. to develop bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
nextcloud/mail#13922 · コメント 1 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
1. to develop enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
nextcloud/mail#13903 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[Feature]: Need a close preview button/option in mail view対応中かも @steven-mpawulo が 16 日前に担当しました。 オープン1. to develop enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
nextcloud/mail#13841 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
似ている issue
-
curriculum documentation quality
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
githubnext/gh-aw-workshop#5367 ·
メンテナーはふだん 3 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 60/100
HeyPuter/everything#187 ·
メンテナーはふだん 1 日以内に返信
-
channels:add check:passed
難易度 2/5 1〜3時間 初心者へのやさしさ 63/100
メンテナーはふだん 4 日以内に返信
-
beginner blocked
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
hiero-ledger/hiero-sdk-js#4670 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 61/100
メンテナーはふだん 1 日以内に返信