web-dev-qa-db-fra.com

Calcul du temps de chargement d'une page en JavaScript

J'essaie de créer une page Web qui, lorsqu'elle commence à se charger, utilise un intervalle pour démarrer une minuterie.

Lorsque la page se charge complètement, il arrête le chronomètre,

mais 99% du temps, j’obtiens des mesures de temps de 0,00 ou 0,01 même si cela prend plus de temps.

De temps en temps, cela dit quelque chose qui a plus de sens comme 0,28 ou 3,10 à certains moments.

Voici le code si cela peut aider:

var hundredthstimer = 0;
var secondplace = 0;

function addinc(){

    hundredthstimer += 1;
    if (inctimer == 100){
        hundredthstimer = 0;
        secondplace += 1;
    }

}

var clockint = setInterval(addinc, 10);

function init(){
    var bconv1 = document.getElementById("bconverter1");
    var bconv2 = document.getElementById("bconverter2");

    $(bconv2).hide();

    clearInterval(clockint);

    if (inctimer.len !== 2){
        inctimer = "0" + inctimer;
    }
    alert(secondplace + "." + inctimer);
}
onload = init;

Donc, cela crée fondamentalement une variable appelée centième compteur qui est augmentée de '1' toutes les 10 millisecondes (.01 secondes).

Ensuite, si ce nombre atteint 1000 (1 seconde complète), une variable appelée secondesplace augmente de 1, car elle correspond au nombre de secondes complètes écoulées.

Ensuite, il alerte secondesplace, un point décimal et centième comme le temps de chargement total.

Mais le problème ci-dessus avec des nombres incorrects existe toujours. Pourquoi?

60
zingzing45

N'utilisez jamais les fonctions setInterval ou setTimeout pour mesurer le temps! Ils ne sont pas fiables et il est très probable que la planification de l'exécution de JS lors de l'analyse et de l'affichage des documents est retardée.

Utilisez plutôt l'objet Date pour créer un horodatage au début du chargement de la page et calculez la différence par rapport au moment où la page a été entièrement chargée:

<doctype html>
<html>
    <head>
        <script type="text/javascript">
            var timerStart = Date.now();
        </script>
        <!-- do all the stuff you need to do -->
    </head>
    <body>
        <!-- put everything you need in here -->

        <script type="text/javascript">
             $(document).ready(function() {
                 console.log("Time until DOMready: ", Date.now()-timerStart);
             });
             $(window).load(function() {
                 console.log("Time until everything loaded: ", Date.now()-timerStart);
             });
        </script>
    </body>
</html>
67
Bergi

Pourquoi si compliqué? Quand tu peux faire:

var loadTime = window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart;

Si vous avez besoin de plus de temps, consultez l’objet window.performance:

console.log(window.performance);

Vous montrera l'objet de chronométrage:

connectEnd                 Time when server connection is finished.
connectStart               Time just before server connection begins.
domComplete                Time just before document readiness completes.
domContentLoadedEventEnd   Time after DOMContentLoaded event completes.
domContentLoadedEventStart Time just before DOMContentLoaded starts.
domInteractive             Time just before readiness set to interactive.
domLoading                 Time just before readiness set to loading.
domainLookupEnd            Time after domain name lookup.
domainLookupStart          Time just before domain name lookup.
fetchStart                 Time when the resource starts being fetched.
loadEventEnd               Time when the load event is complete.
loadEventStart             Time just before the load event is fired.
navigationStart            Time after the previous document begins unload.
redirectCount              Number of redirects since the last non-redirect.
redirectEnd                Time after last redirect response ends.
redirectStart              Time of fetch that initiated a redirect.
requestStart               Time just before a server request.
responseEnd                Time after the end of a response or connection.
responseStart              Time just before the start of a response.
timing                     Reference to a performance timing object.
navigation                 Reference to performance navigation object.
performance                Reference to performance object for a window.
type                       Type of the last non-redirect navigation event.
unloadEventEnd             Time after the previous document is unloaded.
unloadEventStart           Time just before the unload event is fired.

Support du navigateur

Plus d'infos

186
HaNdTriX

La réponse mentionnée par @HaNdTriX est excellente, mais nous ne savons pas si DOM est complètement chargé dans le code ci-dessous:

var loadTime = window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart; 

Cela fonctionne parfaitement lorsqu'il est utilisé avec onload comme:

window.onload = function () {
    var loadTime = window.performance.timing.domContentLoadedEventEnd-window.performance.timing.navigationStart; 
    console.log('Page load time is '+ loadTime);
}

Edit 1: Ajout d'un contexte pour répondre

Note:loadTime est en millisecondes, vous pouvez diviser par 1000 pour obtenir les secondes mentionnées par @nycynik

31
Samdeesh

Il est difficile de faire un bon timing, car le performance.dominteractive est mal calculé (de toute façon un lien intéressant pour les développeurs de chronométrage).

Lorsque dom est analysé, il peut toujours charger et exécuter des scripts différés. Et les scripts en ligne en attente de css (css blocking dom) doivent également être chargés jusqu’à DOMContentloaded . Donc ce n'est pas encore analysé?

Et nous avons readystatechange événement où nous pouvons regarder readyState qui manque malheureusement "dom est analysé" et qui se situe quelque part entre "chargé" et "interactif".

Tout devient problématique quand même pas l'API Timing nous donne une heure où dom a arrêté d'analyser HTML et de démarrer le processus The End . Cette norme dit que le premier point doit être que "interactif" se déclenche précisément après dom analysé ! Les deux Chrome et FF l’ont implémenté lorsque le document est terminé chargement peu de temps après qu’il soit Ils semblent (mal) interpréter les normes car l'analyse se poursuit au-delà des scripts différés exécutés, alors que les gens interprètent mal DOMContentLoaded comme un obstacle avant l'exécution différée et non après.

Ma recommandation pour vous est de lire sur API Navigation Timing . Ou choisissez la solution la plus simple et choisissez-en un, ou exécutez-les tous les trois et regardez dans la console de votre navigateur ...

  document.addEventListener('readystatechange', function() { console.log("Fiered '" + document.readyState + "' after " + performance.now() + " ms"); });

  document.addEventListener('DOMContentLoaded', function() { console.log("Fiered DOMContentLoaded after " + performance.now() + " ms"); }, false);

  window.addEventListener('load', function() { console.log("Fiered load after " + performance.now() + " ms"); }, false);

Le temps est en millisecondes après le début du document. J'ai vérifié avec API Navigation Timing .

Pour obtenir des secondes par exemple à partir du temps que vous avez fait var ti = performance.now(), vous pouvez faire parseInt(performance.now() - ti) / 1000

Au lieu de ce genre de soustractions performance.now (), le code devient un peu plus court de API de synchronisation utilisateur où vous définissez marques dans votre code et mesure entre les marques.

0