Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display a progress bar while loading single bundled javascript file by webpack?

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!

like image 817
Nicolas S.Xu Avatar asked Feb 04 '16 08:02

Nicolas S.Xu


2 Answers

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

like image 194
Dmitriy V. Avatar answered Oct 13 '22 21:10

Dmitriy V.


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>
like image 35
Viktor Tabori Avatar answered Oct 13 '22 22:10

Viktor Tabori