Zuo Lin, Front end development engineer of Wedoctor Front End Technology Department. Super ~ can eat, like swimming, fitness and dancing, love life and technology.

Recognize vuE-SSR activation failure

For SSR server rendering this concept of slightly experienced development should be no stranger, official documentationVue SSR guideIt is clear what server rendering is, why it is used, and when it is used, with a classic build process to summarize the basics of SSR.

1. Basic knowledge

What is server-side rendering?

  • Client rendering is to output Vue components in the browser, generate DOM and manipulate DOM, and render for HTML page display;
  • Server-side rendering renders the same component as server-side HTML strings and sends them directly to the browser for display.
  • Vue SSR “activates” the static HTML rendered by the server into fully interactive HTML pages on the client side. The HTML rendered by the server and the client side is mixed, reflecting one of the features of Vue SSR — isomorphism.

Why SSR?

  • Fast rendering speed on the first screen;
  • SEO, server rendered page content can be retrieved by search engine crawlers;

When is SSR used?

SSR server rendering advantage mainly lies in the first screen rendering and SEO, then why not directly comprehensive promotion and use? The following disadvantages are mainly taken into account:

  • Increased code complexity – In order to achieve the aforementioned isomorphism, the application code needs to be compatible with both server and client implementations, so the API methods that previously supported only the browser environment must add special handling to run in the server renderer;
  • There are more requirements involved in build setup and deployment – fully static single-page applications (SPA) can be deployed on any static file server, while server rendering applications need to be in the Node.js server runtime environment;
  • More server load – render complete applications in Node.js,

Therefore, whether to use the server to render SSR requires developers to consider the input-output ratio. If most pages of the application system do not need SEO, and the first screen time can basically meet the demand, using SSR is not necessary. Combined with point 2 above, the use scenario of SSR:

  • High requirements on the first screen rendering time, and as far as possible, only the first screen content on the server rendering;
  • SEO demanding content.

2. Major pain points

Server-side rendering has many benefits, especially when a site like Nuxt.js or GridSome is a breeze to develop vuE-SSR applications, whether using dynamic SSR or generating static sites. However, on the other hand, due to the code complexity brought by isomorphism and unknown errors on node side, the stability and reliability of system application are reduced. Therefore, it is not recommended to use SSR development in unnecessary scenarios. Although most of the errors can be avoided or resolved with the guidance of official guidelines and workarounds provided by previous users, there are still unknown errors that we can’t start with.

For example, I once encountered a Bug in SSR server rendering. I checked it for 2 hours and identified it as client rendering failure. However, there are many reasons for client rendering failure.

Error: Error while mounting app: HierarchyRequestError: Failed to execute 'appendChild' on 'Node':
This node type does not support this method. at some-file.js:1
Copy the code

My experience with SSR has made me realize that most of the sticky errors I encounter are the result of Vue client activation failures.

3. What is Vue client Activation failure (Client-side Hydration)

Client Activation

The official guide to Vue client-side Activation is clear:

Client-side activation refers to the process by which the Vue takes over static HTML sent by the server at the browser side and turns it into a dynamic DOM managed by the Vue.

Encounter with chocolate, which translates as “injection”, is the process of injecting the virtual DOM structure generated on the client into the HTML rendered on the server to make the static HTML dynamic. As we can also see from the build process diagram above, the activation here takes place between the completion of the client’s build package and the rendering to HTML.

Failed to activate the client. Procedure

The server has rendered the HTML. Instead of discarding it and recreating all the DOM elements, it deactivates the rendered static HTML and makes it dynamic in response to subsequent data changes. However, if the virtual DOM tree generated by the Vue client does not match the DOM structure rendered by the server, a client activation failure occurs.

There are two types of development mode and production mode:

  • In development mode, if there is no match, it exits blending mode, discards the existing DOM and starts rendering from scratch;
  • In production mode, this detection is skipped to avoid performance degradation.

This explains why some errors occur only in production mode.

In the process of troubleshooting errors, I read (Google) a detailed article about the failure of client activation in SSR service, listing most possible causes and solutions.

What to do When Vue tells tells fails

Two, the text -What to do when Vue hydration fails

1. What is Vue activation failure

When I first heard the word ‘chocolate’, it was very abstract to me. I couldn’t figure out what it meant. Eventually, I realized it wasn’t as complicated as it first sounded:

Chocolate is a process by which Vue transforms server-side rendered markup and makes it dynamically reactive, so it can reflect dynamic changes from Vue.

If Vue expects a different markup than the HTML rendered on the server, Hydration fails (also known as “Vue drops Chocolate”). You can read more about this in the official Vue SSR documentation.

2. How do I identify an activation failure

We’re now aware of what an activation is and when it fails, but how do we as developers find out that an activation doesn’t work as expected?

There are two error messages that will definitely indicate that the activation failed but both have limitations.

1) The first is only in a development environment:

Parent: <div class="container"> client-hook-3.js:1:16358 Mismatching childNodes vs. VNodes: NodeList(3) [p, p, p] Array [{...}] [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.Copy the code

2) The second error message is when using statically generated sites only in a production environment:

Error: Error while mounting app: HierarchyRequestError: Failed to execute 'appendChild' on 'Node':
This node type does not support this method. at some-file.js:1
Copy the code

As we all know, activation only happens when the page is first rendered by the server, so it’s usually only in your application’s initialization request.

Activation failures are invisible when navigating through a TAB and can only be reproduced when hard reloading occurs, making it more difficult to detect activation failures in a development environment.

So activation errors are sometimes found only in staging systems or, worse, only in production environments. In rare cases, errors are not even printed and some components simply stop working.

3. Common causes of errors

Now that we know how to spot activation errors, we’ll look at the typical causes of Vue activation errors. Of course, it’s not possible to cover all possible causes here, as these error causes vary widely and depend largely on the code.

In the following sections, every time server-side rendering is mentioned, it is relevant to both cases (dynamic SSR and static site generation) because technically both have server-side rendering content (unless otherwise noted).

1) Unreasonable HTML

When an activation failure occurs, the first check should be to see if the HTML is reasonable. The official guide has this kind of pit warning, and usually has an error message:

This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>
Copy the code

Unfortunately, bad HTML is not usually the cause of activation failures. Still, you should double check your marks.

Also, be sure to check the miniaturization Settings, as excessive HTML miniaturization can result in invalid HTML.

If you have user-generated output or content from your CMS, verify that the content is also valid HTML.

Finally, third-party plug-ins or services can also affect and manipulate HTML. A common example of the latter is Cloudflare, when you enable their services — such as HTML miniaturisation, Rocket Loader, or other features that change the content of a page.

Here is a simple example codeAndBox that contains invalid HTML and triggers an activation failure.

2) Modify the HTML script

About scripting: If you insert a third-party JS file into a Vue application, you can also change the HTML before the Vue receives and activates the HTML from the server.

3) The server and client are in different states

Inconsistent states on the server and client are the most common cause of activation failures. As usual, the reasons for the inconsistencies vary widely.

  • Date, timestamp, and randomization

When a site contains a date or time stamp, be careful and make it as static as possible, especially if the site is statically generated. If the client evaluates an expression like new Date(), the expression may be different from the Date generated when the same Date was retrieved during the development phase on the server. It also confused me about the company’s “About” page, where I wanted to sort the people displayed by the current minute.

export const deterministicRotate = (arr) = > {
  if (arr.length <= 1) {
    return arr
  }
  const rotations = (new Date()).getMinutes() % arr.length

  return rotations ? arr : arr.reverse()
}
Copy the code

If the user opens the page at an odd time, plan to reverse the array. This works well when using dynamic SSR. But this feature becomes a Bug when switching to a statically generated JAMstack site. You can click the link to refresh a minute later and see that the name and person have been swapped correctly, but the image is the same as before. Oh, no! This is due to a server and client time mismatch. Work returned to normal after removing the nondeterministic code.

  • authorization

Another common reason for inconsistencies is user authentication. This applies to both dynamic SSR and static site generation. The server “does not know authentication” when authentication status is stored only on the client (for example, in localStorage). This inevitably leads to activation problems because the server and client information are fundamentally different at login time. Therefore, if the server does not know the authentication status of the page being statically generated **, ** should not render any authentication-related components on the server side. You might wonder why it always works for static sites: Because when the site is generated, it’s HTML, and serialized code is “stateless.” During the construction phase, we cannot consider “logged in user state.” This means that all authentication-related components must be excluded from rendering on the server.

  • Other reasons

In addition to these two cases, there are many more edge cases that can hit you and cause inconsistencies. We will resolve activation errors even if they are not listed here! First, we should narrow it down to the DOM element that is causing the problem.

4. Resolve the activation failure

1) Discover the element that causes activation failure

We can use devTools on your favorite browser to narrow the problem down to a specific component or DOM element.

  • Make sure you’re in a development environment
  • Open the development debugging tool
  • Trigger an activation alert (usually by reloading a web page)
  • an [Vue Warn] The client side ... Error message view trace stack (depending on browser, also open pop-up VueJS list)
  • Clicking on an activation callback will open the source code for the Vue activation function
  • Now, whenever this function returns false, a debugger is set, which happened three times while writing text:
if(process.env.NODE_ENV ! = ='production') {
  if(! assertNodeMatch(elm, vnode, inVPre)) {return false //HERE}}Copy the code
if(process.env.NODE_ENV ! = ='production' &&
          typeof console! = ='undefined' &&
          !hydrationBailed
    ) {
        hydrationBailed = true;
        console.warn('Parent: ', elm);
        console.warn('server innerHTML: ', i);
        console.warn('client innerHTML: ', elm.innerHTML);
    }
  return false //HERE
}
Copy the code
 if(process.env.NODE_ENV ! = ='production' &&
      typeof console! = ='undefined' &&
      !hydrationBailed
  ) {
    hydrationBailed = true;
    console.warn('Parent: ', elm);
    console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);
  }
  return false //HERE
}
Copy the code

This also allows the parameters of the activation function to be checked before the activation fails.

  • Last but not least, it is often possible but sometimes more difficult to reload the page to make the activation error reappear
  • You can now see that one of our breakpoints has been triggered and the script has stopped executing
  • Now open the debugger console and write an element to retrieve the DOM element where activation failed. Using DOM elements, you will be able to trace activation errors back to one of your Vue components
  • Proceed to the next step

PS: This is the order in which user Budden73 adapted StackOverflow’s answer.

2) Make sure your HTML markup is reasonable

Now that you’ve found the code causing the problem, the first thing you need to do is make sure your markup (perhaps from an API) is valid. Code like

Text

is invalid because a p element is not allowed to contain other block elements (such as paragraph tags) within it. Note, however, that the tag does not allow images

Such tags as child elements, these tags are the default tags for Vue transitions. You can do this by
.

3) Resolve the inconsistency between the server and the client

During the debugger, you can see the results from the server and redraw the client side. If there is a difference, you can take a look at how you get the data and what you render on the server or client side. A common problem is authentication of static web pages. Because HTML is generated stateless at build time and therefore does not know any authorization status, all authorization related parts of your application should be re-rendered on the client side. Otherwise, users with authorization status on the client side expect different HTML from the server side because of login. And then there’s only one option left…

4) Final avoidance measures:

The final option for resolving activation errors is to avoid component activation errors altogether. This is necessary for authentication-related components on statically generated pages, and sometimes for components that deliver content (for example, from third-party applications) that you can’t change but must embed. As we learned at the beginning, activation only occurs when the component is rendered on both the server and client sides. To avoid activation failures, you can avoid re-rendering server-side components by using tags. The only downside: This component is not included in the HTML returned by the server and does not help SEO.

5. To summarize

This article is over! Now you know more about vUE activation failures:

  • What is activation and what does it do?
  • How did the activation fail and how do I detect the activation failure?
  • Common cause of activation failure
  • How to debug activation failures and resolve your application

I hope this article was insightful and that you learned a thing or two. Did you encounter a cause of activation errors not described here, or did I miss a common cause? Feel free to send me a message on Twitter or via email. And as always – I’d be happy if you could spread the word and share your blog posts with your colleagues.

Three, step pit summary

This blog post covers most of the client-side activation failures I’ve encountered in server-side rendering, even the ones I haven’t. Of course, this blog also has shortcomings, for example, this is the article of 2020, some of the problems may have new progress, of course, there may also be many novices like me are still stepping on the pit. A final note on what I learned during development:

1. The isomorphism

Because our goal with isomorphism is to write code that is as generic as possible, that runs on both ends. Therefore, we need to be familiar with the operating environment of different terminals, at least familiar with the relevant API, node. js terminal has no browser object, so window, document, DOM operations can not be implemented. Similarly, there are no process objects on the browser side, and their RESPECTIVE API implementations are different, which needs to be kept in mind. Sometimes you don’t know if the introduced library will run entirely on the Node/browser side. If it only runs in a browser-only environment, it can be introduced and executed after the Created phase to avoid node.js.

2. Data prefetch problems

Problem: When using V-HTML to inject dynamically retrieved HTML content. If the HTML content has

Analysis: The page was actually rendered twice, the first time when SSR was delivered directly to the browser: now

Solution: Match the obtained HTML content and filter it out

** So why does the page render twice? **

This is because Vue SSR has a first encounter with chocolate after the initial page rendering, during which it carries out the life cycle of process and mounted as usual. At this point, it will determine whether the content rendered by the component at this time is consistent with the content rendered by SSR. If there is any inconsistency, an additional CSR will be performed separately (client activation failure) to achieve the page can be rendered correctly. Because we used V-HTML, this process was only performed during CSR, resulting in inconsistence between the two renders, triggering Vue SSR’s “compensation rendering mechanism” to perform the second render.

Refer to the article

  • Vue SSR guide
  • What to do when Vue hydration fails
  • Thoroughly understand server-side rendering – SSR principles
  • Vue. Js server rendering (SSR) does not completely refer to north
  • Understand server rendering from the ground up