javascript - w3schools - jquery documentation
¿Por qué se recomienda jQuery.ready cuando es tan lento? (4)
He hecho una pregunta similar antes, pero nunca expuse mi punto de vista con claridad, o al menos creo que es una pregunta tan relevante que vale la pena mencionarla y ver si alguien puede dar algunos pensamientos profundos.
Cuando usamos jQuery, muchos de nosotros usamos la función jQuery.ready
para ejecutar un init
cuando el DOM se ha cargado. Se ha convertido en la forma estándar de facto de agregar programas de manipulación DOM a una página web usando jQuery. Un evento relacionado existe de natively algunos navegadores, pero jQuery lo emula en otros navegadores, como algunas versiones de IE. Ejemplo:
<head>
<script>
var init = function() { alert(''hello world''); };
$.ready(init);
</script>
Ahora, todas nuestras pruebas muestran que este evento puede ser bastante lento. No es tan lento como window.onload
, pero a menudo todavía tiene una demora de 100 ms antes de la ejecución. Si FF puede ser de hasta 200-300 ms, especialmente en la actualización.
Estos son algunos milisegundos muy importantes, porque esta es la cantidad de tiempo que se muestra el diseño inicial antes de realizar cualquier manipulación DOM (como ocultar un menú desplegable). Muchas veces, un "parpadeo" de diseño se debe principalmente al uso de un evento lento preparado para DOM, lo que obliga a los programadores a ocultar elementos mediante CSS en lugar de hacerlo potencialmente menos accesibles.
Ahora, si en su lugar colocamos una función de inicio en una etiqueta de script antes de cerrar la etiqueta de cuerpo, se ejecutará mucho más rápido, por lo general alrededor de la mitad del tiempo, pero a veces incluso más rápido:
<head>
<script>
var init = function() { alert(''hello world''); };
</script>
</head>
<body>
<!-- some HTML -->
<script>init();</script>
</body>
Una página de prueba simple que demuestra las diferencias: http://jsbin.com/aqifon/10
Quiero decir, no estamos hablando de diferencias apenas perceptibles ya que algunos de los "policías de optimización" promueven cuando se trata de usar selectores efectivos. Estamos hablando de algunas demoras importantes cuando se realizan cargas de DOM manipuladas. Al probar este ejemplo en FF, domready a veces puede ser más de 100 veces más lento (300 ms frente a 2 ms).
Ahora a mi pregunta: ¿Por qué se recomienda utilizar jQuery.ready
cuando es obviamente mucho más lento que otras alternativas? ¿Y cuáles son los inconvenientes de llamar a init
antes de cerrar el CUERPO vs usar jQuery.ready
? domReady
decirse que es más "seguro" usar domReady
, pero ¿en qué contexto es más seguro que la otra opción? (Estoy pensando en cosas como document.write
y scripts diferidos) Hemos usado BODY
durante casi 5 años en muchos sitios de clientes, y nunca nos encontramos con ningún problema. Es mucho más rápido.
También me pregunto, dado que hay tanta confusión sobre jsPerf y optimización de selectores por un par de ms por cada 10000 ejecuciones, ¿cómo es que no se habla mucho de esto? Básicamente es la primera demora que enfrenta el usuario, y parece ser bastante simple cortar 50-100 ms en cada carga de página ...
Para el punto primero:
No, no hay ninguna desventaja al llamarte init
antes de cerrar el <body>
. Como se habrá dado cuenta, tendrá un mejor rendimiento que depender de $.ready()
y también funcionará con todos los navegadores sin problemas (incluso en IE).
Ahora, sin embargo, hay razones para usar $.ready()
, que en su caso probablemente no se apliquen:
-
$.ready()
facilita a los desarrolladores hacer las cosas en el orden correcto. En particular, lo más importante es no hacer referencia a los elementos DOM que no se han cargado. Si bien esto es bastante simple, muchos desarrolladores aún lo encuentran confuso.$.ready()
es una obviedad, aunque lenta. - En el caso de que diga varios scripts que necesitan
init()
, no es necesariamente fácil / conveniente hacerlo manualmente al final de su cuerpo. Requiere disciplina y conocimiento de lo que hacen estos guiones. En particular, a menudo verá$.ready()
en bibliotecas dependientes de jQuery, ya que hace que las cosas funcionen sin importar de qué manera los desarrolladores usarán para cargar las librerías. - Con la definición de módulo asíncrono (por ejemplo require.js ) se está popularizando como una forma de cargar su javascript, el final del método
<body/>
no está garantizado.
Porque hace que domReady y window.load sean más lentos.
Es fácil de optimizar para la métrica, en lugar de la experiencia real del usuario. Entonces los gráficos de "optimización del usuario real" disminuyen, aunque la interacción se retrasa.
Si ha escrito un archivo JS que otras personas están incluyendo en sus páginas, es más seguro usar document.ready dentro de ese archivo (suponiendo que necesita hacer algún procesamiento automáticamente después de que DOM esté listo) porque no puede estar seguro de si el archivo se incluirá en la cabeza o en el extremo del cuerpo.
Cuando se trata de páginas sobre las que tienes un control total, obviamente no tienes esa preocupación, así que no veo que sea más "seguro" usar document.ready en lugar de llamar a tu init()
desde el final del cuerpo. Usar document.ready (o onload) y poner script en el extremo del cuerpo son las dos formas más comunes de hacerlo, y son comunes porque ambos funcionan bien.
Usted mencionó document.write()
como una posible excepción, pero no desea llamar a eso desde document.ready o al final del cuerpo porque de cualquier manera toda la página ya ha sido analizada.
Una ventaja sería que puede colocar el código en cualquier lugar de la página. En nuestro caso, utilizamos un sistema de plantillas en nuestro CMS que sutura la página de alrededor de 10 a 30 plantillas para las diferentes partes (dependiendo de la complejidad).
Dado que desea que las plantillas funcionen en cualquier página que se utilicen, debe incluir el Javascript necesario en ella. Para esos casos, la función ready()
es un verdadero salvavidas.