Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle "Loading chunk failed" errors with Lazy-loading/Code-splitting

Tags:

We are developing a Vue.js application based on Vue CLI 3 with Vue Router and Webpack. The routes are lazy-loaded and the chunk file names contain a hash for cache busting. In general, everything is working fine.

However, there is a problem during the deployment. Steps to reproduce are the following.

  • User opens the application (let's assume route "/"), thus the main chunk file is loaded.
  • We change something in the application and deploy a new version.
    • Old chunk files are removed
    • New chunk files are being added (i.e. hashes in the chunk file names change)
  • User clicks a link to another route (e.g. "/foo")
    • An error occurs as the application tries to load a chunk file that has been renamed: Error: "Loading CSS chunk foo failed. (/assets/css/foo.abc123.css)" (this might be CSS or JavaScript)

What is the best way to avoid errors like this?

  • One approach that should work is just to retain old chunk files and delete them at a later time. That, however, complicates the deployment of new versions as you need to keep track of old versions and always also deploy the old chunk files with the new version.

  • Another (naive) approach is to just reload as soon as such an error is detected (e.g. Vue Lazy Routes & loading chunk failed). It somewhat works, but it reloads the old route, not the new one. But at least it ensure that consecutive route changes work again.

Any other ideas? Maybe there is something in webpack that could fix this?

like image 714
str Avatar asked Feb 26 '19 16:02

str


People also ask

How do I fix loading chunk failed?

If you are encountering this error as a user of an application, the simplest way to resolve it is to clear your browser cache (and also restart it for good measure) and try again. If the error was because your browser had cached older files, this should fix the issue.

What is the difference between code splitting and lazy loading?

As the name suggests lazy loading is a process of loading parts (chunks) of your application lazily. In other words — loading them only when we really need them. Code splitting is just a process of splitting the app into this lazily loaded chunks.

What is code splitting?

Code splitting is the splitting of code into various bundles or components which can then be loaded on demand or in parallel. As an application grows in complexity or is maintained, CSS and JavaScripts files or bundles grow in byte size, especially as the number and size of included third-party libraries increases.


2 Answers

DoNOT cache the entry file(usually index.html). We add:

expires 0; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate'; 

in our nginx server config.

Then, after you refreshed the client's code, you can use the vue-router's error hook to detect the error and do something properly.

like image 146
zhangv Avatar answered Oct 01 '22 06:10

zhangv


As long as you have a versioned API, you can use the old app files (just leave them on the server and delete after a vew days).

You will get problems as soon as your API changes during deployments.

I assume, you deploy a new API each time you deploy new JS code.

Then you can:

  • Pass on the API version (simply use the git hash) to the application as header with every response (JS resources, CSS, API requests, 404 responses)
  • Store the API version in your main JS entry point (or make it accessible somehow, e.g. as generated constant)
  • On each server response, check if the Server version matches your main client version.
  • If it does not: Display a prominent warning to the user (like the cookie banners) that he should reload the page (=> allows the user to save chnages in hope the API did not change for that save button).

For async components, we display normal 'not found' messages if loading fails, together with a reload button that appears instead of the component. Reloading without user interaction will cause a lot of confusion.

like image 41
Michael2 Avatar answered Oct 01 '22 07:10

Michael2