HTML 5 Script Execution Events

Ya sea por pruebas de rendimiento, acciones previas o posteriores, comprobar en qué orden se están ejecutando, etcétera en ocasiones nos hubiera encantado tener el control de cuándo un script, ya sea un bloque entre el código HTML (por favor no :() o bien en archivos independientes, va a ejecutarse o ha sido ejecutado.

En la especificación del elemento script en HTML 5 se definen dos eventos para este cometido: beforescriptexecute y afterscriptexecute. El primero de ellos se lanzará antes de que el script se haya ejecutado y el segundo inmediatamente después.
Para verlo con un ejemplo, he implementado el siguiente escenario:

<!DOCTYPE html>
<html>
<head>
    <title>Script Execution Events</title>
</head>
<body>
    <ul id="message"></ul>
    <script id="inline-Block">
        function log(msg) {
            var li = document.createElement("li");
            li.textContent = msg;

            document.getElementById('message').appendChild(li);
        }

        log("Hello World from inline-Block");
    </script>
    <script id="handlers-block">
        document.addEventListener("beforescriptexecute", function (ev) {
            var script = ev.target.id != "" ? ev.target.id : ev.target.outerHTML;
            console.time(script);
            log("Starting script: " + script);
        }, true);

        document.addEventListener("afterscriptexecute", function (ev) {
            var script = ev.target.id != "" ? ev.target.id : ev.target.outerHTML;
            console.timeEnd(script);
            log("Finished script: " + script);

        }, true);
    </script>
    <script id="other-inline-block">
        log("Hello World from other-inline-block");
    </script>
    <script id="" src="Scripts/a.js"></script>
    <script src="Scripts/b.js"></script>
</body>
</html>

Como podemos ver en el código anterior, se han creado varios bloques: El primero de ellos es simplemente para crear una función llamada log donde vamos añadiendo los mensajes que se producen a través de código JavaScript y justo después tenemos el apartado handlers-block donde creamos los handlers, donde recuperamos el id del bloque o bien el outerHTML para saber a qué archivo corresponde el evento que acaba de ocurrir. Además, he utilizado console.time/console.timeEnd para determinar cuánto tiempo tarda un script desde que se reconoce que se va a ejecutar hasta que finalmente es ejecutado 🙂
El resultado de este ejemplo es el que sigue:

Script Execution Event

Si observamos la captura, vemos que se van registrando cada uno de los eventos y, en la consola, podemos ver los tiempos de ejecución de cada uno de ellos. Sin embargo, en el primer caso vemos que únicamente tenemos:

Hello World from inline-Block
Finished script: handlers-block

Se podría esperar:

Starting script: inline-Block
[Hello World from inline-Block] -> Si está presente
Finished script: inline-block
Starting script: handlers-block

Esto es evidente, debido a que inline-Block se ejecuta antes de que el manejador haya sido enlazado y la función log está contenida en él, para que el resto pueda utilizar dicho método (Firefox se queja cuando una función está siendo llamada antes de ser declarada, aunque navegadores como Chrome hace caso omiso). Por otro lado, el script con id handlers-block es detectado únicamente al finalizar, ya que es en ese momento cuando ya están enlazados los eventos con sus funciones correspondientes.

A día de hoy, estos eventos sólo están implementados para Firefox 17+. El resto de navegadores por el momento no soportan esta funcionalidad. Más información.

Espero que haya sido de utilidad.

¡Saludos!