- 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
		
			
				
	
	
	
		
			12 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	
			12 KiB
		
	
	
	
	
	
	
	
ObsiViewer Nimbus — Performance Roadmap & Todo List (Angular 20 + Tailwind 3.4)
Cette roadmap est une liste d’actions priorisées pour optimiser les performances côté client de l’interface 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 d’acceptation, Emplacements de code, Risques/Dépendances et un Prompt prêt à l’emploi pour exécuter la tâche à 100% (desktop + mobile).
✅ Phase 0 — Quick Wins (ROI élevé, faible risque)
0.1 Retirer l’import global Excalidraw du bundle initial
- Objectif: réduire la taille du bundle initial et le TTI en excluant 
@excalidraw/excalidrawdu chunk principal. - Critères d’acceptation:
- L’import global n’apparaî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).
 
 - L’import global n’apparaît plus dans 
 - Emplacements: 
index.tsx,src/app/features/drawings/drawings-editor.component.ts,web-components/excalidraw/define.ts. - Risques/Dépendances: s’assurer 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 d’un fichier .excalidraw.md dans l’éditeur (réactivité, chargement lazy OK).
5) Ne change pas l’UI/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 d’acceptation:
- 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.
 
 - Le centre affiche 
 - 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 l’UX.
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 d’acceptation:
@deferentourant 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 l’affichage 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 d’un PDF/Excalidraw/Video/Code charge un chunk async seulement à l’affichage.
4) Mesure LCP/TTI avant/après (Lighthouse Mobile). Objectif: LCP ≤ 2.5s, TTI ≤ 3.0s.
5) Aucun changement d’UI. 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 d’acceptation:
NgOptimizedImageimporté etngSrcutilisé dansimage-viewer.- Dimensions (width/height) ou stratégie calculée, 
sizesrenseigné. - 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 l’identité des items.
 - Critères d’acceptation:
- Listes dynamiques dans Nimbus utilisent 
@for (...; track ...). - Aucune régression d’interaction (sélection tags/dossiers/etc.).
 
 - Listes dynamiques dans Nimbus utilisent 
 - 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 d’acceptation:
- Flux de recherche: debounce/throttle ~16–100ms.
 - É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 d’acceptation:
- Panneaux secondaires rendus via 
@defer (on interaction)+ placeholder. - Aucun changement d’UX; charge uniquement à l’ouverture.
 
 - Panneaux secondaires rendus via 
 - 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 d’acceptation: 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 d’import global.
2) Les imports doivent être dynamiques/conditionnels à l’usage.
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 d’acceptation:
- 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 d’acceptation: 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 d’acceptation: affichage progressif sans saut, qualité finale correcte.
 - Emplacements: chargement d’images (viewer et markdown rendu).
 - Prompt:
 
Tu es un dev front. Mets en place un pipeline responsive images.
1) Servez d’abord 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 d’acceptation: 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 d’analyse + (optionnel) Lighthouse CI gate
- 
[] done
 - 
Objectif: visibilité continue et garde-fous automatiques.
 - 
Critères d’acceptation: scripts npm
build:statsetanalyze:bundle; pipeline peut exécuter Lighthouse avec seuils mobiles. - 
Emplacements:
package.json, CI. - 
Prompt:
 
Tu es un dev outillage. Ajoute scripts d’analyse 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:statsnpx 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.)