problem phenomenon
In actual project development, we often encounter problems like the following page crashes. The cause of browser page crashes is generally JS heap heap memory overflow, but such problems generally do not report errors on the console, so the positioning problem The experience and means are very important. The following is a summary of the problems I encountered in the actual project.
identify the problem
First of all, let's talk about the background of the project's technology stack, which is a micro front-end, middle- and back-end application built with React+Mobx+single-react-spa
. When the page is initialized and loaded, click "Delete" to trigger the event and the page will be stuck, and it will crash directly after a while, but there is no error message in the console, and there is no way to start the positioning problem. After thinking for a while, I decided to try the most basic method. The delete event will delete the table source data, trigger the re-rendering of the table component and some of its descendant components, and define and use each component that will be re-rendered and inside the component. A breakpoint is added to the function body. Finally, the breakpoint debugging found that the method body of getParentClassName
is trapped in an infinite loop. When currentElement=null
, the loop body of while
is trapped in an infinite loop.
/** 获取所有父节点的className */
export const getParentClassName = (element: Element, fatherClassName?: string) => {
const classNames = [];
let currentElement = element;
classNames.push(currentElement?.className || '');
if (fatherClassName) {
while (
!(currentElement?.className || '').includes(fatherClassName) &&
currentElement !== document.body
) {
classNames.push(currentElement?.className || '');
currentElement = currentElement?.parentElement as Element;
}
} else {
while (currentElement !== document.body) {
classNames.push(currentElement?.className || '');
currentElement = currentElement?.parentElement as Element;
}
}
classNames.push(currentElement?.className || '');
return classNames;
};
Because it is impossible to locate the code block that causes the problem, the above debugging method is like black-box testing, which is time-consuming. After thinking about it, in fact, we can use performance
record the execution of the entire stack frame ( Stack Frame
) after triggering the delete event
We can obviously find that the getParentClassName
method has an infinite loop, and the JS Heap
has risen from the starting 28.3M
to 747M
, and the method execution time accounts for 84.9%
. This positioning method is much faster than the manual breakpoint positioning method, and it is worth learning from students.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。