Del síntoma al panel: el árbol de decisión
Una tabla de correspondencias entre lo que ves roto y dónde se investiga, más el árbol que la genera, para dejar de abrir paneles al azar.
La diferencia medible entre alguien que depura rápido y alguien que no está casi toda en los primeros noventa segundos. No en la destreza con el panel, sino en la elección del panel. Quien acierta la primera vez tarda diez minutos; quien empieza mirando el sitio equivocado descubre su error cuando ya lleva cuarenta y ha contaminado el estado de la página con veinte cambios. Esta lección es un árbol de decisión y su tabla, para que el primer movimiento deje de ser un reflejo y empiece a ser una elección.
- Clasificar un síntoma en una de las cinco categorías raíz antes de abrir ningún panel.
- Aplicar el árbol de decisión para elegir el panel de entrada de un problema concreto.
- Reconocer los tres síntomas ambiguos que apuntan a dos familias y cómo desempatarlos.
- Justificar por qué el orden de las preguntas del árbol no se puede alterar.
Las cinco categorías raíz
Todo síntoma reportado por un humano cae en una de cinco cajas. La clasificación no es opinable: depende de si algo se ve, se ve mal, no responde, va lento, o se rompe con el tiempo.
No se ve. El elemento no aparece en pantalla. Puede que no exista en el DOM, que exista con dimensión cero, que esté fuera del área visible, o que esté tapado. Son cuatro causas con cuatro diagnósticos distintos y el árbol las separa en dos preguntas.
Se ve mal. Está ahí, pero con el color, el tamaño, la posición o la tipografía equivocados. Es el territorio nativo de Elements, y casi siempre se resuelve leyendo la cascada real en vez de escribiendo más CSS.
No hace lo que debe. El botón no responde, el formulario no envía, el estado no se actualiza. Es el territorio de Sources y de la consola, y es donde más se pierde el tiempo porque la tentación de instrumentar con trazas es máxima.
Va lento. Tarda en cargar, tarda en responder al clic, salta al hacer scroll. Tres síntomas que la gente agrupa bajo “lento” y que no tienen nada que ver entre sí: el primero es red o arranque, el segundo es el hilo principal ocupado, el tercero es composición.
Se degrada con el uso. Funciona bien al principio y peor con el tiempo. Es el único síntoma que apunta directamente a memoria, y también el único que exige un ciclo de reproducción diseñado antes de medir.
El árbol
flowchart TB
s[Sintoma] --> a{Se ve el elemento}
a -->|No| b{Esta en el arbol del DOM}
b -->|No| n1[Network o Sources]
b -->|Si| e1[Elements estilos y geometria]
a -->|Si pero mal| e2[Elements cascada y computados]
s --> c{Responde a la interaccion}
c -->|No| so1[Sources breakpoints de evento]
c -->|Con datos malos| so2[Network respuesta y Sources]
s --> d{Va lento}
d -->|Al cargar| ne1[Network waterfall]
d -->|Al interactuar| pe1[Performance hilo principal]
d -->|Al hacer scroll| re1[Rendering y capas]
s --> f{Empeora con el tiempo}
f -->|Si| me1[Memory tres snapshots]
style s fill:#cba6f7,color:#11111b
style n1 fill:#f9e2af,color:#11111b
style e1 fill:#89b4fa,color:#11111b
style e2 fill:#89b4fa,color:#11111b
style so1 fill:#a6e3a1,color:#11111b
style so2 fill:#a6e3a1,color:#11111b
style ne1 fill:#f9e2af,color:#11111b
style pe1 fill:#fab387,color:#11111b
style re1 fill:#fab387,color:#11111b
style me1 fill:#f38ba8,color:#11111bLa primera bifurcación del árbol es la que más rendimiento da y la que más gente se salta: antes de mirar por qué algo se ve mal, comprueba si existe. Un Cmd+F en el panel de Elements buscando el texto o el selector del elemento responde en tres segundos y bisecciona el problema en dos mitades que no tienen ninguna herramienta en común. Si el nodo no está en el árbol, todo el CSS del mundo es irrelevante y el problema está en los datos o en la lógica que decide renderizarlo. Si está, el problema es de presentación y Sources no pinta nada.
La tabla de correspondencias
El árbol se despliega en una tabla que conviene tener presente hasta que se automatice. La columna que importa no es la del panel sino la de la primera acción: abrir el panel correcto sin saber qué hacer dentro sirve de poco.
| Síntoma | Panel de entrada | Primera acción concreta |
|---|---|---|
| El elemento no aparece | Elements | Buscar por selector o por texto para saber si el nodo existe |
| El nodo existe pero no se ve | Elements | Mirar el modelo de caja: dimensión cero, display, opacity, overflow |
| El estilo no se aplica | Elements | Panel de estilos: buscar la declaración tachada y por qué lo está |
| El valor es raro pero la regla está bien | Elements | Pestaña de computados y de dónde hereda |
| El clic no hace nada | Sources | Breakpoint de evento en click y ver si siquiera se dispara |
| El estado no se actualiza | Sources | Breakpoint de modificación de subárbol en el nodo que debería cambiar |
| La API devuelve algo raro | Network | Ver la respuesta cruda antes de culpar al código que la consume |
| La petición no sale | Network | Filtrar y comprobar; si no está, breakpoint de fetch o de XHR |
| Falla solo en producción | Sources | Source maps y overrides locales para reproducir el fix |
| Tarda en cargar | Network | Leer la forma de la cascada antes que ningún número concreto |
| Se congela al interactuar | Performance | Grabar solo la interacción y buscar la tarea larga |
| Salta al hacer scroll | Rendering | Activar el resaltado de repintado y los bordes de capa |
| Consume memoria creciente | Memory | Diseñar el ciclo de reproducción antes de tomar el primer snapshot |
| Falla al recargar y funciona en caliente | Application | Estado persistente: almacenamiento, cookies, service worker |
Ninguna fila de esa tabla dice “abrir la consola y poner trazas”. No es un descuido. La consola es una herramienta excelente de verificación de hipótesis y una herramienta pésima de exploración inicial: te obliga a adivinar dónde mirar antes de saber nada, y cada trazo que añades es una recarga más y una modificación del código que después hay que quitar.
Los tres síntomas ambiguos
Hay tres casos donde el árbol se bifurca de verdad y hace falta un desempate. Merecen conocerse porque son exactamente los que más tiempo consumen.
“El dato no aparece en pantalla.” Puede ser que la petición no devolviera el dato o que el dato llegara y el render lo ignorara. El desempate cuesta cinco segundos: mira la pestaña de respuesta de esa petición en Network. Si el dato está en la respuesta, el problema es tuyo y está en el código de render. Si no está, deja de mirar el frontend. Este único movimiento evita la conversación más larga y más estéril entre frontend y backend.
“Funciona en mi máquina.” Casi siempre es estado persistente o caché. El desempate es abrir una ventana de incógnito, que arranca con almacenamiento vacío, sin service worker registrado y sin extensiones. Si allí falla igual, es código. Si allí funciona, es estado, y Application es tu panel.
“A veces pasa y a veces no.” La intermitencia apunta casi siempre a tiempo: una carrera entre dos operaciones asíncronas, un setTimeout que gana o pierde, una respuesta que llega después de que el componente se desmonte. El desempate es exagerar la asimetría: activa el throttling de red al perfil más lento y el de CPU al máximo. Si con eso el fallo pasa de intermitente a constante, tienes una carrera y ya sabes cuál de las dos ramas gana cuando la red va lenta.
El árbol funciona sobre síntomas observables, y ahí está la trampa: lo que llega en un ticket no es un síntoma, es la interpretación que un humano hizo de un síntoma. “El botón de guardar está roto” puede significar que el botón no responde, que responde y falla la petición, que la petición va bien pero la interfaz no se actualiza, o que se guarda perfectamente y la pantalla siguiente muestra datos viejos. Son cuatro bugs en tres familias distintas del mapa, y la palabra “roto” no distingue ninguno. Antes de tocar un panel, gasta noventa segundos en convertir la interpretación en observación: reproduce el fallo tú, con las DevTools abiertas, y describe lo que ves sin usar ninguna palabra causal. No “no guarda”, sino “sale una petición POST que devuelve 200 y la tabla sigue mostrando el valor anterior”. Esa frase ya contiene el diagnóstico, y la anterior no contenía nada. La mitad del trabajo de depurar es escribir bien el síntoma; la otra mitad la hace el árbol.
Por qué el orden no se puede alterar
Las preguntas del árbol están ordenadas por coste de respuesta creciente y por poder de bisección decreciente. Comprobar si un nodo existe cuesta tres segundos y parte el espacio de búsqueda en dos. Grabar un perfil de rendimiento cuesta un minuto de grabación más cinco de lectura y no descarta casi nada por sí solo.
Empezar por la pregunta cara es un error doble: gastas el tiempo y además llenas la cabeza de datos que todavía no sabes interpretar porque no has acotado el problema. Un perfil de Performance de una página que no funciona es ilegible; el mismo perfil, cuando ya sabes que la lentitud aparece al pulsar un botón concreto y solo con cien filas en la tabla, se lee en dos minutos.
Ese es el principio general y vale para todo lo que viene después: acotar antes que medir, y medir antes que arreglar. Las lecciones siguientes de este nivel formalizan las dos mitades de ese principio.