15

The question is concerning webpack. After packing almost everything into a single bundle.js which is loaded in index.html, the bundle.js file is about 2M and requires several seconds to load.

I'd like to display a progress bar indicating loading progress while hiding all the content. Only enable user interaction and show the content after loading is done, exactly the one that Gmail is using.

Is it possible to use webpack to do that? How?

Thanks!

Nicolas S.Xu
  • 13,794
  • 31
  • 84
  • 129
  • it could be possible to do, but I don't think it's possible if bundle.js is loaded in a ` – Jaromanda X Feb 04 '16 at 08:39
  • 1
    Possible duplicate of [How can I get the progress of a downloading – Jaromanda X Feb 04 '16 at 08:41
  • Since downloading and appending a JS file while assessing progress is not really trivial, I don't think this is duplicate, see the answer below. – Viktor Tabori May 06 '17 at 21:05

2 Answers2

2

Since downloading the source of a JS and appending it to the DOM could be quite painful, you normally would use jQuery.getScript(url [, success ]). But you can't set a progress function on that call.

Lucky for us: https://api.jquery.com/jquery.getscript/

This is a shorthand Ajax function, which is equivalent to:

$.ajax({
  url: url,
  dataType: "script",
  success: success
});

And on an jQuery.ajax() call we can set a progress function.

We can calculate the progress percentage if the server includes the response size in http headers. Otherwise we can only use the total received bytes at each progress event call.

$.ajax({
  url: 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js', // unminified angular is 1.2mb, perfect for demonstration :)
  dateType: 'script',
  xhr: function()
  {
    var xhr = new window.XMLHttpRequest();
    //Download progress
    xhr.addEventListener("progress", function(evt){
      // do something with progress info
      if (evt.lengthComputable) {
        // we can calculate the percentage
        var percentComplete = evt.loaded / evt.total;
        //Do something with download progress
        console.log(percentComplete);
      } else if (evt.loaded)
        // we only know the received amount and not the total amount
       console.log('downloaded:',evt.loaded);
    }, false);
    return xhr;
  }
}).done(function( data, textStatus, jqXHR ) {
  console.log('finished');
}).fail(function( jqXHR, settings, exception ) {
  console.log('could not load');
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
Viktor Tabori
  • 2,087
  • 1
  • 13
  • 14
1

I tried to solve the same problem and ended up writing bootloader and webpack plugin. The webpack plugin collects metadata about js, css and its sizes, inject this metadata into index.html. Bootloader loads assets and calculate current progress using the injected metadata.

Check out the source code of demo app. Here is my article about this.

What it looks like: Loading splash screen

Dmitriy V.
  • 47
  • 1
  • 4
  • While this link can provide an answer to the question, it is necessary to add all info needed to the answer. Please consider editing the answer with more information. Also your website with article has broken CSS and is very hard to read. – Ruli Dec 21 '20 at 17:15
  • 1
    @Ruli it is very hard to add all needed info because there is too much code. The main idea I have already described in the answer. – Dmitriy V. Dec 21 '20 at 19:04