Las capturas de pantalla que se muestran son de la sección de problemas simulados del artículo, no el problema del código original, debido a preocupaciones de privacidad. Las capturas de pantalla que se muestran son de la sección de problemas simulados del artículo, no el problema del código original, debido a preocupaciones de privacidad. ️ Tabla de contenidos El establecimiento El problema: la página se congela en la entrada Intentos fallidos de debug The Breakthrough: Pause Script ejecución La causa de la raíz: un rumbo que nunca termina Simulando la congelación (Try It Yourself) Lo que aprendí Título: Debugging Memory Leaks Tags El establecimiento Este bug apareció en un El proyecto. React + TypeScript + Redux + RxJS La forma tenía un único campo numérico Cuando se actualizó, desencadenó un (Construido utilizando Para recalcular el Estado de texto sincronizado. quantity Redux selector reselect Total cost Todo se veía bien en la El lado. Buy Sin embargo, cambiando a la la página causó algo extraño: la página se congeló instantáneamente cuando entró incluso . Sell 1 El problema: la página se congela en la entrada Cuando se escribe en el campo de la cantidad: The UI froze completely The browser tab became unresponsive The in Chrome Performance Monitor. (Sometimes, the JS heap size also keeps increasing) CPU usage 100% No era un retrato típico “lento”. . Conexión completa Chrome finalmente mostró el diálogo "Página sin respuesta" y tuve que matar la pestaña. Intentos fallidos de debug Los métodos de depuración comunes no ayudaron: Attempt Result console.log Never printed anything debugger; Too slow or never triggered React DevTools Profiler Froze with the app Chrome Performance Profiler Couldn’t finish recording Removing components Still froze, even with just the input console.log Nunca imprimió nada debugger; Demasiado lento o nunca desencadenado Características del perfil de DevTools Froze con la app Perfil de rendimiento de Chrome No pudo terminar la grabación Eliminar los componentes Aún congelado, incluso con sólo la entrada El tema debía ser un Correr sin fin, pero ¿dónde? loop or recursive render The Breakthrough: Pause Script ejecución Entonces me di cuenta de que si el JavaScript sigue creciendo, . JavaScript is still running Así que abrí y usó la joya oculta: Chrome DevTools → Sources tab Pause Script Execution (⏸️) Desafortunadamente, no pude ver una explicación de esta característica ni siquiera en los documentos oficiales de Chrome DevTools: https://developer.chrome.com/docs/devtools/javascript/breakpoint Desafortunadamente, no pude ver una explicación de esta característica ni siquiera en los documentos oficiales de Chrome DevTools: https://developer.chrome.com/docs/devtools/javascript/breakpoint https://developer.chrome.com/docs/devtools/javascript/breakpoint Los pasos: Open Chrome DevTools first! You won’t be able to open them during the freeze. Reproduce the freeze (enter quantity). When the tab hangs, open . DevTools → Sources tab Click the icon (top-right). ⏸️ Pause Chrome freezes JS execution . at that exact line Scroll down on the right panel & check the panel to trace which functions are currently executing. Call Stack Scroll through the parent calls to reveal how the function chain started. You can even click on the parent calls to see their invoked line! La causa de la raíz: un rumbo que nunca termina La pila interrumpida reveló una cadena de 8+ funciones, a partir de la que termina en el interior de una Utilizado por A . onChange utility function Redux Reselect selector Aquí está el culpable: let a = 0; const size = props.size; // expected number, got string while (a < size) { // do something } se vuelve derivado indirectamente del valor de entrada: a como . props.size string "5" Debido a los trucos de coerción de JS, la comparación de loop no logró salir bajo ciertas condiciones, causando un loop infinito y congelando todo el hilo. Corregirlo era tan simple como convertir el valor en un número antes de usarlo: const size = Number(props.size); De inmediato, la página congelada desapareció . Simulando la congelación (Try It Yourself) Usted puede recrear este error exacto y probar el truco de depuración usted mismo al ir a este codesandbox O ejecutar el código de abajo en un nuevo pero guardar su trabajo primero porque este Descarga tu navegador Enlace Create React App, Will Enlace import { useState } from "react"; export default function App() { const [quantity, setQuantity] = useState(""); const handleChange = (e) => { const value = e.target.value; setQuantity(value); const end = Date.now() + 145000; let a = 0; // ❌ Intentional infinite loop while (Date.now() < end) { // Busy-wait a++; } console.log("Done!"); // never reached }; return ( <div style={{ padding: 20 }}> <h2>🧊 Simulate a Page Freeze</h2> <input type="text" placeholder="Enter quantity" value={quantity} onChange={handleChange} /> <p>Type any number and watch Chrome suffer.</p> </div> ); } Pasos para reproducir Abra este código en el codesandbox de arriba o localmente. Escriba cualquier número en la entrada. Observe la tabla congelar sólido. Abra Chrome DevTools → Tab de fuentes → ️ Pausa la ejecución de scripts. Observe el loop infinito dentro de handleChange en la pila de llamadas. Lo que aprendí Cuando nada funciona: la ejecución de guión de pausa es la bala de plata. Los loop infinitos pueden ocultarse dentro de selectores, reductores o archivos de utilidad lejos de la interfaz de usuario. Siempre sanear y verificar la entrada de usuario antes de los cálculos. mientras que los loop son herramientas agudas: una condición equivocada y tu aplicación se convierte en un toaster de CPU . Título: Debugging Memory Leaks Esta misma técnica podría ayudar a rastrear lentamente → casos en los que la pila de JS aumenta gradualmente. memory leaks Pausar la ejecución de scripts durante el tiempo vacío podría revelar qué procesos de fondo o suscripciones todavía se ejecutan innecesariamente. Pero eso es un experimento para otro artículo 😉.