HTML
script, noscript, modules e import maps
Cómo cargar JavaScript desde HTML con scripts clásicos, módulos, defer, async, noscript e import maps, y cómo afectan parsing y ejecución.
- Última actualización
- Actualizada
- Nivel
- Aplicación
HTML
Cómo cargar JavaScript desde HTML con scripts clásicos, módulos, defer, async, noscript e import maps, y cómo afectan parsing y ejecución.
<script src="/app.js"></script>Sin async o defer, puede:
Esto puede bloquear la construcción del documento.
<script defer src="/app.js"></script>Descarga en paralelo y ejecuta después de terminar parsing, antes de DOMContentLoaded.
Varios scripts defer conservan el orden del documento.
Solo tiene efecto relevante sobre scripts externos clásicos.
<script async src="/analytics.js"></script>Descarga en paralelo y ejecuta tan pronto está disponible. No garantiza orden respecto a otros async ni espera al final del parsing.
Aporta para scripts independientes como analytics, siempre que su ejecución temprana y privacidad estén controladas.
<script type="module" src="/main.js"></script>Los modules:
defer no necesita añadirse.
<script type="module" async src="/main.js"></script>Ejecuta cuando el grafo está disponible sin esperar el orden normal. Úsalo solo cuando el módulo es independiente.
<script type="module" src="/modern.js"></script>
<script nomodule src="/legacy.js"></script>Fue un patrón de transición para navegadores sin modules. En proyectos con soporte moderno puede ser innecesario y duplicar estrategia de build.
<script>
document.documentElement.classList.add("js");
</script>Forma parte de HTML, complica CSP y puede bloquear parsing. Manténlo mínimo, con nonce/hash cuando la política lo permite, o usa archivo externo.
Entrada no confiable dentro de script necesita encoding específico de JavaScript/HTML; no concatenes JSON o strings sin una serialización segura.
<script type="application/json" id="initial-data">
{"projectId":"domisys"}
</script>El navegador no lo ejecuta como JavaScript. Un script puede leer su textContent y parsear JSON.
Aun así, la serialización debe evitar cerrar accidentalmente el elemento mediante secuencias como </script> y debe considerar CSP/XSS.
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"Person"}
</script>Contiene datos estructurados para consumidores, no código ejecutable ordinario.
<noscript>
<p>Activa JavaScript para utilizar el editor interactivo.</p>
</noscript>Su parsing depende de si scripting está habilitado y de si aparece en head o body.
No lo uses para culpar al usuario. Ofrece contenido o alternativa útil.
En una app que requiere JavaScript, explica qué funcionalidad falta; en contenido básico, procura que HTML siga siendo funcional.
<script
src="https://cdn.example.com/library.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>Subresource Integrity permite verificar que el contenido coincida con un hash esperado.
El recurso necesita una respuesta CORS compatible cuando es cross-origin. Al actualizar el archivo, actualiza el hash.
Para modules cross-origin y reportes detallados de errores, la política CORS importa.
<script
src="https://cdn.example.com/app.js"
crossorigin="anonymous"
></script>No concede acceso por sí solo; el servidor debe responder con headers adecuados.
<script
src="https://external.example/widget.js"
referrerpolicy="no-referrer"
></script>Controla información de referrer durante la carga y dependencias relacionadas según el contrato.
<script src="critical.js" fetchpriority="high"></script>Es una pista de prioridad. No conviertas todos los scripts en high; mide el efecto.
Características modernas pueden permitir declarar ciertos bloqueos de render mediante blocking. Es una herramienta especializada y dependiente de soporte; no debe reemplazar una estrategia clara de carga.
<script type="importmap">
{
"imports": {
"lit": "/vendor/lit/index.js",
"@app/": "/src/"
}
}
</script>Define cómo el navegador resuelve specifiers de módulos.
import { html } from "lit";Debe declararse antes de modules que usan esos specifiers.
<script type="importmap">
{
"imports": {
"library": "/v2/library.js"
},
"scopes": {
"/legacy/": {
"library": "/v1/library.js"
}
}
}
</script>Permiten resoluciones diferentes bajo rutas específicas.
No:
Solo participan en resolución de specifiers del navegador.
HTML admite otros tipos de script declarativo en evolución. Mantén features cambiantes en una nota de compatibilidad y verifica el estándar/soporte antes de usarlas.
<script type="importmap">
{
"imports": {
"@app/": "/assets/"
}
}
</script>
<script type="module" src="/assets/main.js"></script>¿Por qué dos scripts async no deberían depender del orden en que aparecen?
Porque cada uno se ejecuta cuando termina su descarga, por lo que el orden real depende de la red y no del documento.
template, slots y custom elements explica componentes declarativos y su relación con el DOM.