Content
View differences
Updated by Yan Zubrytskyi about 1 month ago
\# Network requests optimization review
{{toc}}
\---
This document ties \*\*observed HTTP traces\*\* (parsed network logs below) to redundant and heavy API usage, with \*\*concrete file paths\*\* in this repository for follow-up work. Paths in the tables use the \`/api/v3/…\` prefix; query strings are abbreviated as \`…\` where the capture used long filter JSON.
\## 1. Captured request traces
The rows below are taken from representative sessions (method, path pattern, status, type, duration, timestamp). They are the empirical basis for the optimization suggestions in the sections that follow.
\### 1.1 App startup
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">#</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Method</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Address</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Status</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Type</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Duration</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Timestamp</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">1</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/me`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">307 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.000</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">2</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/schema`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">74 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.378</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">3</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/notifications?pageSize=0&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">873 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.528</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">4</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/configuration`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">870 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.529</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">5</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/configuration`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">868 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.530</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">6</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/capabilities?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">870 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.531</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">7</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/capabilities?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">873 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.532</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">8</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/capabilities?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">872 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.532</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">9</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/notifications?pageSize=0&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">236 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.171</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">10</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/statuses`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">649 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.171</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">11</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">—</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Pending</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.172</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">12</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/priorities`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">—</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Pending</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.172</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">13</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/statuses`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">256 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.172</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">14</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Pending</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.175</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">15</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/priorities`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">538 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.175</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">16</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/26`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">164 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:56.354</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">17</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/18`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">181 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:56.356</p></td></tr></tbody></table></figure>
> \*\*Observations:\*\* Duplicate \`configuration\`, overlapping \`notifications\` (unread-style \`pageSize=0\`), three \`capabilities\` calls at the same millisecond, duplicate \`statuses\`, parallel \`work\_packages\` + \`priorities\` with mixed Pending/complete.
\### 1.2 Work package details (##314)
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">#</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Method</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Address</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Status</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Type</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Duration</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Timestamp</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">1</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/relations?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">531 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.789</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">2</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/attachments`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">531 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.790</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">3</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/activities`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">538 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.791</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">4</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/watchers`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">379 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.791</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">5</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">621 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.804</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">6</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/help_texts`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">522 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.805</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">7</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/me/preferences`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">515 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.805</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">8</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">516 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.805</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">9</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">587 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.806</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">10</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">607 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.806</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">11</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">414 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:20.424</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">16</p></td><td class="op-uc-table--cell"><p class="op-uc-p">POST</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/form`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">192 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:20.476</p></td></tr></tbody></table></figure>
> \*\*Observations:\*\* Same work package fetched twice (rows 5 and 11); relations/attachments/activities/watchers start alongside core WP; list-oriented \`views\` and \`work\_packages\` list calls overlap the details window; four capability checks in a tight burst.
\### 1.3 Project details — duplicate requests
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">#</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Method</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Address</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Status</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Type</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Duration</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Timestamp</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">1</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">358 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.553</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">2</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">216 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.727</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">3</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">222 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.727</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">4</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/projects/3/types`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">231 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.915</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">5</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/projects/6/types`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">202 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.949</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">6</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/projects/6/types`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">216 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.953</p></td></tr></tbody></table></figure>
> \*\*Observations:\*\* Three identical \`views\` calls at the same timestamp; duplicate \`projects/{id}/types\` for project \`6\`.
\---
\## 2. Component Analysis & Mitigation
\### 2.1 App startup — duplicate or overlapping requests
\*\*Issue:\*\* Categories like statuses, priorities, and configuration are requested from multiple entry points during cold start.
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Concern</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Source File</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Notes</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Statuses**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`status_repository_impl.dart`](../lib/app/services/repositories/status/status_repository_impl.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Uses `Completer` for concurrent `getAll()`, but list/detail flows trigger this often.</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Priorities**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`priority_repository_impl.dart`](../lib/app/services/repositories/priority/priority_repository_impl.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Invoked from [`get_work_package_entities.dart`](../lib/app/domain/usecase/workpackage/get_work_package_entities.dart).</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Configuration**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`local_settings_repository.dart`](../lib/app/services/repositories/settings/local_settings_repository.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`force: true` bypasses cache. Callers: `work_package_form_bloc.dart`, `bottom_bar_bloc.dart`, `time_tracking_bloc.dart`.</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Unread Count**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`api_notifications_repository.dart`](../lib/app/services/repositories/notifications/api_notifications_repository.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Review debouncing after login to avoid multiple constructor triggers.</p></td></tr></tbody></table></figure>
\### 2.2 Work package details — payload and timing
\*\*Issue:\*\* Details screen pulls excessive parallel data before stable UI emission.
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Topic</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Code Path</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Improvement ideas</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Parallel gate**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`work_package_form_bloc.dart`](../lib/forms/page/bloc/work_package_form_bloc.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`Future.wait` bundles WP, form, config, help texts. Consider **progressive emit** (WP overview first).</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Sub-blocs**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`initialize_details_feature_blocs.dart`](../lib/app/features/work_package/work_package_details/initialize_details_feature_blocs.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Defer network work for non-visible tabs (Activity, Watchers) until visibility.</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Help texts**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`help_text_in_memory_cache.dart`](../lib/app/services/repositories/help_text/help_text_in_memory_cache.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Long-lived cache candidate; shouldn't block first paint.</p></td></tr></tbody></table></figure>
\### 2.3 Project & Time Tracking
\* \*\*Project Overview:\*\* \[\`project\_overview\_bloc.dart\`\](../lib/app/features/projects/project\_overview/bloc/project\_overview\_bloc.dart) should avoid refetching project data if already present in the portfolio cache.
\* \*\*Time Tracking:\*\* \[\`time\_tracking\_bloc.dart\`\](../lib/app/features/time\_tracking/bloc/time\_tracking\_bloc.dart) forces \`getConfiguration(force: true)\` on refresh. Share configuration via a singleton instead.
\### 2.4 Capabilities API
\*\*Issue:\*\* \[\`sync\_permissions.dart\`\](../lib/app/domain/usecase/sync\_permissions.dart) runs \`Future.wait\` over actions, resulting in \*\*three parallel HTTP calls\*\*.
\*\*Direction:\*\* consolidate into one round-trip if OpenProject API allows broader filtering; otherwise, rely on the \`userId:action:projectId\` cache in \[\`permissions\_repository\_impl.dart\`\](../lib/app/services/repositories/permissions/permissions\_repository\_impl.dart).
{{toc}}
\---
This document ties \*\*observed HTTP traces\*\* (parsed network logs below) to redundant and heavy API usage, with \*\*concrete file paths\*\* in this repository for follow-up work. Paths in the tables use the \`/api/v3/…\` prefix; query strings are abbreviated as \`…\` where the capture used long filter JSON.
\## 1. Captured request traces
The rows below are taken from representative sessions (method, path pattern, status, type, duration, timestamp). They are the empirical basis for the optimization suggestions in the sections that follow.
\### 1.1 App startup
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">#</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Method</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Address</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Status</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Type</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Duration</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Timestamp</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">1</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/me`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">307 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.000</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">2</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/schema`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">74 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.378</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">3</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/notifications?pageSize=0&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">873 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.528</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">4</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/configuration`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">870 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.529</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">5</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/configuration`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">868 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.530</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">6</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/capabilities?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">870 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.531</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">7</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/capabilities?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">873 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.532</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">8</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/capabilities?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">872 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:52.532</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">9</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/notifications?pageSize=0&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">236 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.171</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">10</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/statuses`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">649 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.171</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">11</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">—</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Pending</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.172</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">12</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/priorities`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">—</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Pending</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.172</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">13</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/statuses`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">256 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.172</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">14</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Pending</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.175</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">15</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/priorities`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">538 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:53.175</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">16</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/26`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">164 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:56.354</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">17</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/18`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">181 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:07:56.356</p></td></tr></tbody></table></figure>
> \*\*Observations:\*\* Duplicate \`configuration\`, overlapping \`notifications\` (unread-style \`pageSize=0\`), three \`capabilities\` calls at the same millisecond, duplicate \`statuses\`, parallel \`work\_packages\` + \`priorities\` with mixed Pending/complete.
\### 1.2 Work package details (##314)
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">#</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Method</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Address</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Status</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Type</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Duration</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Timestamp</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">1</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/relations?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">531 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.789</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">2</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/attachments`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">531 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.790</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">3</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/activities`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">538 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.791</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">4</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/watchers`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">379 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.791</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">5</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">621 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.804</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">6</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/help_texts`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">522 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.805</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">7</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/users/me/preferences`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">515 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.805</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">8</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">516 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.805</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">9</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">587 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.806</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">10</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages?filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">607 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:19.806</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">11</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">414 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:20.424</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">16</p></td><td class="op-uc-table--cell"><p class="op-uc-p">POST</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/work_packages/314/form`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">192 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:12:20.476</p></td></tr></tbody></table></figure>
> \*\*Observations:\*\* Same work package fetched twice (rows 5 and 11); relations/attachments/activities/watchers start alongside core WP; list-oriented \`views\` and \`work\_packages\` list calls overlap the details window; four capability checks in a tight burst.
\### 1.3 Project details — duplicate requests
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">#</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Method</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Address</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Status</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Type</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Duration</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Timestamp</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">1</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">358 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.553</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">2</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">216 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.727</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">3</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/views?pageSize=100&filters=…`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">222 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.727</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">4</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/projects/3/types`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">231 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.915</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">5</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/projects/6/types`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">202 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.949</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">6</p></td><td class="op-uc-table--cell"><p class="op-uc-p">GET</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`/api/v3/projects/6/types`</p></td><td class="op-uc-table--cell"><p class="op-uc-p">200</p></td><td class="op-uc-table--cell"><p class="op-uc-p">http</p></td><td class="op-uc-table--cell"><p class="op-uc-p">216 ms</p></td><td class="op-uc-table--cell"><p class="op-uc-p">10:27:21.953</p></td></tr></tbody></table></figure>
> \*\*Observations:\*\* Three identical \`views\` calls at the same timestamp; duplicate \`projects/{id}/types\` for project \`6\`.
\---
\## 2. Component Analysis & Mitigation
\### 2.1 App startup — duplicate or overlapping requests
\*\*Issue:\*\* Categories like statuses, priorities, and configuration are requested from multiple entry points during cold start.
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Concern</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Source File</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Notes</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Statuses**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`status_repository_impl.dart`](../lib/app/services/repositories/status/status_repository_impl.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Uses `Completer` for concurrent `getAll()`, but list/detail flows trigger this often.</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Priorities**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`priority_repository_impl.dart`](../lib/app/services/repositories/priority/priority_repository_impl.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Invoked from [`get_work_package_entities.dart`](../lib/app/domain/usecase/workpackage/get_work_package_entities.dart).</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Configuration**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`local_settings_repository.dart`](../lib/app/services/repositories/settings/local_settings_repository.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`force: true` bypasses cache. Callers: `work_package_form_bloc.dart`, `bottom_bar_bloc.dart`, `time_tracking_bloc.dart`.</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Unread Count**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`api_notifications_repository.dart`](../lib/app/services/repositories/notifications/api_notifications_repository.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Review debouncing after login to avoid multiple constructor triggers.</p></td></tr></tbody></table></figure>
\### 2.2 Work package details — payload and timing
\*\*Issue:\*\* Details screen pulls excessive parallel data before stable UI emission.
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Topic</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Code Path</p></th><th class="op-uc-table--cell op-uc-table--cell_head"><p class="op-uc-p">Improvement ideas</p></th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Parallel gate**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`work_package_form_bloc.dart`](../lib/forms/page/bloc/work_package_form_bloc.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">`Future.wait` bundles WP, form, config, help texts. Consider **progressive emit** (WP overview first).</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Sub-blocs**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`initialize_details_feature_blocs.dart`](../lib/app/features/work_package/work_package_details/initialize_details_feature_blocs.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Defer network work for non-visible tabs (Activity, Watchers) until visibility.</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-table--cell"><p class="op-uc-p">**Help texts**</p></td><td class="op-uc-table--cell"><p class="op-uc-p">[`help_text_in_memory_cache.dart`](../lib/app/services/repositories/help_text/help_text_in_memory_cache.dart)</p></td><td class="op-uc-table--cell"><p class="op-uc-p">Long-lived cache candidate; shouldn't block first paint.</p></td></tr></tbody></table></figure>
\### 2.3 Project & Time Tracking
\* \*\*Project Overview:\*\* \[\`project\_overview\_bloc.dart\`\](../lib/app/features/projects/project\_overview/bloc/project\_overview\_bloc.dart) should avoid refetching project data if already present in the portfolio cache.
\* \*\*Time Tracking:\*\* \[\`time\_tracking\_bloc.dart\`\](../lib/app/features/time\_tracking/bloc/time\_tracking\_bloc.dart) forces \`getConfiguration(force: true)\` on refresh. Share configuration via a singleton instead.
\### 2.4 Capabilities API
\*\*Issue:\*\* \[\`sync\_permissions.dart\`\](../lib/app/domain/usecase/sync\_permissions.dart) runs \`Future.wait\` over actions, resulting in \*\*three parallel HTTP calls\*\*.
\*\*Direction:\*\* consolidate into one round-trip if OpenProject API allows broader filtering; otherwise, rely on the \`userId:action:projectId\` cache in \[\`permissions\_repository\_impl.dart\`\](../lib/app/services/repositories/permissions/permissions\_repository\_impl.dart).