Charging bar with pure JavaScript

3

Sometimes I see load bars with percentage in sites that I believe, they override the default behavior of the page when loading (white screen until content is ready). There are some jQuery plugins that do this, but I want to understand exactly how this process works with pure JS.

I rely on what to find the loading percentage on a page?

    
asked by anonymous 19.02.2015 / 15:04

1 answer

2

Based on the pace.js plugin ( link ), it uses a number of methods to detect the page load percentage:

  •  
      Ajax requests:   
        - The plugin checks the requests, calculating the percentage of each one depending on its type:     
          If the request is an XMLHttpRequest it uses the "progress" event, which returns an object with the size of the file being downloaded and how long it has been completed, if Content-Length is available in the Response Request Header. In addition to checking the events "load", "abort", "timeout" and "error" to determine if the request is over.
    request.addEventListener('progress', function(evt) {
          //Verifica se Content-Length foi declarado no Header de resposta
          if (evt.lengthComputable) {
            //Calcula a porcentagem de acordo com o quanto já foi baixado.
            return _this.progress = 100 * evt.loaded / evt.total;
          } else {
            //Se não há Content-Length retorna uma porcentagem sintética.
            return _this.progress = _this.progress + (100 - _this.progress) / 2;
          }
        }, false);
    

       

      If the request type is a WebSocket it checks the "error" and "open" events to determine if the request is terminated.
    SocketRequestTracker = (function() {
      function SocketRequestTracker(request) {
        var event, _j, _len1, _ref2,
          _this = this;
        this.progress = 0;
        _ref2 = ['error', 'open'];
        //Registra listener aos eventos acima para determinar quando conexão estiver estabelecida, ou não.
        for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
          event = _ref2[_j];
          request.addEventListener(event, function() {
            return _this.progress = 100;
          }, false);
        }
      }
    
      return SocketRequestTracker;
    })();
    

        

  •  
      HTML document:   
        - The plugin uses document.readystate to determine the state the document is in ("loading", "interactive", "complete") and assigns a percentage for each .
    DocumentMonitor = (function() {
      //Determina porcentagens para cada estado de document.readyState.
      DocumentMonitor.prototype.states = {
        loading: 0,
        interactive: 50,
        complete: 100
      };
    
      function DocumentMonitor() {
        var _onreadystatechange, _ref2,
          _this = this;
        //Verifica document.readystate e atribui valor ao estado atual da página
        this.progress = (_ref2 = this.states[document.readyState]) != null ? _ref2 : 100;
        _onreadystatechange = document.onreadystatechange;
        //Nas mudanças de estado atualiza o valor da porcentagem
        document.onreadystatechange = function() {
          if (_this.states[document.readyState] != null) {
            _this.progress = _this.states[document.readyState];
          }
          return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0;
        };
      }
    
      return DocumentMonitor;
    })();
    

     

  •  
      Lag in Event Loop:   
        - The plugin checks through the lag in the event loop if javascript code is running and calculates a percentage relative to lag.
    EventLagMonitor = (function() {
      function EventLagMonitor() {
        var avg, interval, last, points, samples,
          _this = this;
        this.progress = 0;
        avg = 0;
        samples = [];
        points = 0;
        last = now();
        //Utiliza um timer para calcular o Lag no loop de eventos do javascript
        interval = setInterval(function() {
          var diff;
          //Calcula a diferença entre o tempo de execução determinado para o Timer (50ms) e o tempo real de execução
          diff = now() - last - 50;
          last = now();
          samples.push(diff);
          if (samples.length > options.eventLag.sampleCount) {
            samples.shift();
          }
          //Calcula a amplitude media a partir dos Lag's salvos
          avg = avgAmplitude(samples);
          //Verifica se a amplitude dos Lag's está acima do limite na execução do javascript
          if (++points >= options.eventLag.minSamples && avg < options.eventLag.lagThreshold) {
            _this.progress = 100;
            return clearInterval(interval);
          } else {
            //Se estiver, calcula a porcentagem a partir dessa amplitude.
            return _this.progress = 100 * (3 / (avg + 3));
          }
        }, 50);
      }
    
      return EventLagMonitor;
    })();
    

     

  •  
      HTML elements (optional):   
        - The plugin checks for certain default elements using document.querySelector .
    //De acordo com a documentação - Define as classes/id's a serem verificados pelo pace.js
    paceOptions = {
     elements: {
      selectors: ['.timeline,.timeline-error', '.user-profile,.profile-error']
     }
    }
    


    //Para verificar a existência dos elementos no documento
    ElementTracker = (function() {
      function ElementTracker(selector) {
        this.selector = selector;
        this.progress = 0;
        this.check();
      }
    
      ElementTracker.prototype.check = function() {
        var _this = this;
        if (document.querySelector(this.selector)) {
          return this.done();
        } else {
          return setTimeout((function() {
            return _this.check();
          }), options.elements.checkInterval);
        }
      };
    
      ElementTracker.prototype.done = function() {
        return this.progress = 100;
      };
    
      return ElementTracker;
    })();
    

     

  •     
    15.04.2015 / 02:21