10

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.

页面崩溃1.gif

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

image-20220226155912563.png

image-20220226160032937.png

image-20220226160125088.png

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.


记得要微笑
1.9k 声望4.5k 粉丝

知不足而奋进,望远山而前行,卯足劲,不减热爱。


引用和评论

0 条评论