Blank Screen, it can do anything and destroy everything, making users lose all sense of body, test mention P0 meet, research and development shudder, tremble, only to know the rush back.

For the user’s closest front end, is the disaster area, as long as the browser appears white screen, first look for the front end.

Recently, I frequently encountered online blank screen accidents in my work. I would like to take this opportunity to introduce why blank screen occurs and how to deal with it.

The art of war: know the enemy, know yourself, and fight a hundred battles without danger of defeat; Without knowing the enemy and knowing yourself, you can win a battle without knowing the enemy and knowing yourself.

Only enough to understand the white screen, understand the limitations of their own code, in order to yundanfeng light, programming.

Where does the white screen come from

There are two reasons for the white screen:

  1. Resource access error
  2. Code execution error

Both have their own strengths and weaknesses, but from a modern front-end perspective, both are closely related to the widespread use of the SPA framework.

Resource access error

Resources refer specifically to static resources such as JavaScript scripts, style sheets and images, excluding dynamic resources such as service calls.

The most typical example is the React, Vue SPA framework to build Web applications, once [bundle | app]. Js access failed because the network reasons, will trigger a white page.

You can go to vue-ebgcbmiy3-b2d1.vercel.app/ and repeat the steps as follows: Go to DevTools > Network, find app.3b315b6b.js, right-click and select the Block Request URL, then refresh the page.

Code execution error

If there is some wiggle room for a resource access error, the user’s network may be unstable, and it takes a few retries to recover.

Errors in code execution during render are a death sentence, including but not limited to:

  • Read the property of undefined null,null.a;
  • Function calls on ordinary objects,const o = {}; o();
  • Pass null undefined to object. keys,Object.keys(null);
  • JSON deserialization received an invalid value,JSON.parse({});

You have to go through local debugging, CI, CD, build deployment, or just rollback.

Why read Properties of undefined is blank?

First, I would like to ask a question. Will the following code result in a blank screen?

To get away from the constraints of the framework, I deliberately used native JavaScript to render a web page dynamically in an imperative programming paradigm.

<body>
  <div id="root"></div>
  <script>
    const arr = ["webpack"."rollup"."parcel"];
    const root = document.getElementById("root");

    const ul = document.createElement("ul");

    for (let i = 0; i <= arr.length - 1; i++) {
      const li = document.createElement("li");
      li.innerHTML = arr[i];
      ul.appendChild(li);
    }

    root.appendChild(ul);

    const h1 = document.createElement("h1");

    // trigger read properties of undefined
    h1.textContent = document.createTextNode({}.a.b);

    root.appendChild(h1);
  </script>
</body>
Copy the code

The browser’s true representation is that UL is rendered normally, but H1 is not rendered directly, and the two do not affect each other and do not result in a blank screen.

Cutting back to React, let’s compare rendering UL H1 to rendering < ul /> components and < h1 /> components and see what happens.

const Ul = () = > (
  <ul>
    {["webpack", "rollup", "parcel"].map((v) => (
      <li>{v}</li>
    ))}
  </ul>
);

// trigger read properties of undefined
const H1 = () = > <h1>{{}.a.b}</h1>;

const App = () = > {
  return (
    <>
      <Ul />
      <H1 />
    </>
  );
};

ReactDOM.render(<App />.document.getElementById("root"));
Copy the code

Unsurprisingly, the page went white, and a

rendering error caused the entire
to crash.

The root cause is that since React 16, any error not caught by the error boundary will cause the entire React component tree to be uninstalled.

If Uncaught Errors occur during component rendering and Error Boundaries are not captured, the entire DOM structure represented by
will be removed as follows:

ReactDOM.render(null.document.getElementById("root"));
Copy the code

React uses a white screen to explain what is called cold lips and teeth, and it can affect the whole body. This also confirms my previous statement that the frequent white screen of modern Web applications is closely related to the SPA framework.

But can you say that this mechanism is negatively optimized? The official line:

We had some debate about this decision, but in our experience, leaving a bad UI there is worse than removing it completely. For example, in a product like Messenger, presenting a user with an abnormal UI could cause the user to send the wrong message to someone else. Similarly, displaying the wrong amount is worse for a payment application than showing nothing at all.

More and more, I believe that the endless flow of frameworks or new technologies on the front end, while big enough, implies trade-off, works well in most scenarios, and you have to accept its “rules” in others.

Why not ⬛ or 🟦 screen?

Now that the DOM has been removed, the only thing left is a bare div#app node, and the default background color for the body is #FFF, the screen should be blank.

<body>
  <div id="app"></div>
  <script src="/js/chunk-vendors.61a12961.js"></script>
  <script src="/js/app.3b315b6b.js"></script>
</body>
Copy the code

Therefore, not only the black screen and blue screen can be realized, but also the rainbow screen can be realized as long as the background color of the body is slightly adjusted. At that time, the title of the copy document is “XXX causes the rainbow screen”, which makes it look like a front-end comedian.

I think the white screen is just a code name, which by extension means the page is rendered without content.

I also want to emphasize that the white screen is just an external manifestation. The internal error has already happened and cannot be reversed, which will definitely bring functional impact to users. However, the visual impact of the white screen is the strongest, and the intuitive feedback of the brain is very serious.

How to Reduce the “destructive Power” of white Screen

I won’t go into details about how to avoid a blank screen, because mistakes happen all the time. What we can do is to do our best and follow these principles:

  • Dependence is not credible, NPM’s Breaking Change
  • Calls are not trusted, and API calls such as HTTP/RPC will not only fail, but also return data outside the convention, incompatible with outdated versions
  • Input is not trusted, users often enter some boundary values, illegal values to avoid exceptions as much as possible.

We focus on how to remedy the situation when the error has already occurred, reducing the external bad performance to an acceptable or unperceived state.

With ErrorBoundary, it can catch any Uncaught Errors made by any child component during rendering, thus avoiding the uninstallation of the entire component tree and killing the white screen in the cradle.

In addition, it can take advantage of components that render incorrectly in two ways: fusing and demoting.

Component “fuse”

The circuit breaker mechanism refers to a mechanism that suspends trading in a stock market for a period of time when the range of price fluctuations reaches a specified target (the circuit breaker). The mechanism is like a fuse that blows out when the current is too high, preventing a bigger accident, hence the name.

It is widely used in disaster recovery system, corresponding to React system, fuse point is equivalent to rendering error, temporary transaction is equivalent to unloading components, directly do not render, save the car.

Look directly at examples:

import { ErrorBoundary } from "react-error-boundary";

const Other = () = > <h1>I AM OTHER</h1>;

const Bug = () = > {
  const [val, setVal] = useState({});

  const triggerError = () = > {
    setVal(undefined);
  };

  return (
    <>
      <button onClick={triggerError}>trigger render error</button>

      <h1>I HAVE BUG, DO NOT CLICK ME</h1>
      {Object.keys(val)}
    </>
  );
};

const App = () = > (
  <>
    <Other />
    <ErrorBoundary fallbackRender={()= > null}>
      <Bug />
    </ErrorBoundary>
  </>
);
Copy the code

Graceful degradation of components

Graceful downgrading refers to using alternative rendering components that fail, and doing so in line with the functional scene, the user’s mental cues.

import { ErrorBoundary } from "react-error-boundary";

function ErrorFallback({ error, resetErrorBoundary }) {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}

const App = () = > (
  <>
    <Other />
    <ErrorBoundary fallbackRender={ErrorFallback}>
      <Bug />
    </ErrorBoundary>
  </>
);
Copy the code

The error bound library chosen for the above demo is github.com/bvaughn/rea… , can be put into use in the production environment.

The premise is that everyone has a common understanding of error boundaries for each component, along with internal monitoring reporting and Lint detection, to minimize the “destructive power” of white screens and create a more stable online environment.

Off-topic: An active throw error causes a blank screen

I’d rather be wrong than do nothing.

I agree with the React Team that it’s better not to show the wrong UI.

Error UI, is a ticking time bomb, at any time under certain circumstances would explode, imagine the user in the wrong interface, small BUG, is caused economic losses, the security leaks, not the loss of the effects, so have to unexpected behavior, must take the initiative to throw the error, and make the component characteristics and degradation.