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

12 KiB
Raw Blame History

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)

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