Skip to content

Un arbre qui s'ouvre sur rien le dit, un niveau large ne fige plus, et la page tient son journal - #52

Merged
Beennnn merged 2 commits into
mainfrom
claude/reprise-sans-binaires-fu4e2h
Sep 4, 2026
Merged

Un arbre qui s'ouvre sur rien le dit, un niveau large ne fige plus, et la page tient son journal#52
Beennnn merged 2 commits into
mainfrom
claude/reprise-sans-binaires-fu4e2h

Conversation

@Beennnn

@Beennnn Beennnn commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Trois défauts de la même famille : une absence qui se lit comme un vide, une attente qui se lit comme un blocage, et rien nulle part pour les distinguer.

1. Un arbre d'exécution vide dit pourquoi

Cliquer sur une exécution dont l'arbre ne tient aucune image affichable faisait tourner la molette, n'ajoutait aucune ligne, et ne laissait pas d'erreur dans la console non plus — parce que rien n'avait échoué. Cinq situations produisent ce vide et se réparent de cinq façons différentes :

Situation Ce que la page dit maintenant
Recherche sans résultat « Aucune image de cette exécution ne correspond à la recherche. »
Aucun profil : Windows async-profiler ne publie pas de binaire pour Windows ; la couverture et les valeurs ne sont pas touchées
Aucun profil : --level coverage l'échantillonnage n'a pas été lancé, relancer sans --level
Aucun profil : autre pas un échantillon enregistré, le journal de l'exécution dit ce qu'a fait le profileur
Paquet masqué le bandeau au-dessus de l'arbre les nomme et les rend
Profil sans source « L'analyse des sources » dit quelles racines ont été consultées et propose la ligne SOURCE_DIRS
Profil hors des classes analysées élargir avec --classes et --sources, puis réassembler

Rien n'est deviné : la raison se lit dans le run-context.json de l'exécution — le système, le niveau — et dans un parcours de l'arbre que la page tient déjà.

Le compteur de la racine annonçait par ailleurs « 1 samples » quand rien n'avait été mesuré : le 1 servait de dénominateur aux pourcentages et s'était mis à s'afficher.

2. Un niveau large ne fige plus l'ouverture

L'arbre n'est jamais construit d'avance — on ne paie que ce qu'on ouvre — mais un niveau l'était en entier, quelle que soit sa largeur. Et la largeur d'un niveau n'est bornée par rien : à la place d'une image sans source, visibleChildren remonte toute sa descendance lisible.

Mesuré sur un profil synthétique bâti sur les mêmes méthodes, machine au repos :

Enfants sur un niveau Avant Après
4 000 0,36 s 0,11 s
20 000 4,4 s 0,18 s
60 000 10,6 s 0,18 s

Et chaque repli-dépli repayait le même prix. LEVEL_BUDGET s'arrête à 400 lignes, le dit, et rend le reste en un clic — les plus lourdes d'abord, l'ordre étant déjà décroissant en temps.

Le volume, lui, n'est pas le problème : un arbre d'un million de nœuds dans un bloc de 68 Mo s'ouvre en 6,7 s puis se comporte comme un autre — onglet, racine, replis restent sous 200 ms.

3. La page tient son propre journal

Tout ce qui tranche « ça ne marche pas chez moi » vivait dans la console du navigateur : personne ne l'ouvre, elle ne garde rien une fois l'onglet fermé, on ne peut pas la demander par téléphone. Le menu Exports porte maintenant une entrée « Journal d'activité » qui remet le texte, prêt à recoller.

  0.052  block          runs/…/vue/couverture.js — 1 entrie(s), 44 ms
  0.853  block          runs/…/vue/arbre.js — 1 entrie(s), 802 ms
  0.949  ready          27 class(es), 160000 sample(s), 340000 tree node(s), 942 ms
  1.072  tab            runs and call tree
  1.080  wide level     20000 calls at depth 1, 400 laid down
  1.089  tree drawn     403 row(s), 17 ms

Quatre décisions le tiennent :

  • Une ligne par geste, jamais par rendu — les fonctions de dessin tournent des dizaines de fois pour un seul clic.
  • Les répétitions se replient, mais seulement là où le site d'appel dit que le geste se répète : replier sur le genre seul fusionnait six chargements de blocs différents en une ligne et ne gardait que le dernier nom.
  • Aucune valeur capturée n'y entre. Les noms de classes et de méthodes voyagent — le rapport en est plein — un argument observé non. Un test parcourt les appels et casse la construction sur l'un qui irait chercher une valeur.
  • Il n'emporte jamais la page. L'écriture est enveloppée : un confort qui casserait la vue qu'il explique serait pire que pas de journal.

La ligne restored dit ce que le navigateur a ramené d'une lecture précédente — masques, élagages. Invisible par nature : ça voyage avec le navigateur et non avec le rapport, et ça peut vider un arbre sans aucun geste pour l'expliquer.

Vérification

  • 296 tests, dont trois nouveaux dans ViewContractTest qui tiennent les cinq raisons, leurs traductions, le plafond de niveau et le journal.
  • Rendu comparé sur les 8 556 chaînes des dix-huit états des deux rapports de référence : 54 différences, toutes la nouvelle entrée du menu, dans les deux langues. Rien d'autre n'a bougé.
  • 72 vérifications de la recette locale, vertes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01J956wjynbd7fkZx4HpjHzP


Generated by Claude Code

Une racine d'exécution qui s'ouvre sur rien se lit exactement comme une exécution
qui n'a rien fait. Elle ne l'est presque jamais : la molette tournait, aucune
ligne n'apparaissait, et la console ne portait pas d'erreur non plus — parce que
rien n'avait échoué. On a cherché une semaine un problème de déploiement qui
n'existait pas, sur une machine où le profileur ne tourne tout simplement pas.

Cinq situations produisent ce vide et se réparent de cinq façons différentes :
une recherche qui ne trouve rien, un profil jamais pris (Windows n'a pas de
binaire async-profiler, ou le niveau couverture a été demandé), un paquet masqué,
un profil dont les méthodes n'ont pas de source, un profil entièrement hors des
classes analysées. Rien n'est deviné : la raison se lit dans le contexte de
lancement de l'exécution et dans un parcours de l'arbre que la page tient déjà.

Le compteur de la racine disait « 1 samples » quand rien n'avait été mesuré : le
1 servait de dénominateur aux pourcentages et s'était mis à s'afficher. Un chiffre
que personne n'a compté fait douter de tous les autres à côté.

Vérifié au rendu, sur les 8 556 chaînes des dix-huit états des deux rapports de
référence : 0 différence là où un arbre existe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J956wjynbd7fkZx4HpjHzP
Tout ce qui tranche « ça ne marche pas chez moi » vivait dans la console du
navigateur : personne ne l'ouvre, elle ne garde rien une fois l'onglet fermé, et
on ne peut pas la demander par téléphone. Journal écrit une ligne par geste —
jamais par rendu, les fonctions de dessin tournent des dizaines de fois pour un
seul clic — et le menu Exports remet le texte. Ce qu'on n'a PAS pu faire y entre
d'abord : erreur non rattrapée, promesse rejetée, bloc introuvable. Aucune valeur
capturée n'y entre, et un test parcourt les appels pour le tenir.

La ligne « restored » dit ce que le NAVIGATEUR a ramené d'une lecture précédente
— masques, élagages. C'est invisible par nature : ça voyage avec le navigateur et
non avec le rapport, et ça peut vider un arbre sans aucun geste pour l'expliquer.

L'arbre n'est jamais construit d'avance, mais UN niveau l'était en entier, quelle
que soit sa largeur — et la largeur d'un niveau n'est bornée par rien : à la place
d'une image sans source, l'affichage remonte toute sa descendance lisible. Mesuré
sur un profil synthétique : 4 000 enfants coûtent 0,36 s à poser, 20 000 coûtent
4,4 s, 60 000 coûtent 10,6 s — et chaque repli-dépli les repaie. C'est le rapport
« qui ne s'ouvre pas quand on clique » : le navigateur travaillait, il n'était pas
bloqué. Le même profil s'affiche maintenant en 0,18 s.

Le volume, lui, n'est pas le problème : un arbre d'un million de nœuds dans un
bloc de 68 Mo s'ouvre en 6,7 s puis se comporte comme un autre. C'est la largeur
d'un seul niveau affiché qui coûte.

Vérifié au rendu : 54 différences sur les 8 556 chaînes des dix-huit états, toutes
la nouvelle entrée du menu, dans les deux langues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J956wjynbd7fkZx4HpjHzP
@Beennnn
Beennnn marked this pull request as ready for review September 4, 2026 14:52
@Beennnn
Beennnn merged commit a604a1f into main Sep 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants