Task #73915: Analyse and detect bottlenecks and possible optimisations to improve performance (lo...

Yan Zubrytskyi
2026-04-17T12:45:20+00:00

# 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

# | Method | Address | Status | Type | Duration | Timestamp
1 | GET | `/api/v3/users/me` | 200 | http | 307 ms | 10:07:52.000
2 | GET | `/api/v3/users/schema` | 200 | http | 74 ms | 10:07:52.378
3 | GET | `/api/v3/notifications?pageSize=0&filters=…` | 200 | http | 873 ms | 10:07:52.528
4 | GET | `/api/v3/configuration` | 200 | http | 870 ms | 10:07:52.529
5 | GET | `/api/v3/configuration` | 200 | http | 868 ms | 10:07:52.530
6 | GET | `/api/v3/capabilities?filters=…` | 200 | http | 870 ms | 10:07:52.531
7 | GET | `/api/v3/capabilities?filters=…` | 200 | http | 873 ms | 10:07:52.532
8 | GET | `/api/v3/capabilities?filters=…` | 200 | http | 872 ms | 10:07:52.532
9 | GET | `/api/v3/notifications?pageSize=0&filters=…` | 200 | http | 236 ms | 10:07:53.171
10 | GET | `/api/v3/statuses` | 200 | http | 649 ms | 10:07:53.171
11 | GET | `/api/v3/work_packages?filters=…` | — | http | Pending | 10:07:53.172
12 | GET | `/api/v3/priorities` | — | http | Pending | 10:07:53.172
13 | GET | `/api/v3/statuses` | 200 | http | 256 ms | 10:07:53.172
14 | GET | `/api/v3/work_packages?filters=…` | 200 | http | Pending | 10:07:53.175
15 | GET | `/api/v3/priorities` | 200 | http | 538 ms | 10:07:53.175
16 | GET | `/api/v3/users/26` | 200 | http | 164 ms | 10:07:56.354
17 | GET | `/api/v3/users/18` | 200 | http | 181 ms | 10:07:56.356

> **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 ()

# | Method | Address | Status | Type | Duration | Timestamp
1 | GET | `/api/v3/relations?filters=…` | 200 | http | 531 ms | 10:12:19.789
2 | GET | `/api/v3/work_packages/314/attachments` | 200 | http | 531 ms | 10:12:19.790
3 | GET | `/api/v3/work_packages/314/activities` | 200 | http | 538 ms | 10:12:19.791
4 | GET | `/api/v3/work_packages/314/watchers` | 200 | http | 379 ms | 10:12:19.791
5 | GET | `/api/v3/work_packages/314` | 200 | http | 621 ms | 10:12:19.804
6 | GET | `/api/v3/help_texts` | 200 | http | 522 ms | 10:12:19.805
7 | GET | `/api/v3/users/me/preferences` | 200 | http | 515 ms | 10:12:19.805
8 | GET | `/api/v3/views?pageSize=100&filters=…` | 200 | http | 516 ms | 10:12:19.805
9 | GET | `/api/v3/work_packages?filters=…` | 200 | http | 587 ms | 10:12:19.806
10 | GET | `/api/v3/work_packages?filters=…` | 200 | http | 607 ms | 10:12:19.806
11 | GET | `/api/v3/work_packages/314` | 200 | http | 414 ms | 10:12:20.424
16 | POST | `/api/v3/work_packages/314/form` | 200 | http | 192 ms | 10:12:20.476

> **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

# | Method | Address | Status | Type | Duration | Timestamp
1 | GET | `/api/v3/views?pageSize=100&filters=…` | 200 | http | 358 ms | 10:27:21.553
2 | GET | `/api/v3/views?pageSize=100&filters=…` | 200 | http | 216 ms | 10:27:21.727
3 | GET | `/api/v3/views?pageSize=100&filters=…` | 200 | http | 222 ms | 10:27:21.727
4 | GET | `/api/v3/projects/3/types` | 200 | http | 231 ms | 10:27:21.915
5 | GET | `/api/v3/projects/6/types` | 200 | http | 202 ms | 10:27:21.949
6 | GET | `/api/v3/projects/6/types` | 200 | http | 216 ms | 10:27:21.953

> **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.

Concern | Source File | Notes
**Statuses** | [`status_repository_impl.dart`](../lib/app/services/repositories/status/status_repository_impl.dart) | Uses `Completer` for concurrent `getAll()`, but list/detail flows trigger this often.
**Priorities** | [`priority_repository_impl.dart`](../lib/app/services/repositories/priority/priority_repository_impl.dart) | Invoked from [`get_work_package_entities.dart`](../lib/app/domain/usecase/workpackage/get_work_package_entities.dart).
**Configuration** | [`local_settings_repository.dart`](../lib/app/services/repositories/settings/local_settings_repository.dart) | `force: true` bypasses cache. Callers: `work_package_form_bloc.dart`, `bottom_bar_bloc.dart`, `time_tracking_bloc.dart`.
**Unread Count** | [`api_notifications_repository.dart`](../lib/app/services/repositories/notifications/api_notifications_repository.dart) | Review debouncing after login to avoid multiple constructor triggers.

### 2.2 Work package details — payload and timing

**Issue:** Details screen pulls excessive parallel data before stable UI emission.

Topic | Code Path | Improvement ideas
**Parallel gate** | [`work_package_form_bloc.dart`](../lib/forms/page/bloc/work_package_form_bloc.dart) | `Future.wait` bundles WP, form, config, help texts. Consider **progressive emit** (WP overview first).
**Sub-blocs** | [`initialize_details_feature_blocs.dart`](../lib/app/features/work_package/work_package_details/initialize_details_feature_blocs.dart) | Defer network work for non-visible tabs (Activity, Watchers) until visibility.
**Help texts** | [`help_text_in_memory_cache.dart`](../lib/app/services/repositories/help_text/help_text_in_memory_cache.dart) | Long-lived cache candidate; shouldn't block first paint.

### 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).

---

## 3. Summary checklist for implementers

1. **Audit Caller Graph:** Map `getConfiguration`, `updateUnreadCount`, and `hasCapability` calls.
2. **Hot Path Optimization:** Refactor [`GetWorkPackageEntities`](../lib/app/domain/usecase/workpackage/get_work_package_entities.dart) to prevent duplicate global entity loads.
3. **Staged Details UI:** Prototype staged emission from `WorkPackageFormBloc`.
4. **Link Reference:** See also wp-list-tab-performance-plan.md.