ObsiViewer/docs/ARCHITECTURE/PERF_ROADMAP_TODOLIST.md
Bruno Charest 545c07a4b3 feat: enhance notes list with filtering, sorting and view modes
- Added comprehensive filtering system with support for file types, tags, and quick links
- Implemented sort options (title, created, updated) with dropdown menu
- Added three view modes (compact, comfortable, detailed) for different density layouts
- Added note color indicators and hover actions (edit, delete) to note cards
- Integrated file type detection with appropriate icons for different content types
- Added filter badges to show
2025-10-31 10:54:17 -04:00

261 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ObsiViewer Nimbus — Performance Roadmap & Todo List (Angular 20 + Tailwind 3.4)
Cette roadmap est une liste dactions priorisées pour optimiser les performances côté client de linterface Nimbus, en respectant strictement:
- Angular 20 (signals, @for/@if, @defer, standalone, zoneless)
- TailwindCSS 3.4 (purge actuelle conservée)
- UI/UX Nimbus existante (aucun changement visuel ou de comportement attendu)
- Modes Desktop et Mobile
Chaque tâche contient: Objectif mesurable, Critères dacceptation, Emplacements de code, Risques/Dépendances et un Prompt prêt à lemploi pour exécuter la tâche à 100% (desktop + mobile).
---
## ✅ Phase 0 — Quick Wins (ROI élevé, faible risque)
### 0.1 Retirer limport global Excalidraw du bundle initial
- Objectif: réduire la taille du bundle initial et le TTI en excluant `@excalidraw/excalidraw` du chunk principal.
- Critères dacceptation:
- Limport global napparaît plus dans `index.tsx`.
- Le Drawings Editor reste fonctionnel via import dynamique (`web-components/excalidraw/define`).
- Build prod montre une baisse du poids du bundle initial (source-map-explorer).
- Emplacements: `index.tsx`, `src/app/features/drawings/drawings-editor.component.ts`, `web-components/excalidraw/define.ts`.
- Risques/Dépendances: sassurer que les usages Excalidraw restent lazy et conditionnels.
- Prompt:
```
Tu es un pair-programmer Angular 20. Objectif: retirer tout import global d'Excalidraw du bundle initial sans casser le Drawings Editor. Étapes:
1) Ouvre `index.tsx` et supprime toute ligne `import '@excalidraw/excalidraw'`.
2) Vérifie que `src/app/features/drawings/drawings-editor.component.ts` importe `../../../../web-components/excalidraw/define` via `await import(...)`.
3) Lance un build prod avec stats et analyse les bundles (source-map-explorer) pour confirmer la réduction du main chunk.
4) Teste Desktop et Mobile: ouverture dun fichier .excalidraw.md dans léditeur (réactivité, chargement lazy OK).
5) Ne change pas lUI/UX. Respecte Angular 20 et Tailwind 3.4.
```
### 0.2 Virtualiser la liste centrale Nimbus avec `PaginatedNotesList`
- Objectif: maintenir ≥55 FPS et mémoire <200MB avec 5k+ notes.
- Critères dacceptation:
- Le centre affiche `PaginatedNotesListComponent` (CDK virtual scroll + pagination).
- Scroll fluide Desktop/Mobile, FPS 55 sur 5k items.
- Émissions/inputs existants (openNote, queryChange, selectedId, quickLink) préservés.
- Emplacements: `src/app/layout/app-shell-nimbus/app-shell-nimbus.component.ts` (zones de liste Desktop/Tablet/Mobile).
- Risques/Dépendances: compatibilité filtres/search/URL state; conserver événements.
- Prompt:
```
Tu es un expert Angular 20/CDK Virtual Scroll. Remplace la liste centrale dans `AppShellNimbus` par `PaginatedNotesListComponent` sans changer lUX.
1) Identifie les trois zones de rendu de la liste (desktop/tablet/mobile) dans `app-shell-nimbus.component.ts`.
2) Remplace le composant de liste actuel par `<app-paginated-notes-list>` en câblant:
- Inputs: folderFilter, tagFilter, quickLinkFilter, query, selectedId
- Outputs: openNote, queryChange, clearQuickLinkFilter
3) Vérifie Desktop/Mobile: scroll fluide, sélection, recherche, quick links.
4) Mesure FPS (DevTools) sur 5k notes; objectif ≥55 FPS.
5) Pas de modification visuelle. Respecte Angular 20/Tailwind 3.4.
```
### 0.3 Déférer les viewers lourds (PDF/Video/Excalidraw/Code) via `@defer`
- Objectif: réduire LCP et TTI en chargeant à la demande les viewers lourds.
- Critères dacceptation:
- `@defer` entourant le SmartFileViewer (non-markdown) avec placeholder.
- Le chunk viewer se charge uniquement quand visible (on viewport/interactions).
- Pas de régression Desktop/Mobile.
- Emplacements: `src/components/tags-view/note-viewer/note-viewer.component.ts` (ou template), `src/components/smart-file-viewer/`.
- Risques/Dépendances: placeholders légers; événements image/video conservés.
- Prompt:
```
Tu es un spécialiste Angular 20. Déferre laffichage des viewers lourds.
1) Dans le template NoteViewer (ou SmartFileViewer), entoure le rendu non-markdown avec `@defer (on viewport)` et un placeholder léger.
2) Garde le rendu markdown immédiat.
3) Vérifie Desktop/Mobile: ouverture dun PDF/Excalidraw/Video/Code charge un chunk async seulement à laffichage.
4) Mesure LCP/TTI avant/après (Lighthouse Mobile). Objectif: LCP ≤ 2.5s, TTI ≤ 3.0s.
5) Aucun changement dUI. Respecte Angular 20/Tailwind 3.4.
```
### 0.4 Adopter `NgOptimizedImage` pour les images
- Objectif: améliorer LCP et éliminer CLS en fournissant dimensions/sizes.
- Critères dacceptation:
- `NgOptimizedImage` importé et `ngSrc` utilisé dans `image-viewer`.
- Dimensions (width/height) ou stratégie calculée, `sizes` renseigné.
- LCP image et CLS 0.
- Emplacements: `src/app/features/note-view/components/image-viewer/image-viewer.component.ts` (+ contenu markdown rendu si applicable).
- Risques/Dépendances: fournir dimensions raisonnables; ne pas dégrader mise en page.
- Prompt:
```
Tu es un dev Angular 20. Optimise les images avec NgOptimizedImage.
1) Dans `image-viewer.component.ts`, ajoute `NgOptimizedImage` aux imports standalone.
2) Remplace `src` par `ngSrc` et fournis `width`, `height`, `sizes`.
3) Vérifie Desktop/Mobile: absence de sauts de layout (CLS), affichage net, LCP image améliorée.
4) Garde les événements/émissions inchangés. Pas de changement visuel.
```
### 0.5 Convertir les `*ngFor` restants en `@for` avec `track`
- Objectif: réduire le coût de diffing et stabiliser lidentité des items.
- Critères dacceptation:
- Listes dynamiques dans Nimbus utilisent `@for (...; track ...)`.
- Aucune régression dinteraction (sélection tags/dossiers/etc.).
- Emplacements: `app-shell-nimbus.component.ts` (ex. flyout tags/dossiers) et autres listes restantes.
- Risques/Dépendances: choisir une clé stable (`id`, `name`).
- Prompt:
```
Tu es un expert Angular 20. Modernise les boucles.
1) Recherc he `*ngFor` dans les templates Nimbus et remplace-les par `@for`.
2) Ajoute un `track` stable (id, name) pour chaque liste.
3) Teste Desktop/Mobile: navigation, clics tags/dossiers, pas de re-rendu excessif.
```
---
## Phase 1 — Correctifs cœur
### 1.1 Throttling/Debouncing des entrées + écouteurs passifs
- Objectif: TBT 150ms, INP 200ms durant saisie/recherche/scroll.
- Critères dacceptation:
- Flux de recherche: debounce/throttle ~16100ms.
- Écouteurs scroll/wheel/resize en `{ passive: true }` si custom.
- Profiler: long tasks et input latency sur Desktop/Mobile.
- Emplacements: composants de recherche/liste; directives éventuelles dévénements.
- Prompt:
```
Tu es un dev perf Angular. Lisse les entrées.
1) Ajoute debounce/throttle (RxJS) aux flux de recherche et scroll.
2) Convertis tout `addEventListener` custom en `{ passive: true }` si pertinent.
3) Mesure INP/TBT (Lighthouse Mobile). Objectifs: INP ≤ 200ms, TBT ≤ 150ms.
```
### 1.2 Déférer panneaux lourds (paramètres/tests/about)
- Objectif: réduire bundle initial et coût de rendu.
- Critères dacceptation:
- Panneaux secondaires rendus via `@defer (on interaction)` + placeholder.
- Aucun changement dUX; charge uniquement à louverture.
- Emplacements: `app-shell-nimbus.component.ts` (panneaux/overlays non essentiels).
- Prompt:
```
Tu es un expert Angular 20. Déferre les panneaux non essentiels.
1) Ajoute `@defer (on interaction)` autour des panneaux paramètres/tests/about.
2) Placeholder léger et accessibilité préservée.
3) Vérifie Desktop/Mobile: ouverture fluide, chunks chargés à la demande.
```
### 1.3 Vérifier import conditionnel des libs lourdes
- Objectif: `@excalidraw/excalidraw`, PDF et autres libs uniquement chargés si viewer requis.
- Critères dacceptation: aucun import global résiduel; lazy import confirmé (network waterfall).
- Emplacements: `smart-file-viewer`, `drawings-editor`, pdf viewer.
- Prompt:
```
Tu es un dev Angular. Vérifie et force les imports conditionnels.
1) Inspecte smart-file-viewer/drawings-editor/pdf-viewer: pas dimport global.
2) Les imports doivent être dynamiques/conditionnels à lusage.
3) Confirme au profiler: chunks chargés seulement si nécessaires.
```
---
## Phase 2 — Refactors profonds
### 2.1 Slices de store par signals (Sélection/Filtre/Recherche)
- Objectif: diminuer les re-rendus et effets transverses.
- Critères dacceptation:
- Séparation claire des signals; reactivité localisée; pas de boucle.
- UX identique; URL state toujours synchronisé.
- Emplacements: `AppComponent`, `AppShellNimbusLayoutComponent`, services détat/URL.
- Prompt:
```
Tu es un architecte Angular 20. Isoles les états en slices par signals.
1) Identifie les states très utilisés (sélection, filtres, recherche).
2) Crée des slices/cohorts de signals avec computed/effects.
3) Assure la synchro URL <-> UI intacte. Tests Desktop/Mobile.
```
### 2.2 content-visibility/contain pour grands conteneurs
- Objectif: réduire le coût de layout/paint hors écran.
- Critères dacceptation: scrolling et navigation plus fluides; aucune régression visuelle.
- Emplacements: grands conteneurs de liste/notes (CSS global ou scss locaux).
- Prompt:
```
Tu es un expert CSS perf. Ajoute `content-visibility: auto` et `contain-intrinsic-size` sur les grands conteneurs offscreen.
1) Cible les conteneurs principaux liste/viewer.
2) Vérifie Desktop/Mobile: aucun artefact; paint/layout réduits (Performance panel).
```
### 2.3 Pipeline images responsive (thumb→medium→full)
- Objectif: améliorer le temps de rendu perçu des assets visuels.
- Critères dacceptation: affichage progressif sans saut, qualité finale correcte.
- Emplacements: chargement dimages (viewer et markdown rendu).
- Prompt:
```
Tu es un dev front. Mets en place un pipeline responsive images.
1) Servez dabord une miniature, puis une image medium, puis la full.
2) Adapte `sizes/srcset` (NgOptimizedImage) pour Desktop/Mobile.
3) Mesure LCP perçu et absence de CLS.
```
---
## Phase 3 — Plateforme / Build
### 3.1 Budgets Angular (initial, anyComponentStyle, css)
- Objectif: prévenir les régressions de poids.
- Critères dacceptation: budgets ajoutés à `angular.json`; build échoue si dépassement.
- Emplacements: `angular.json`.
- Prompt:
```
Tu es un mainteneur Angular. Ajoute des budgets stricts.
1) Ajoute budgets pour initial (warn 1400kb / error 1800kb), anyComponentStyle, css.
2) Lance un build prod pour valider.
3) Documente dans README/CI les seuils.
```
### 3.2 Scripts danalyse + (optionnel) Lighthouse CI gate
- [] done
- Objectif: visibilité continue et garde-fous automatiques.
- Critères dacceptation: scripts npm `build:stats` et `analyze:bundle`; pipeline peut exécuter Lighthouse avec seuils mobiles.
- Emplacements: `package.json`, CI.
- Prompt:
```
Tu es un dev outillage. Ajoute scripts danalyse et un job Lighthouse CI (optionnel).
1) `build:stats` (ng build --stats-json) et `analyze:bundle` (source-map-explorer) dans package.json.
2) Pipeline: exécute Lighthouse Mobile/Desktop et échoue si LCP/TTI/CLS/TBT hors seuils.
3) Ne modifie pas le code applicatif.
```
---
## Mesure & Validation
- Baseline puis post-implémentation: Lighthouse Mobile (4x CPU, 1.5 Mbps) et Desktop.
- Objectifs cibles:
- LCP 2.5s (Mobile), TTI 3.0s, CLS 0.02, TBT 150ms
- Liste 5k items: 55 FPS, mémoire <200MB
- Bundle initial: -40% vs baseline si possible
- Scripts utiles:
- `npm run build:stats`
- `npx source-map-explorer "dist/**/*.js"`
---
## Checklist globale (progression)
- [x] 0.1 Retirer import global Excalidraw
- [ ] 0.2 Virtualiser liste centrale Nimbus (PaginatedNotesList)
- [ ] 0.3 Déférer viewers lourds (@defer)
- [ ] 0.4 NgOptimizedImage pour images
- [ ] 0.5 Convertir *ngFor @for avec track
- [ ] 1.1 Throttle/Debounce + passive listeners
- [ ] 1.2 Déférer panneaux non essentiels
- [ ] 1.3 Imports conditionnels libs lourdes
- [ ] 2.1 Slices signals (Sélection/Filtre/Recherche)
- [ ] 2.2 content-visibility/contain pour conteneurs
- [ ] 2.3 Pipeline images responsive
- [ ] 3.1 Budgets Angular
- [ ] 3.2 Scripts analyse + Lighthouse CI (opt.)