Skærmbillederne, der vises, er fra det simulerede problem afsnit af artiklen, ikke det oprindelige kode problem, på grund af privatlivets fred. Skærmbillederne, der vises, er fra det simulerede problem afsnit af artiklen, ikke det oprindelige kode problem, på grund af privatlivets fred. ️ Indholdsfortegnelse Den oprettelse Problemet: Sidefrysning på input Mislykkede Debug-forsøg Anmeldelse af The Breakthrough: Pause Script Execution The Root Cause: En løb, der aldrig ender Simulering frysningen (prøv det selv) Hvad jeg lærte Bonus Thought: Debugging hukommelse lækager Tiderne Den oprettelse Denne bug optrådte i en af projektet. React + TypeScript + Redux + RxJS Formularen havde et enkelt numerisk felt Når det blev opdateret, udløste det en (Bygget ved hjælp af For at genberegne den Den synkroniserede tekst. quantity Redux selector reselect Total cost Alting så godt ud på side af. Buy Men skifte til den side forårsagede noget mærkeligt: siden frøs øjeblikkeligt, når du . Sell 1 Problemet: Sidefrysning på input Når du skriver i kvantitetsfeltet: 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% Dette var ikke en typisk "langsom" rendering. . Fuld hængning Chrome viste til sidst dialogboksen "Page Unresponsive" og jeg var nødt til at dræbe fanen. Mislykkede Debug-forsøg Almindelige metoder til debugging hjalp ikke: 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 Aldrig trykt noget debugger; For langsomt eller aldrig udløst React DevTools Profiler Frosse med app’en Chrome præstationsprofil Kan ikke afslutte optagelsen Fjernelse af komponenter Endnu frosset, selv med kun indgangen Spørgsmålet skulle være en Det er uendeligt, men hvor? loop or recursive render Anmeldelse af The Breakthrough: Pause Script Execution Så kom jeg til en erkendelse: hvis JavaScript-højen fortsætter med at vokse, . JavaScript is still running Så jeg åbnede og brugte den skjulte gem: Chrome DevTools → Sources tab Pause Script Execution (⏸️) Desværre kunne jeg ikke se en forklaring på denne funktion selv i de officielle Chrome DevTools-dokumenter: https://developer.chrome.com/docs/devtools/javascript/breakpoint Desværre kunne jeg ikke se en forklaring på denne funktion selv i de officielle Chrome DevTools-dokumenter: https://developer.chrome.com/docs/devtools/javascript/breakpoint https://developer.chrome.com/docs/devtools/javascript/breakpoint af skridt: 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! The Root Cause: En løb, der aldrig ender Den paused stack afslørede en kæde af 8+ funktioner, begyndende med handler og slutter inde i a Bruges af a . onChange utility function Redux Reselect selector Her er den skyldige: let a = 0; const size = props.size; // expected number, got string while (a < size) { // do something } Bliver ud der kommer indirekte fra inputværdien: a Som . props.size string "5" På grund af JS coercion quirks, sløjfen sammenligning mislykkedes at komme ud under visse betingelser, hvilket forårsager en uendelig sløjfe og fryse hele tråden. Det var lige så simpelt som at konvertere værdien til et tal før brug: const size = Number(props.size); Så forsvandt fryseren med det samme. Simulering frysningen (prøv det selv) Du kan genskabe denne nøjagtige bug og prøve fejlfinding trick selv ved at gå til denne codesandbox Eller køre nedenstående kode i en ny men spar dit arbejde først, fordi dette Hæng din browser-tab 🙂 Link til Create React App, vil Link til 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> ); } Trin til reproduktion Åbn denne kode i ovenstående codesandbox eller lokalt. Skriv et hvilket som helst tal i indtastningen. Hold øje med fryseren Solid. Åbn Chrome DevTools → Sources-fanen → ️ Pause script execution. Observér den uendelige bue inde i handleændring i opkaldsstacken. Hvad jeg lærte Når intet virker: pause script execution er sølvkuglen. Uendelige sløjfer kan gemme sig inde i selektorer, reduktorer eller utility-filer langt fra brugergrænsefladen. Altid rens og tjek brugerindtastning før beregninger. mens loops er skarpe værktøjer: en forkert tilstand og din app bliver en CPU toaster . Bonus Thought: Debugging hukommelse lækager Den samme teknik kan hjælpe med at spore langsomt I de tilfælde, hvor JS-toppen gradvist øges. memory leaks Pausering af scriptkørsel i tom tid kan afsløre, hvilke baggrundsprocesser eller abonnementer der stadig kører unødvendigt. Men det er et eksperiment for en anden artikel 😉