Html5-boilerplate: solución de carga de scripts

Creado en 10 ago. 2010  ·  132Comentarios  ·  Fuente: h5bp/html5-boilerplate




Este hilo de problemas ahora está cerrado.

Fue divertido, pero las conversaciones se han trasladado a otra parte por ahora. Gracias

En agradecimiento por los tiempos de diversión que tuvimos, @rmurphey nos hizo una feliz nube de palabras del hilo.

Disfrutar.





a través de labjs o require.

mi archivo load.js "boilerplate" tiene LABjs insertado, y luego lo usa para cargar jquery, GA y un archivo js de un sitio. si ayuda, tengo un RequireJS + jQuery integrado en un archivo: http://bit.ly/dAiqEG;)

también, ¿cómo influye esto en la expectativa de un script de compilación que concatene y minimice todo el script? ¿Debería ser una opción la carga de scripts?

javascript

Todos 132 comentarios

kyle: " @paul_irish , no estoy de acuerdo. http://bit.ly/9IfMMN caché (CDN externos), descarga paralela, cambio de secuencia de comandos-volatilidad ..."

james burke: " @paul_irish @fearphage @getify RequireJS tiene una herramienta de compilación para hacer paquetes / minificación de scripts, por lo que puede tener lo mejor de ambos: dinámico y prediseñado"

La forma más fácil para que los desarrolladores comiencen con la carga de scripts probablemente sea usando $ Lab.js, porque ya está usando la sintaxis de encadenamiento con la que están familiarizados muchos usuarios de jQuery.

Si están creando aplicaciones para grandes empresas, siempre pueden migrar a require.js si es necesario.

Actualmente existen tres técnicas principales de carga de scripts:

  1. HeadJS
  2. ControlJS
  3. LABjs

úselo o no, cuál usar es un poco discutible: http://blog.getify.com/2010/12/on-script-loaders/

También hay requireJS y EnhanceJS solo para informarle las alternativas a HeadJS ControlJS y LabJS . Incluso Yahoo y Google ofrecen algo similar.

Con el lanzamiento de jQuery 1.5 y diferidos - http://www.erichynds.com/jquery/using-deferreds-in-jquery/ , Boris Moore los está utilizando en DeferJS, un nuevo proyecto de cargador de scripts: https: // github. com / BorisMoore / DeferJS

De forma predeterminada, la carga del script detiene todas las demás descargas, por lo que descargar modernizr en el encabezado es malo. El cargador integrado tiene sentido, porque los cargadores pueden descargar secuencias de comandos en paralelo y en modo sin bloqueo. Por ejemplo, si no necesita todas las funciones de modernizr, puede insertar head.min.js, que es de solo 6kb, o una compilación personalizada de modernizr (http://modernizr.github.com/Modernizr/2.0-beta/). Insertar CSS a veces también tiene sentido. Google usa inlining, ellos inline css, js y gifs 1x1 vacíos a través de datauri.

LabJS se está volviendo bastante utilizado y es una buena solución; también se puede incluir de forma asincrónica, por lo que no es necesario bloquear.

http://blog.getify.com/2010/12/on-script-loaders/ es del autor

http://yepnopejs.com/ acaba de pasar a la versión 1.0 y no se rompe en el nuevo webkit, a diferencia de LAB y head.js. La carga de secuencias de comandos es difícil.

yepnope también está integrado en Modernizr como Modernizr.load .. http://modernizr.github.com/Modernizr/2.0-beta/

Así que probablemente tengamos un cargador de scripts en h5bp a través de Modernizr.load muy pronto.

No creo que sea 1.0, pero una vez que lleve Modernizr a 1.8, lo lanzaremos a h5bp 1.1. Sí

Hola Pablo

He transferido un sitio existente para usar su H5BP y quiero usar el cargador de scripts yepnope.js. Es realmente agradable ver todos los bits y bots reunidos como lo ha hecho.

¿Qué recomendarías usar en este momento?

  1. Incluya yepnope.js junto con modernizer.js en la parte superior de la página
  2. Inclúyalo en la parte inferior de la página, para que se cargue después de que el HTML haya terminado de cargarse.
  3. Utilice la versión beta de modernizer.js
  4. Podría concatenar yepnope.js con modernizer.js en una inclusión.

Independientemente de la mejor manera de incluirlo, ¿cómo recomienda cargar los scripts con yepnope, js?

Supongo que deberíamos hacerlo por aquí: https://github.com/paulirish/html5-boilerplate/blob/master/index.html#L52 y usar yepnope para cargar la copia CDN / Local de jQuery y nuestros otros scripts.

Pero, ¿cree que es mejor usar un script externo que incluya o renderice un bloque de script dentro del html, que luego carga los scripts a través de yepnope.js?

Muchas gracias.

Andy

Ah, y otra cosa.

Como yepnope puede cargar css a través de, yo diría que es mejor incluir el css principal como lo haría normalmente y usar yepnope para incluir solo css para arreglos específicos.

Por ejemplo, incluye algunos css que solo se aplican a versiones anteriores de IE.

hokapoka,

Use la versión beta de modernizr ... solo incluya lo que necesita (e incluya Modernizr.load() ) y luego colóquelo en la parte superior de la página.

el código real para el respaldo de jquery con yepnope está en http://yepnopejs.com/

Y sí, me gusta tu idea de la carga condicional de IE css.

tbh hay demasiada fe ciega en torno a los cargadores de scripts con respecto al rendimiento y no creo que estemos listos para decir que ESTA ES LA MANERA CORRECTA.

necesitamos más investigación sobre los tamaños de archivos, el ancho de banda y las condiciones de la red que indiquen recomendaciones inteligentes sobre la carga de scripts, pero en este momento el campo es incipiente y sería ingenuo recomendar una solución general de carga de scripts.

asi que.

cerrar este ticket y pedirle a cualquier persona interesada que realice la investigación y la publicación exhaustivas necesarias para que sea más fácil para los desarrolladores tomar una decisión inteligente sobre este

He investigado bastante acerca de la carga paralela frente a concat. Aún así, sin reservas, hago la recomendación de combinar todos los js en un archivo primero, luego dividirlo en 2-3 ~ trozos de igual tamaño y cargarlos en paralelo.

Me encantaría poder llevar mi investigación y difundirla ampliamente y a escala, de modo que sea viable como un "hecho" en esta área. El problema es que intenté e intenté encontrar un ancho de banda de alojamiento en el que no me costaría mucho dinero ejecutar las pruebas a escala, y todavía no he podido encontrar esa provisión de alojamiento.

Si yo / nosotros podemos resolver el problema del ancho de banda para la prueba, tengo las pruebas que se pueden ejecutar para averiguar si la teoría de la carga paralela es de hecho viable (como creo que lo es).

@getify ¿qué necesitas en cuanto a una plataforma de prueba?

Puedo hacer alrededor de 1,5 TB más de datos de mi servidor personal de los que estoy usando actualmente. Tengo Nginx instalado y eso puede manejar alrededor de 4 billones de billones de visitas por microsegundo. No siento que la tecnología sea la barrera aquí.

Si nos preocupan las ubicaciones, podemos falsificar una latencia más alta y / o encontrar un par de personas más con un poco de espacio adicional en sus cajas.

Por cierto, tomo un pequeño problema con la "fe ciega".

Es fácil, demostrable y casi sin lugar a dudas cierto que si tiene un sitio existente que carga muchos scripts con etiquetas de script, el uso de un cargador de scripts en paralelo (sin otros cambios) mejora el rendimiento. Esto es cierto porque incluso los navegadores más nuevos no pueden (y nunca lo harán, no creo) desanclar la carga de scripts del bloqueo de DOM-ready. Entonces, incluso en el mejor de los casos, la carga del navegador, si no hay otro beneficio, acelerar drásticamente la compatibilidad con DOM en un sitio es casi siempre una victoria (para los usuarios y UX).

Su declaración es una premisa un poco falsa porque asume que estamos tratando de comparar, para cada sitio, la carga paralela con script-concat. La mayoría de los sitios en la web no pueden / no pueden usar script-concat, por lo que realmente la comparación (para ellos, la mayoría) no es tan matizada y complicada como se supone. Si no pueden usar script-concat (por el motivo que sea), la comparación es simple: la carga en paralelo es casi siempre una ventaja sobre las etiquetas de script.

Si están abiertos a script-concat (o ya lo usan), entonces sí, se vuelve un poco más matizado / complicado decidir si la carga en paralelo podría ayudar o no. Pero script-concat tampoco es una solución milagrosa única para todos, por lo que hay muchos sitios para los que la carga en paralelo seguirá siendo el enfoque preferido y el mejor.

El hecho de que algunos sitios se ocupen de los matices / complejidades de decidir entre carga en paralelo frente a script-concat no significa que la discusión mayor (más impactante) de carga en paralelo frente a etiquetas de script deba perderse en la mezcla. Lo primero es difícil de probar, pero lo segundo es casi un hecho en este momento.


Todo esto es para decir que, considerando todo, en mi humilde opinión, un modelo estándar debería alentar un patrón que tenga el mayor impacto en una dirección positiva. Si el 80% de los sitios en Internet hoy en día utilizan etiquetas de secuencia de comandos, la mayoría de las cuales se beneficiarían de pasar de las etiquetas de secuencia de comandos a la carga en paralelo, entonces la carga en paralelo es algo muy saludable para sugerir como punto de partida para el modelo estándar.

Es una subsección mucho más pequeña (pero importante) de esos sitios que potencialmente pueden obtener aún más beneficios al explorar script-concat versus carga paralela. Pero un caso de uso minoritario no es para lo que debería optimizarse en un modelo estándar.

Solo mis pocos centavos.

@paulirish @slexaxton -

En cuanto a las necesidades de ancho de banda, calculé que para que 10,000 personas (lo que sentí que era necesario ser un muestreo preciso) ejecutaran la prueba una vez (y muchas personas la ejecutarían varias veces, estoy seguro), sería aproximadamente 200 GB de ancho de banda gastados. Para algunas personas, eso es una gota en el mar. Para mí, 200 GB de ancho de banda en unos pocos días serían abrumadores para los costos de alojamiento de mi servidor. Entonces, no he seguido escalando las pruebas solo por esa razón.

Además, tengo más de una docena de variaciones de esta prueba que creo que debemos explorar. Entonces, docenas de veces usando 100-200GB de ancho de banda cada una sería un costo prohibitivo para mí. No quería comenzar por ese camino a menos que estuviera seguro de que tenía suficiente ancho de banda para terminar la tarea.

Son solo archivos estáticos y las pruebas no requieren muchos usuarios simultáneos, por lo que no hay preocupaciones reales sobre problemas de escalado tradicionales como CPU, etc. Solo ancho de banda, eso es todo.

Podemos tomar el resto de la discusión de las pruebas fuera de línea y continuar por correo electrónico o mensajería instantánea. Me gustaría mucho escalar finalmente las pruebas y "resolver" este problema. Ha estado rondando la parte posterior de mi cerebro durante la mayor parte de un año.

Puedo hacer TB ilimitado en mi VPS dreamhost, por lo que esto no será un problema. ahora mismo estoy haciendo 72 gb / día y puedo manejar mucho más. :)

Estoy de acuerdo con Paul, y creo que hay bastante información errónea sobre cómo y cuándo los cargadores de scripts serán de algún beneficio para cualquiera.

Su primer párrafo dice que es "fácil", "demostrable" y "sin lugar a dudas" que los cargadores de scripts mejoran el rendimiento.

Hice una postulación similar a @jashkenas hace un tiempo, y él y yo reunimos algunas páginas idénticas lo mejor que pudimos para intentar medir el rendimiento de nuestras _mejores_ técnicas. Es un fanático del 100% concat, y probé 2 técnicas diferentes de carga de scripts.

https://github.com/SlexAxton/AssetRace

El código está todo ahí. Obviamente, no hubo una gran audiencia de prueba, pero los resultados en el mejor de los casos mostraron que este cargador de scripts tenía aproximadamente la misma velocidad que el método concat (con las pautas de carga paralela de 3 archivos de tamaño similar seguidas), y en el peor de los casos mostró que el script- Los cargadores variaron mucho más y, en general, fueron más lentos dentro de un margen de error. Siéntase libre de bifurcar y encontrar una solución que supere a los nuestros oa ambos, incluso si solo está en su máquina en un navegador.

En cuanto a la "premisa falsa" porque h5bp asume que la gente concatena sus js. Este argumento es completamente inválido porque h5bp ofrece una herramienta de creación de scripts, completa con concat y minificación. Entonces, el argumento de que la carga en paralelo es casi siempre una ventaja sobre múltiples etiquetas de script puede ser cierto, pero no es mejor que lo que ofrece h5bp actualmente. Ese es el contexto de esta discusión.

Creo que el peor de los casos es que las personas tomen algo como yepnope o lab.js y lo usen como una etiqueta de script polyfill. Eso resultará absolutamente en una carga más lenta (de sus 19 archivos JS y 34 archivos CSS), además de introducir una gran cantidad de problemas de compatibilidad hacia atrás y hacia adelante de los que no se darán cuenta por completo.

Creo que con el espíritu de brindar a las personas el valor predeterminado más sensato, eficiente y compatible para un _boilerplate_, una herramienta de compilación va mucho más allá para garantizar los tres.

@slexaxton

... los resultados en el mejor de los casos mostraron que este cargador de scripts tenía aproximadamente la misma velocidad que el método concat (con sus pautas de carga paralela de 3 archivos de tamaño similar seguidas) ...

Con mucho gusto encontraré algo de tiempo para echar un vistazo a las pruebas que preparaste. Estoy seguro de que saben lo que están haciendo, así que estoy seguro de que sus pruebas son válidas y correctas.

OTOH, tengo muchas pruebas contradictorias. Si alguna vez hubiera visto algo convincente que sugiriera que la carga de scripts en paralelo fue un desperdicio o inútil para la mayoría de los sitios, hace mucho que habría abandonado el loco sumidero de tiempo que es LABjs.

Puedo decir con 100% de certeza que nunca, en 2 años de ayudar a poner LABjs a disposición de las personas, nunca encontré una situación en la que LABjs fuera más lento que la alternativa de etiqueta de script. Cero veces me ha ocurrido eso a mí. Ha habido algunas ocasiones en las que la gente dijo que no veía mucho beneficio. Ha habido algunas ocasiones en las que las personas estaban cargando más de 100 archivos y, por lo tanto, la sobrecarga loca de tantas conexiones eliminó cualquier beneficio que de otro modo hubieran visto. Pero nunca alguien me ha dicho que LABjs hizo que su sitio fuera más lento.

Literalmente, yo mismo he ayudado a más de 50 sitios diferentes a pasar de etiquetas de script a LABjs, y sin falta, los sitios vieron mejoras de rendimiento desde el principio. Al principio de los esfuerzos, tomé una muestra de quizás 7 u 8 sitios en los que había ayudado, y en conjunto habían visto una mejora promedio de alrededor del 15% en la velocidad de carga. Para los 4 o 5 sitios que administro, por supuesto implementé LABjs e inmediatamente vi hasta 3 veces la velocidad de carga.

Por supuesto, cuando se lanzó LABjs por primera vez, los navegadores tenían la tecnología más avanzada para cargar scripts en paralelo (solo unos pocos lo estaban haciendo). Entonces, las ganancias fueron enormes y visibles. Ahora, casi todos los navegadores realizan cargas en paralelo, por lo que las ganancias ya no son tan drásticas.

Pero lo único que es innegable es que todos los navegadores bloquean el evento DOM-ready para la carga de etiquetas de script. _Tienen que_ debido a la posibilidad de encontrar document.write() . La carga de secuencias de comandos en paralelo consiste básicamente en decir "navegador, te prometo que no tendrás que lidiar con document.write, así que sigue adelante y sigue adelante con la página".

Eche un vistazo a los dos diagramas de la diapositiva 10 de esta presentación:

http://www.slideshare.net/shadedecho/the-once-and-future-script-loader-v2

Compare la ubicación de la línea azul (listo para DOM). Esa es una mejora drástica en el rendimiento percibido (UX), incluso si el tiempo total de carga de la página (o el tiempo para finalizar la carga de todos los activos) no es mejor.

... h5bp ofrece una herramienta de creación de scripts ...

La suposición errónea aquí es que solo porque h5bp ofrece esta herramienta, todos (o incluso la mayoría) de los usuarios de h5bp pueden usarla. Incluso si el 100% de los usuarios de h5bp _do_ lo usa, eso no significa que si h5bp se implementara en la cola larga de Internet, todos ellos usarían esa herramienta concat. Hay muchos otros factores que pueden evitar fácilmente que alguien lo use. Hay _muy pocas_ razones por las que alguien no puede pasar de usar etiquetas de secuencia de comandos a usar un cargador de secuencias de comandos paralelo.

Como tal, la carga de scripts en paralelo todavía ofrece un atractivo más amplio para la cola larga de Internet. Todavía es más fácil para la mayoría de los sitios que no utilizan optimizaciones de carga de scripts, pasar de la nada a algo, y que algo les ofrezca ganancias de rendimiento. Pocos de esos sitios de cola larga alguna vez gastarán el esfuerzo (o tendrán la habilidad para experimentar con) herramientas automatizadas de creación de scripts en sus entornos de alojamiento web sin CDN, alojamiento compartido masivo y barato de $ 6 / mes.

Creo que el peor de los casos es que las personas tomen algo como yepnope o lab.js y lo usen como una etiqueta de script polyfill. Eso resultará absolutamente en una carga más lenta ...

No podría estar más en desacuerdo con esta afirmación. LABjs está diseñado específicamente como un polyfill de etiquetas de script. Y las mejoras de LABjs sobre las etiquetas de script regulares (ignore el script concat por el momento) están bien establecidas y nunca han sido refutadas seriamente. Si tiene pruebas de que la mayoría (o incluso muchos) de los sitios que usan LABjs estarían mejor si volviera a las etiquetas de script, por favor comparta.

No hay absolutamente ninguna razón por la que la carga de secuencias de comandos en paralelo resulte en una carga más lenta de lo que el navegador podría lograr con las etiquetas de secuencias de comandos. Eso no tiene sentido. Y como establecí anteriormente, las etiquetas de secuencia de comandos siempre bloquearán las listas para DOM, mientras que la carga de secuencias de comandos en paralelo no lo hará.

introducir una gran cantidad de problemas de compatibilidad hacia atrás y hacia adelante que no conocerán por completo.

¿De qué problemas de compatibilidad estás hablando? La matriz de soporte de navegadores de LABjs cubre absolutamente la gran mayoría de todos los navegadores web del planeta. La pequeña y loca franja de navegadores en la que interviene se ve superada por la gran cantidad de navegadores en los que tiene claras ventajas.

LABjs 1.x tenía un montón de trucos locos, como la precarga de caché, que de hecho eran preocupaciones importantes por la rotura de los navegadores. LABjs 2.x lo ha invertido completamente y ahora usa enfoques confiables y estandarizados para la carga paralela en todos los casos, solo recurriendo al truco del navegador webkit anterior. Además, LABjs 2.x ya tiene comprobaciones para las pruebas de funciones de las próximas técnicas de carga de scripts (con suerte, que pronto se estandarizarán) como la "precarga real".

No puedo hablar definitivamente por ningún otro cargador de scripts, sé que muchos todavía usan hacks, pero en cuanto a los LABj, estoy desconcertado por la afirmación de que presenta problemas de compatibilidad hacia adelante o hacia atrás, ya que creo que esto es claramente engañoso. afirmar.

para explicar un poco por qué tengo la intención de que LABjs sea de hecho un polyfill de etiqueta de script ...

  1. Los navegadores más antiguos claramente son MUCHO inferiores en el manejo de la carga de etiquetas de script que la carga paralela puede manejar. Fue en esos "navegadores más antiguos" (que eran los más recientes / mejores cuando se lanzó LABjs hace 2 años) donde vimos las mejoras en el tiempo de carga de la página ~ 3x. casi por definición, eso hace que LABjs sea un mejor polyfill de etiquetas de script, ya que brinda una característica (es decir, el rendimiento de la carga paralela) a los navegadores que no lo admiten por sí mismos.
  2. obviamente, los navegadores más nuevos son mucho mejores. pero no han obviado por completo los beneficios de los cargadores de scripts. Chrome tan recientemente como v12 (supongo que finalmente se arreglaron en v13, parece) seguía bloqueando la carga de imágenes mientras las etiquetas de script terminaban de cargarse. Incluso con lo último de IE, Firefox y Chrome, todos siguen bloqueando los dominios preparados mientras los scripts se cargan dinámicamente, porque todavía tienen que asumir de manera pesimista que document.write() puede estar al acecho.

Entonces, para los navegadores más nuevos, LABjs es un "polyfill" en el sentido de que está trayendo "carga de scripts de bloqueo no preparados para DOM" al navegador de una manera que las etiquetas de scripts no pueden hacer. La única forma posible de hacerlo en los navegadores modernos sin un cargador de secuencias de comandos paralelo sería usar etiquetas de secuencia de comandos con defer ( async obviamente no funcionará ya que no conserva el orden) . Sin embargo, defer tiene una serie de peculiaridades y su soporte no está lo suficientemente extendido como para ser una solución viable (la alternativa para no aplazar es un mal rendimiento). Entonces, podría decir que, en el caso más básico, LABjs es un polyfill para las características de rendimiento de la etiqueta de script defer (aunque no exactamente).

Honestamente, sigo pensando que deberíamos solicitar estándares para un objeto de carga de script. Tener que crear una etiqueta de script de un tipo diferente a texto / javascript para activar la caché (o peor, usar una etiqueta de objeto o un objeto de imagen o lo que sea que requiera una nueva versión de un navegador popular) es saltar muchos obstáculos por nada. y el rendimiento variará dependiendo de demasiadas variables. Puedo entender que todavía cargamos hojas de estilo usando la inserción del nodo dom (pero eso es solo por orden) pero cuando se trata de un script, creo que ya no tiene ningún sentido (desearía que Google dejara de usar document.write en la mayor parte de sus guiones, pero esa es otra historia completamente).

Además, creo que nos estamos perdiendo el punto más importante con respecto a los cargadores de scripts aquí: poder cargar código js a pedido en lugar de cargar todo por adelantado (incluso con todo en caché, analizar e inicializar lleva tiempo y puede ser bastante feo con una cantidad no trivial de scripts concatenados). Tener algo de tiempo de espera después de una interacción de la interfaz de usuario es un problema mucho menor que tener el navegador "colgado", aunque sea un poco al inicio (DOM puede estar listo, pero de qué sirve si el código para mejorar la página y agregar iteración aún no se ha ejecutado: ¿alguna vez notó cómo algunos sitios se cargan inmediatamente y luego ocurre algo torpe?).

Así que la medición estricta del rendimiento está bien y es excelente, pero sigo pensando que el rendimiento percibido es el objetivo final ... y, lamentablemente, es mucho menos fácil de estimar / optimizar / calcular.

Esto es intenso.

@ jaubourg--

Honestamente, sigo pensando que deberíamos solicitar estándares para un objeto de carga de script.

Hay muchas peticiones sobre cómo los estándares / especificaciones y los navegadores pueden brindarnos una mejor tecnología de carga de scripts. La primera gran victoria en esta categoría en años fue la "asincrónica ordenada" ( async=false ) que se adoptó en febrero y ahora está en todos los principales navegadores de versiones actuales (excepción: Opera muy pronto e IE10p2 lo tiene ).

El próximo debate, sobre el que estoy actualmente en conversaciones con Ian Hickson, es lo que yo llamo "precarga real". En mi opinión, la "precarga real" (que IE ya admite desde la versión 4, por cierto) sería lo más parecido a una "bala de plata" que resolvería casi todos los escenarios de carga de scripts de manera bastante trivial. Todavía soy bastante optimista de que veremos algo como esto estandarizado.

Consulte este wiki para obtener más información: http://wiki.whatwg.org/wiki/Script_Execution_Control

Tener que crear una etiqueta de secuencia de comandos de un tipo diferente a texto / javascript para activar la caché (o peor aún, usar una etiqueta de objeto o un objeto de imagen o lo que sea que requiera una nueva versión de un navegador popular)

Esto se llama "precarga de caché", y es un truco feo y horrible admitido. La forma de LABj quita énfasis a esto ahora a partir de v2 (solo lo usa como respaldo para webkit más antiguo). Desafortunadamente, otros cargadores de scripts todavía lo usan como su mecanismo de carga principal. Pero el 90% de la necesidad de "precarga de caché" se puede resolver con "async ordenado", que está estandarizado y no es un truco, por lo que los cargadores de scripts con buen comportamiento deberían preferir eso a la "precarga de caché" ahora.

Entonces, estoy de acuerdo en que la "precarga de caché" apesta, pero hay formas mucho mejores de usar document.createElement("script") que no involucran tales hacks, por lo que no estoy de acuerdo en que este sea un argumento en contra de continuar confiando en el elemento Script del navegador para carga de la secuencia de comandos. Si podemos obtener una "precarga real", el elemento Script será todo lo que necesitamos que sea. Sinceramente lo creo.

Creo que nos estamos perdiendo el punto más importante con respecto a los cargadores de scripts aquí: poder cargar código js bajo demanda

Estoy muy de acuerdo en que es un beneficio importante que aportan los cargadores de scripts. Pero es una especie de argumento discutible en _este_ hilo, porque la gente del "script concat" simplemente no puede, sin cargar el script, resolver el caso de uso, por lo que no tiene sentido "comparar" los dos. Puede decir como proponente de "script concat" "bien, no nos importa ese caso de uso", pero no puede decir "podemos servir mejor ese caso de uso usando XYZ".

El rendimiento percibido es enorme e importante, estoy de acuerdo. La carga bajo demanda es una gran parte para que eso suceda. La carga bajo demanda también mejorará el rendimiento real real (no solo la percepción) porque tiende a llevar a que se descargue menos si solo descarga lo que se necesita (pocas visitas a la página requieren el 100% del código que ha escrito).

El rendimiento percibido también es la razón por la que abogo por el argumento listo para DOM anterior. Porque la rapidez con que un usuario "siente" que puede interactuar con una página es _muy_ importante para lo rápido que creen que es la página (independientemente de lo rápido que se cargue realmente). Ese es un hecho establecido por muchas investigaciones de usuarios.

Me encantan los largos y apasionados comentarios de @getify
Kyle ...

Si puedo contribuir de alguna manera a la investigación, me encantaría.
El ancho de banda (costos) no parece ser el problema, así que @getify , ¿qué propones para seguir adelante?
No dude en ponerse en contacto conmigo por correo electrónico (aaron [at] aaronpeters [dot] o twitter (@aaronpeters)

@kyle

Sí, seguí la discusión de "mejoras" de la etiqueta de secuencia de comandos con respecto a la precarga y simplemente no compro el enfoque de "agregar otro atributo en la etiqueta de secuencia de comandos" como un enfoque viable. He visto lo que le hizo a la especificación xhr: mucha complejidad con respecto al pequeño beneficio que obtenemos al final.

Lo que está claro es que prácticamente solo necesitamos el comportamiento de precarga cuando hacemos una inserción dinámica (es decir, ya lo hacemos en javascript), entonces, ¿por qué demonios deberíamos usar la inyección de etiquetas de script? No es que mantengamos la etiqueta allí o la usemos como un nodo DOM: es solo un medio para un fin que no tiene nada que ver con la estructura del documento.

Me sentiría mucho más cómodo con algo así:

window.loadScript( url, function( scriptObject ) {
    if ( !scriptObject.error ) {
        scriptObject.run();
    }
});

Esto haría maravillas. Es bastante fácil "unirse" a varios eventos de carga de secuencias de comandos y luego ejecutar esas secuencias de comandos en el orden que sea necesario. Tampoco implica la presencia de un DOM, lo que lo hace aún más genérico. Ojalá nos alejáramos de la inyección de etiquetas de script lo antes posible. Además, es bastante fácil rellenar esto usando los trucos que todos conocemos. También es una carga mucho menor que un sistema de requisitos completo (pero puede ser un componente básico para un sistema de requisitos que no se limita a los navegadores).

Dicho esto, estoy 100% de acuerdo contigo en cuanto al rendimiento percibido, solo quería señalarlo porque el mantra de "compactemos todo junto" se está convirtiendo rápidamente en una especie de creencia que difumina demasiado las cosas para mi gusto;)

fwiw, defer es compatible con IE4 +, Chrome, Safari y FF 3.5+. No es compatible con Opera.

Eso significa que ... el 98,5% de los usuarios ya tienen soporte script@defer .

@getify

Sin embargo, defer tiene una serie de peculiaridades,

detalles por favor? no he visto nada sobre esto

¿Se ejecutan los scripts con aplazamiento antes o después de que se active el evento DOM Ready?

¿Se conserva el orden de ejecución en todos los navegadores?

¿Qué tal el orden ejecutivo y el acoplamiento externo con scripts en línea?

@ paulirish--

... El 98,5% de los usuarios ya tienen soporte para script @ defer .

El soporte puede estar ahí en tantos navegadores, pero eso no significa que sea confiable en tantos navegadores. a eso me refería. (vea abajo)

Sin embargo, diferir tiene una serie de peculiaridades,

detalles por favor? no he visto nada sobre esto

Déjame ver ... IIRC:

  1. el soporte de aplazamiento en elementos de secuencia de comandos dinámicos no está definido ni es compatible en ningún navegador ... solo funciona para etiquetas de secuencia de comandos en el marcado. esto significa que es completamente inútil para las técnicas y casos de uso "bajo demanda" o "carga diferida".
  2. Creo que hubo un caso en el que, en algunos navegadores, los scripts diferidos comenzarían a ejecutarse inmediatamente antes de que se disparara DOM-ready, y en otros, sucedió inmediatamente después de que se disparara DOM-ready. Tendré que investigar más para obtener más detalles al respecto.
  3. defer usado en una etiqueta de secuencia de comandos que hace referencia a un recurso externo se comportó de manera diferente a defer especificado en una etiqueta de secuencia de comandos con código en línea. Es decir, no se puede garantizar que funcione para diferir ambos tipos de scripts y que aún se ejecuten en el orden correcto.
  4. defer en una etiqueta de secuencia de comandos escrita por una instrucción document.write() difería de una etiqueta de secuencia de comandos en el marcado con defer .

No tengo un montón de detalles listos a mi alcance sobre estos temas. Recuerdo que hace unos 2 años (antes de LABjs) intenté usar defer y encontré suficientes de ellos en las pruebas entre navegadores que básicamente lo dejé a un lado y no lo he vuelto a visitar mucho desde entonces.


También debo señalar que defer no es realmente lo mismo que lo que ofrecen los LABjs (y otros cargadores paralelos). Dije eso arriba con la advertencia de que es algo así. De hecho, lo que proporciona la carga de scripts en paralelo (al menos, para la parte de LABjs), es "asincrónico ordenado", que no tiene absolutamente ninguna forma de lograrse solo a través del marcado.

La diferencia entre "ordenado asíncrono" y "aplazar" es que "ordenado asíncrono" comenzará a ejecutarse tan pronto como termine de cargarse el primer script solicitado, mientras que "aplazar" esperará hasta que `DOM esté listo antes de comenzar las ejecuciones. Para una página simple con poco marcado y sin otras llamadas de marcado de bloqueo (como otras etiquetas de script), esta diferencia es pequeña. Pero para una página con muchos recursos, cuando se permite que los scripts comiencen a ejecutarse, puede ser drásticamente diferente.

Entonces, honestamente, me gustaría no desviarme demasiado de la tangente de defer , porque en realidad no es una gran comparación con lo que proporciona la carga de scripts en paralelo. Fue solo el ejemplo más cercano en el marcado que pude usar para describir el comportamiento ordenado de ejecución al que estaba llegando. Probablemente ni siquiera debería haber traído defer , solo enturbia la discusión.

Permítanme reformular lo anterior: "Para los navegadores modernos, LABjs es una especie de 'polyfill' para el comportamiento de 'asincrónico ordenado', que no es posible optar por el marcado solo en ningún navegador".

Me gusta "asincrónico ordenado", es una buena frase.

Kyle> afaik, los scripts con aplazamiento se ejecutarán _antes_ de la carga, incluso antes de domready.
Los scripts con el atributo async se ejecutarán lo antes posible y _siempre_ _antes_ de la carga, pero no necesariamente antes de domready

@ aaronpeters--
Creo que puede estar un poco desviado. Así es como lo entiendo:

async scripts async deben esperar nada (excepto la disponibilidad del motor JS en sí). Sin embargo, si se solicitan antes de window.onload , entonces en casi todos los navegadores "retendrán" el evento window.onload hasta que se carguen y ejecuten. Creo que hubo un caso documentado en el que los scripts async no aguantaron window.onload , simplemente no recordaban los detalles exactos.

defer por otro lado significa específicamente: esperar hasta que esté listo para DOM. Además, hay una "cola" de todos los scripts con defer establecido en ellos, de modo que la cola no se procesa hasta después de que esté listo para DOM. Esto significa que todos deben ejecutarse estrictamente después de que esté listo para DOM (o, más bien, después de el DOM está listo y terminado de analizar, para ser exactos). Pero pueden retrasarse aún más (si la carga es lenta). Sin embargo, deberían aguantar window.onload . Solo recuerdo de vaga memoria pasada que en algunas versiones de IE la práctica real de esta teoría era un poco confusa.

@getify

No quería descarrilar este hilo aún más, así que publiqué mi pensamiento sobre la precarga del script y su propuesta en la página WHATWG aquí: http://jaubourg.net/driving-a-nail-with-a-screwdriver-the-way -web

async scripts async deben esperar nada (excepto la disponibilidad del motor JS en sí). Sin embargo, si se solicitan antes de window.onload , entonces en casi todos los navegadores "retendrán" el evento window.onload hasta que se carguen y ejecuten.

Esto probablemente sea más fácil de entender una vez que se dé cuenta de que JavaScript es de un solo hilo. (Sé que me tomó un tiempo ...)

De manera similar, si usa setTimeout(fn, 0) para descargar recursos, y ellos ingresan a la cola de descarga antes de que se active onload , la carga de estos recursos (aún) retrasará onload .

Creo que hubo un caso documentado en el que los scripts async no aguantaron window.onload , simplemente no recordaban los detalles exactos.

Me encantaría obtener más información sobre esto. ¡Atención - Recuerde! :)

¡Yay cargadores de scripts!

Un problema que he tenido al implementarlos en la red de sitios de AOL es lidiar con las condiciones de carrera. Por ejemplo, cargar jQuery de forma asincrónica en el encabezado, luego decir un complemento de jQuery a mitad de camino en el documento entregado de forma asincrónica dentro de una publicación de blog.

Por lo tanto, comencé mi propio proyecto de ciencia del cargador de scripts (Boot.getJS) para lidiar con esto. La idea es descargar todos los scripts en paralelo y ejecutarlos en orden, pase lo que pase, lo antes posible. También admite el aplazamiento a listo o cargado y el almacenamiento en caché de scripts. La mayoría de las ideas son tomadas (robadas) por personas en este hilo, así que gracias chicos. :)

Como estaba discutiendo los puntos de referencia, pensé que compartiría una página de prueba que creé para comprender las diferencias en el rendimiento, la sintaxis y el comportamiento de los diversos cargadores de scripts, compruébelo aquí:

http://artzstudio.com/files/Boot/test/benchmarks/script.html

Para ver cómo se comportan varios cargadores, borre el caché y observe las solicitudes de red y la hora final, así como el orden en que se ejecutan los scripts.

Dave (@artzstudio), txs por compartir sus pensamientos y el enlace a su página de prueba.

Pregunta: ¿por qué carga LABjs en la página '<script> tag in head'? Eso parece mal.

@artzstudio también, estás usando una versión antigua de LABjs. ¿Es eso intencional? Si es así, ¿por qué?

@aaronpeters En AOL tenemos scripts como Omniture y un código de anuncios (y más) que deben ir en la cabeza, de modo que ahí es donde va la biblioteca del cargador en nuestro caso de uso. Además, cuando los scripts están en la parte inferior, hay un problema de FOUC en algunos de nuestros widgets, por lo que cuanto antes se carguen las dependencias (como jQuery), mejor.

No fue intencional, esta prueba tiene un par de meses. Actualizaré las bibliotecas cuando tenga la oportunidad.

Para su información (espero que esto sea algo interesante / relevante), realicé algunas pruebas en Webpagetest.org para ver qué sucede en IE8 al cargar algunas de las páginas de prueba de @artzstudio .
Etiquetas de secuencia de comandos: http://www.webpagetest.org/result/110810_C7_752b756180e132f50a3ef065e9e059ca/
Yepnope: http://www.webpagetest.org/result/110810_8S_a53f4ed2e16179c328fc57c572e71076/
LABjs: http://www.webpagetest.org/result/110810_ZV_1ece92044799e52ed5199aed6b407133/
RequireJS: http://www.webpagetest.org/result/110810_Z3_a1537e41a0b0570286151859973d0cfa/

Video que compara Yepnope y LABjs: http://www.webpagetest.org/video/view.php?id=110810_074cb94c1b04a7ac9bd6538ec3fdd8d3c07f842d

Algunas notas:

  • Gzip está desactivado en el servidor, por lo que el tamaño de archivo más grande de RequireJS tiene un impacto
  • Como se mencionó anteriormente, la página de etiquetas de script carga LABjs en HEAD (no tiene sentido) y eso, por supuesto, tiene un impacto

Por estas dos razones, creé un video que solo mostraba Yepnope y LABjs.

Lo que encuentro interesante es que el tiempo de Start Render es mucho mejor para LABjs. ¿Porqué es eso? Me encantaría entender mejor.

Comentario de cierre: No estoy publicando esto con el objetivo de favorecer a los LABj sobre Yepnope ni nada por el estilo. Solo compartiendo datos ...

Oh, lo siento, veo lo que quisiste decir con los LABjs en la prueba <script>. Arreglado ahora, junto con una actualización a LABjs.

@ artzstudio--

Por lo tanto, comencé mi propio proyecto de ciencia del cargador de scripts (Boot.getJS) para lidiar con esto. La idea es descargar todos los scripts en paralelo y ejecutarlos en orden pase lo que pase, lo antes posible

Entonces, ¿sabías que esto es _exactamente_ para lo que está diseñado LABjs y lo hace muy bien (si lo digo yo mismo)? Lo que quiero decir es, ¿solo quería una API diferente o qué pasa con la funcionalidad de carga de scripts en paralelo no era suficiente?


En cualquier caso, por mucho que me encanta presumir de LABjs, no creo que sea efectivo empantanar este hilo con discusiones del tipo "mira, mi cargador de scripts es mejor en X". Esas discusiones son útiles, pero en otros lugares.

Al final, toda la tecnología del cargador de scripts se reduce a unas pocas ideas simples. No importa qué tipo de API elegante coloque encima, o qué casos de uso atienda, la tecnología es la misma. Debe haber 50 cargadores de scripts diferentes en estos días y, en realidad, ninguno de ellos proporciona nada diferente en términos de tecnología, solo API diferentes. Por lo tanto, comparar API es realmente una discusión bastante irrelevante.

En lo que deberíamos centrarnos es en si la tecnología de carga de scripts base que tenemos actualmente disponible en los navegadores se puede utilizar para mejorar el rendimiento de las cargas de página en comparación con el uso de etiquetas de script en el marcado. Esta es una premisa mía desde hace mucho tiempo que es absolutamente cierto, pero esa premisa ha sido cuestionada en este hilo. Entonces, la tarea n. ° 1 es responder a esa pregunta.

Si descubrimos que las etiquetas de secuencia de comandos son simplemente mejores que la carga de secuencias de comandos, entonces podemos detener toda esta locura y cerrar todos nuestros proyectos. Sin embargo, sospecho que ese no será el caso. ;-)

La tarea n. ° 2 es averiguar de una vez por todas si script-concat es siempre mejor que la carga en paralelo. Nuevamente, mi premisa (y mis pruebas) muestran que la concatenación de todos los archivos en uno es bueno, pero luego debe dividir ese archivo grande en 2-3 piezas aproximadamente iguales y cargar esas partes en paralelo. Entonces, realmente necesitamos probar esa teoría también.

Si descubrimos que script-concat siempre es mejor, nuevamente, los cargadores de scripts siguen siendo útiles si se considera que la mayoría de los sitios cargan scripts desde más de una ubicación (jquery de Google CDN, google analytics de google, facebook / twitter / g + botones , etc.). Entonces necesitaríamos, como tarea n. ° 3, determinar si concat es mucho mejor que debería alojar sus propias copias de todos esos archivos, combinándolos con su propio código.

Kyle, ¿puede ver la fuente de mi ejemplo y hacerme saber cómo instrumentaría LabJS para ejecutar todos los scripts en la página en orden (incluso fuera de la cadena)? Bien podría haber leído mal la API (como dijo Paul, los cargadores de scripts son difíciles,% -).

El 10 de agosto de 2011, a las 9:09 a. M. ,

@ artzstudio--

Por lo tanto, comencé mi propio proyecto de ciencia del cargador de scripts (Boot.getJS) para lidiar con esto. La idea es descargar todos los scripts en paralelo y ejecutarlos en orden pase lo que pase, lo antes posible

Entonces, ¿sabías que esto es _exactamente_ para lo que está diseñado LABjs y lo hace muy bien (si lo digo yo mismo)? Lo que quiero decir es, ¿solo quería una API diferente o qué pasa con la funcionalidad de carga de scripts en paralelo no era suficiente?


En cualquier caso, por mucho que me encanta presumir de LABjs, no creo que sea efectivo empantanar este hilo con discusiones del tipo "mira, mi cargador de scripts es mejor en X". Esas discusiones son útiles, pero en otros lugares.

Al final, toda la tecnología del cargador de scripts se reduce a unas pocas ideas simples. No importa qué tipo de API elegante coloque encima, o qué casos de uso atienda, la tecnología es la misma. Debe haber 50 cargadores de scripts diferentes en estos días y, en realidad, ninguno de ellos proporciona nada diferente en términos de tecnología, solo API diferentes. Por lo tanto, comparar API es realmente una discusión bastante irrelevante.

En lo que deberíamos centrarnos es en si la tecnología de carga de scripts base que tenemos actualmente disponible en los navegadores se puede utilizar para mejorar el rendimiento de las cargas de página en comparación con el uso de etiquetas de script en el marcado. Esta es una premisa mía desde hace mucho tiempo que es absolutamente cierto, pero esa premisa ha sido cuestionada en este hilo. Entonces, la tarea n. ° 1 es responder a esa pregunta.

Si descubrimos que las etiquetas de secuencia de comandos son simplemente mejores que la carga de secuencias de comandos, entonces podemos detener toda esta locura y cerrar todos nuestros proyectos. Sin embargo, sospecho que ese no será el caso. ;-)

La tarea n. ° 2 es averiguar de una vez por todas si script-concat es siempre mejor que la carga en paralelo. Nuevamente, mi premisa (y mis pruebas) muestran que la concatenación de todos los archivos en uno es bueno, pero luego debe dividir ese archivo grande en 2-3 piezas aproximadamente iguales y cargar esas partes en paralelo. Entonces, realmente necesitamos probar esa teoría también.

Si descubrimos que script-concat siempre es mejor, nuevamente, los cargadores de scripts siguen siendo útiles si se considera que la mayoría de los sitios cargan scripts desde más de una ubicación (jquery de Google CDN, google analytics de google, facebook / twitter / g + botones , etc.). Entonces necesitaríamos, como tarea n. ° 3, determinar si concat es mucho mejor que debería alojar sus propias copias de todos esos archivos, combinándolos con su propio código.

Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/paulirish/html5-boilerplate/issues/28#issuecomment -1772315

Uno pensaría que la física dice que el concat es el mejor. Cada nueva conexión HTTP es otro inicio lento + un impuesto de 100 ms en el peor de los casos de la CDN.

Sin embargo, la verdad sobre los documentos es que pueden ser muy largos. Por lo tanto, cargar un archivo BFJS en el encabezado puede ralentizar innecesariamente la inicialización de los módulos. Cargarlo al final puede causar un molesto FOUC. Puede haber implicaciones móviles para archivos grandes: http://www.yuiblog.com/blog/2010/06/28/mobile-browser-cache-limits/

Creo que este es el motivo detrás de la regla de "dividir la carga útil" de Souders (http://oreilly.com/server-administration/excerpts/9780596522315/splitting-the-initial-payload.html). También tenemos que hacer lo que es perceptiblemente más rápido.

Y, desafortunadamente, esto se reduce a una especie de respuesta de "depende", lo que hace que este problema sea lo suficientemente interesante como para entretenernos a todos.

Estoy jugando con un enfoque híbrido en el que las llamadas getJS se ponen en cola y se concatenan periódicamente en un intervalo de tiempo establecido, así como también se concaten en un nivel de dependencia del módulo (por ejemplo, se concaten las dependencias de RequireJS en lugar de cargar una a la vez), todo sobre la marcha en el front-end.

Es un experimento científico que, como usted señala, con suerte pronto será inútil, pero de todos modos es interesante.

@getify : Sé que esto es simplemente mear en el desfile en este momento, pero aún así.

Si descubrimos que las etiquetas de secuencia de comandos son simplemente mejores que la carga de secuencias de comandos,
entonces podemos detener toda esta locura y cerrar todos nuestros proyectos.
Sin embargo, sospecho que ese no será el caso. ;-)

Podría decir muchas cosas sobre el aceite de serpiente, pero una demostración funcionará igual de bien:

http://jashkenas.s3.amazonaws.com/misc/snake-oil/labjs.html

http://jashkenas.s3.amazonaws.com/misc/snake-oil/vanilla.html

Esa es una página con 100k de texto, 10 imágenes y 171k de JavaScript. La versión básica utiliza un único archivo minificado que incluye jQuery, jQuery-UI, Underscore y Backbone, así como el archivo timer.js que escribe los resultados del tiempo de carga. La versión de LABjs carga cada uno de los 5 archivos JavaScript (minificados por separado) utilizando LABjs.

Descubrirá que no solo no hay ningún beneficio para la versión LAB, sino que las solicitudes HTTP adicionales solo perjudican el rendimiento de la carga y tienen que competir con otros activos en la página, como las imágenes. Pero todo esto se ha dicho muchas veces antes ...

LABjs

Vanilla

Puedo anticipar un contraargumento sobre la carga de sus scripts en partes ... pero eso es completamente ortogonal a la técnica de carga de scripts, así que, por favor, déjelo fuera de la discusión.

Por supuesto, detén la locura.

@jashkenas Full, 100% ack. Los cargadores de scripts solo agregan gastos generales, complicaciones y puntos de falla. Un solo archivo concatenado en el servidor se carga más rápido (est), tanto en términos de tiempo de transferencia puro como en términos de eficiencia de los intérpretes de JavaScript, y como beneficio adicional, gzipping funciona mejor si solo tiene un solo archivo.

Tengo que decir que la versión de LABjs _a veces_ se carga más rápido en mi navegador (en comparación con la página básica), pero no de manera consistente. Además, onload no siempre se activa, lo que parece ... extraño.

Sí, gzipping le brinda una ganancia general aún mayor con menos solicitudes HTTP.

Y esto no se trata de dogma, no tiene que ser un archivo _solo_ JS para toda la aplicación; dos o tres con defer están bien para un almacenamiento en caché más fino, ya que se cargarán más más adelante.

Algunas investigaciones del equipo de Page Speed ​​de Google:

http://pagespeed-velocity2011.appspot.com/#8 Consulte las diapositivas 8 a 14, lo que aporta más inconclusión a la discusión


Todavía estoy interesado en el atributo @defer del script y creo que es un valor predeterminado básico sabio, a menos que planee dedicar muchas horas / días a la prueba de rendimiento de sus propias variaciones.

@miketaylr : Sí, actualice cada página varias veces para tener una idea general. Las latencias de S3 y las cargas de imágenes harán que las cosas sean un poco impredecibles, comportándose más como una aplicación real.

Bueno, labjs _siempre_ se carga más rápido en mi navegador (Safari 5.1) incluso con shift-refresh o cuando los elementos están almacenados en caché.

Por supuesto, usar un cargador de scripts sin concatenar será más lento que una etiqueta de script concatenada. Es por eso que las personas (YUI, requireJS) crearon cargadores de scripts que cargan archivos y servicios concatenados que los concatenan a pedido (https://github.com/rgrove/combohandler).

Vamos, esta discusión no tiene ningún sentido. Los cargadores de scripts sirven para cargar scripts a pedido, particularmente después de la interacción del usuario, por ejemplo, para cargar la lógica detrás del diálogo y la validación de formularios al hacer clic en un botón "iniciar sesión".

Tengo la astuta sospecha de que @jashkenas y @madrobby están simplificando demasiado las cosas.
Steve sugiere que la descarga paralela tiene varios beneficios para una variedad de problemas de bloqueo y navegadores _ (sí, eso significa que no es WebKit) _. También menciona una estrategia de cargar el JS mínimo requerido para las tareas de carga de dom y luego cargar el resto más tarde según sea necesario. Debido a que las situaciones y las necesidades de desarrollo varían, no sé si un cargador de scripts pertenece a un código estándar _ (habilitado de forma predeterminada) _ pero todavía no arrojaría al bebé con el agua del baño.

Si no estaba claro en mi publicación original. Tiendo a estar de acuerdo (con jdalton) en que hay bastantes beneficios de los cargadores de scripts en entornos altamente probados y específicos que requieren atención especial. No creo que sea un valor predeterminado apropiado.

Estoy de acuerdo con @jdalton : no hay un cargador de tamaño adecuado para todos. Personalmente, uso diferentes cargadores de scripts en función de mis necesidades y proyectos reales. A veces, algo simple como yepnope o LabJS está bien, otras, RequireJS es un regalo del cielo. No estoy seguro de que un texto estándar tenga que forzar a uno. Es complicado porque la idea sería que el texto estándar facilitara el cambio a un cargador de secuencias de comandos ... para no tirar al bebé con el agua de la bañera solo todavía tampoco.

Además, @getify , pretender que todos los cargadores de scripts realmente usan la misma tecnología debajo es una declaración muy desinformada.

Por lo que vale...
esta

var script = document.createElement('script')
script.src = 'foo.js'
document.getElementsByTagName('head')[0].appendChild(script)

es mejor que esto

<script src="foo.js"></script>

por la única razón principal de que no es bloqueante. Por lo tanto, las imágenes y los archivos CSS posteriores deberán esperar hasta que ese archivo se descargue con la última versión. El primero es asíncrono: todo el mundo debería saberlo independientemente de si decide utilizar un cargador de scripts o no.

re: "pretender que todos los cargadores de scripts realmente usan la misma tecnología debajo es una afirmación muy desinformada".

Si no lo están haciendo de la forma anterior, lo están haciendo mal

Bueno, para ser perfectamente justos, el uso de appendChild ha caído en desgracia ...: D

Sin embargo, agregué ese caso de prueba a AssetRace

https://github.com/SlexAxton/AssetRace/blob/master/asyncconcat.html

Hace que la carga se dispare más rápido, por lo que _podría_ haber algún beneficio percibido. Pero el tiempo de finalización es casi el mismo ...

@ded : No estamos hablando de bloqueos grandes incompetentes <script> en <head> aquí ... estamos hablando de etiquetas de script con defer o async atributo, cargado al final del <body> , donde no queda nada para bloquear.

@ jaubourg--

Además, @getify , pretender que todos los cargadores de scripts realmente usan la misma tecnología debajo es una declaración muy desinformada.

Esta es una completa mala representación de lo que estaba tratando de conseguir. De hecho, la mayoría de los cargadores de scripts NO están haciendo las cosas que creo que deberían estar haciendo (y que ahora hacen los LABj) en términos de usar la mejor tecnología. Mi punto fue, incluso si todos ellos usaron la mejor tecnología, todavía hay un límite finito para lo que podemos hacer en cuanto a tecnología. Estoy bastante seguro de que no hay cargadores que estén usando alguna solución mágica que LABjs desconozca o no use. No puede hacer que la luz vaya más rápido que la velocidad de la luz, sin importar lo que haga o cómo juegue con los números.

Discutir sobre la tecnología subyacente (a modo de decir "oye, mira mi API genial y mejor") no tiene sentido. La mejor tecnología en la carga de scripts es una cantidad finita conocida (incluso si muchos cargadores son irresponsables y no la usan). Podemos presionar por una mejor tecnología (que soy yo), pero debatir quién tiene la mejor API en su cargador no hace nada para ese objetivo.


Este hilo realmente parece tener más sentido para tratar de determinar si las etiquetas de secuencia de comandos son lo suficientemente buenas por sí mismas (con o sin aplazamiento) o si los cargadores de secuencias de comandos ayudan a obtener un mejor rendimiento. En segundo lugar, debemos averiguar si concat realmente es el final de la carga de scripts.

También es un punto discutible (para este hilo) que los cargadores de scripts tienen todos estos otros casos de uso que pueden hacer, que las etiquetas de scripts de marcado no pueden hacer (como bajo demanda / carga diferida). Una vez más, eso es básicamente un hecho en este punto, por lo que tratar de restablecer ese hecho no tiene sentido.

NO U

¡CARGUE RAGE!

loaders make me rage

Vea la publicación original aquí.

Además, cualquier persona ofendida por un pene de dibujos animados: ¡bienvenido a Internet! Te recomiendo encarecidamente que comiences tu viaje aquí .

Bien, he creado 3 pruebas para ilustrar algunos puntos. Primero, etiquetas de secuencia de comandos manuales (como línea base):

http://labjs.com/dev/test_suite/test-script-tags.php

Observe que DOMContentLoaded (también conocido como "DOM-ready") llega muy tarde, después de que finalizan los scripts. Esto es lo malo. Si bien el tiempo de carga real de la página puede ser el mismo que en las pruebas posteriores, el tiempo de carga percibido de la página siempre será mucho más lento si se bloquea la función DOM-ready (muchos sitios esperan hasta que DOM-ready para adjuntar comportamientos de clic, aplicar mejoras impulsadas por JS al contenido, etc.).

Ahora, lo que sucede es que usamos defer en nuestras etiquetas de script:

http://labjs.com/dev/test_suite/test-script-defer-tags.php

Bueno, eso es bueno, hemos solucionado el problema de demora de DOMContentLoaded, pero ahora tenemos otro problema. El bloque de secuencia de comandos en línea no funciona con defer . Se ejecuta de inmediato. UPS. Por cierto, esto no es un error, la especificación lo dicta específicamente.

http://labjs.com/dev/test_suite/test-LABjs.php

La prueba LABjs obtiene básicamente los mismos (o mejores) números de rendimiento en comparación con la prueba defer , pero no falla al hacer que el código en línea se ejecute después de que finalicen los scripts.

Pruebe esas pruebas varias veces en navegadores modernos (Chrome 13, FF5, etc.). Para mí, los LABjs siempre se comportaron igual o mejor que la prueba defer . En todos mis intentos, nunca he visto a los LABj funcionar peor que la prueba defer . Pruebe esas pruebas en navegadores más antiguos (como FF3.5 o IE7) y verá que el cargador de scripts comienza a superar las otras pruebas en cantidades notables.

Aunque la prueba LABjs tiene números similares a la prueba defer en los navegadores más nuevos, es un factor decisivo si defer no se puede usar para defer TODO el código (solo funciona para el código que se carga a través de un archivo externo). MUCHOS sitios cargan scripts y luego tienen código en línea para activar / iniciar el código que acaban de cargar. defer no nos ofrece ninguna solución para esto.

Por lo tanto, defer no es adecuado como tecnología de "carga de scripts general". La siguiente mejor opción es un cargador de scripts.

@getify

No se trata solo de microoptimizaciones ... y, SÍ, la API es importante y generalmente es una buena indicación del tipo de limitaciones que tiene la tecnología subyacente, principalmente debido a dichas micro (o incluso macro) optimizaciones. No siempre se trata solo de cargar scripts. La gestión de dependencias complejas, el sandboxing adecuado y la modularidad real, real, no es algo que deba descartarse solo porque no tiene ningún interés en ello. ¿Adivina qué? En realidad, estas son las cosas que las personas necesitan y el rendimiento de carga de la página se puede lograr a un nivel razonablemente bueno con etiquetas de script estáticas.

Finalmente, todo se reduce a que la inyección de etiquetas de script no es la herramienta adecuada para la tarea: en realidad nunca lo fue. Es solo un truco muy feo. En ese sentido, en realidad no está presionando por una mejor tecnología: está presionando por más de lo mismo con nuevos tipos de advertencias que ninguno de nosotros puede inferir todavía. Por favor, piense por un mero segundo y vea si finalmente hace clic.

Lo que realmente enfurece es que se niega a presentar un solo argumento a favor de la inyección de etiquetas de script en lugar de una API de JavaScript nativa y adecuada para la carga de scripts. Simplemente ignora todo el asunto. Sin embargo, te ahorraré la molestia: no hay discusión allí. Pero, eh, todos podemos tener un poco de masturbación mental sobre los entresijos de diferir y asincronizar y sentir que somos los dioses de javascript, ¿verdad? O debata sobre optimizaciones de 50ms como si realmente estuviera ayudando a cualquiera en esta industria.

Si finalmente decide que soy lo suficientemente digno de una respuesta inteligente (a diferencia de otro anuncio de LabJS), hágalo en mi blog y dejemos este hilo solo. Gracias.

@jaubourg -
Leí tu publicación en profundidad la última noche. Estaba planeando escribir una publicación de blog en respuesta, en gran parte felicitándote y felicitándote por los buenos pensamientos que presentaste allí. Desafortunadamente, los miembros del hilo de discusión sobre W3C y WHATWG ya han redactado AT LONGITUD lo que está sugiriendo. Llegas bastante tarde a esa fiesta.

Hubo varias personas que admitieron una API de cargador completamente nueva, y hubo varios contraargumentos importantes de por qué probablemente esa no era la mejor manera de hacerlo. Nuevamente, estaba planeando escribirle una respuesta en una publicación de blog cuidadosa y razonada, para ayudar a explicar todo eso.

Lástima que tengas que ir y ser tan idiota aquí. Ahora me hace sentir que esa publicación razonada del blog será una pérdida de tiempo. Obviamente piensas que soy un idiota y nunca has considerado las cosas que intentas mencionar. Porque no he pasado la mayor parte del año pasado absolutamente obsesionado con la tecnología del cargador de scripts y cómo obtener las especificaciones y los navegadores para mejorarla. Sí, soy un idiota. Claramente, nunca antes había pensado en otra cosa que no fuera la etiqueta del script.


Aparentemente no escuchaste las 15 veces que dije que _este_ hilo tenía el mejor objetivo de enfocarse en las preguntas específicas que Paul Irish y Alex Sexton plantearon: ¿ defer es lo suficientemente bueno? ¿Es mejor script-concat que la carga paralela?

Éstas son las preguntas más importantes.

No qué tecnología de "cargador" subyacente se utiliza. Hay un foro diferente y mejor para discutir cuál es la tecnología de carga subyacente. Entiendo, no te gusta la etiqueta de script. Multa. Pasa decenas de horas en la lista W3C / WHATWG tratando de que Ian y otros te escuchen. Probablemente todos bostezarán y dirán "ya lo hemos aclarado, vete".

@getify : La creación de pruebas ridículas de muñeco de paja no te hará ganar puntos, amigo. Todos sabemos que las etiquetas secuenciales de secuencia de comandos bloquean la página. También sabemos que tener bloques de scripts en línea que se ejecutan antes de "diferir" los scripts ed no es un problema de ninguna manera para los sitios reales.

Si realiza una prueba para confirmar un error previo ... sus pruebas siempre confirmarán ese error. El debate nunca ha sido sobre 20 etiquetas de script frente a 20 cargas de script de LABj. Se trata de recortar, concatenar, minificar, comprimir y cargar de forma inteligente su JavaScript en la menor cantidad posible de solicitudes HTTP y luego almacenarlo en caché.

Por un lado, tenemos un enfoque confiable, compatible con el navegador y probado en el tiempo, que funciona mejor en páginas del mundo real; y, por otro lado, tenemos una "tecnología" pirateada que, en el pasado, ha estropeado todos los sitios que la usaban después de una actualización del navegador, que tiene un rendimiento demostrablemente peor en promedio y con una variación de lentitud mucho mayor.

Es una elección obvia.

@ jashkenas--

También sabemos que tener bloques de scripts en línea que se ejecutan antes de "diferir" los scripts ed no es un problema de ninguna manera para los sitios reales.

Uhh ... Supongo que no ha visto el código fuente en aproximadamente el 98% de todos los sitios en Internet, que de hecho usan bloques de script en línea en el marcado para ejecutar / inicializar el código que cargaron en una previa (bloqueo) llamada de etiqueta de secuencia de comandos.

Si @paulirish sugiere que defer es lo suficientemente bueno y que los cargadores de scripts no son necesarios, entonces creo que es importante señalar por qué, de hecho, defer NO ES lo suficientemente bueno.

Es posible que a USTED solo le interesen los pocos sitios de nicho que controla, que tiene la capacidad completa de estar altamente optimizado sobre los procesos de compilación, etc. Por otro lado, a mí me importa ayudar a mejorar el rendimiento en los sitios de cola larga de Internet, los con media docena de etiquetas de script (¡algunas de ellas bloques de script en línea!), donde el uso de media docena de llamadas $LAB.script() de hecho probablemente mejoraría el rendimiento. De eso se trató siempre LABjs. El hecho de que no sea lo que te importa no significa que no sea relevante.

El debate nunca ha sido sobre 20 etiquetas de script frente a 20 cargas de script de LABj.

El debate en este hilo es sobre si 3-4 etiquetas de script (con o sin defer ) funcionan peor, igual o mejor que 3-4 scripts cargados dinámicamente usando un cargador de script paralelo. Mis "pruebas ridículas del hombre de paja" tienen la intención de probar exactamente eso.

En mi experiencia, los cargadores de scripts reducen muchos milisegundos el tiempo de carga de la página. Pero creo que todos hemos perdido el punto aquí. JavaScript tiene algunos problemas mayores:

  • La falta de declaraciones de importación dificulta la organización de su código de forma modular
  • Las variables globales colisionan, a menos que se preste mucha atención al espacio de nombres cuidadoso de todo.
  • No hay forma de ver claramente cuáles son las dependencias de un script

No uso RequireJS porque se carga más rápido, aunque es un buen efecto secundario. Lo uso para poder organizar mi aplicación JS en pequeños módulos como lo haría en NodeJS. Cada módulo enumera claramente sus dependencias y utiliza el patrón de espacio aislado para mantener limpio el espacio de nombres global. Los módulos (y sus dependencias) pueden cargarse por adelantado, cargarse a pedido (al hacer clic en el usuario, por ejemplo), o cargarse de forma diferida. Realmente puede ajustar su desempeño con estas técnicas. Y RequireJS también viene con una herramienta de compilación que combina y minimiza todas las dependencias en un solo (o un puñado de) archivo (s) listo para gzip para su implementación. Resolver estos tres problemas es una gran victoria para mí.

Puedo ver por qué la gente debatiría sobre el uso de un cargador de scripts que no resuelva estos problemas. Si el rendimiento es el único punto y es debatible, entonces seguro. Pero use un cargador de módulos AMD como RequireJS y el debate se vuelve irrelevante. Los módulos son el futuro de JavaScript. Dave Herman de Mozilla está trabajando con miembros de la junta de Apple y Google para agregar módulos nativos al idioma en sí . Pero mientras tanto, podemos obtener todos los beneficios mediante el uso de un cargador de módulos AMD. No se trata solo de rendimiento.

@getify

No puede esperar que la gente lo trate de manera diferente a como lo hace con los demás. Ser condescendiente no es una forma inteligente de obtener una reacción decente (y Dios es condescendiente) y, como dije en la publicación de mi blog, no creo que seas un idiota, solo creo que estás obsesionado (lo que dices usted mismo por cierto) y que perjudica gravemente su juicio. Como dije en la publicación de mi blog, no depende de W3C o WHATWG manejar este problema, sino de EcmaScript en sí: esto no es un problema del navegador, es un problema de idioma. Ahora, no responda si no quiere, es su prerrogativa.

Tal vez vine con dureza, pero solo defiendo lo que creo.

Me daré de baja de este hilo y volveré a comentarlo. Lamento haber descarrilado cosas @paulirish y @SlexAxton.

@getify

Es posible que USTED solo se preocupe por los pocos sitios de nicho que controla, que tiene
completa capacidad de estar altamente optimizado sobre los procesos de construcción, etc.
Por otro lado, se preocupan por ayudar a mejorar el rendimiento en los sitios de cola larga del
Internet, los que tienen media docena de etiquetas de secuencia de comandos (algunas de ellas
bloques!), donde el uso de media docena de llamadas $ LAB.script () de hecho probablemente
mejorar el rendimiento. De eso se trató siempre LABjs. Simplemente porque
no es lo que te importa no significa que no sea relevante.

Si LABjs se trata de ayudar a que los sitios mediocres se carguen un poco menos ... ese es un objetivo noble, supongo. Pero si realmente quiere tomar un sitio web de carga lenta y hacer que se cargue lo más rápido posible, potencialmente literalmente unos segundos más rápido de lo que permitirían los LABjs, entonces le conviene mantener la mente abierta y reconocer que lo más fácil y menos frágil La técnica también es más eficaz.

El debate en este hilo es sobre si 3-4 etiquetas de script (con o sin aplazamiento)
funciona peor, igual o mejor que 3-4 scripts cargados dinámicamente usando
un cargador de scripts en paralelo. Mis "ridículas pruebas de hombre de paja" tienen la intención de
prueba exactamente eso.

El debate en este hilo es sobre cómo construir un sitio web para cargar y ejecutar su JavaScript lo más rápido posible. Vender aceite de serpiente a los clientes y promocionarlo entre los desarrolladores web es un flaco favor para ambos.

Existe latencia en Internet. Concatenar, minificar y gzip su JS y cargarlo en la parte inferior de la página en la menor cantidad posible de solicitudes HTTP. Dijo Nuff.

@ jashkenas--

Si LABjs se trata de ayudar a que los sitios mediocres se carguen un poco menos ... ese es un objetivo noble, supongo

Hay cientos de sitios que conozco personalmente de los últimos 2 años que no hicieron nada más que reemplazar sus etiquetas de script con llamadas $LAB.script() , y en general todos vieron un mejor rendimiento (algunos drásticamente, otros solo modestamente).

Se han escrito artículos (completamente independientes y no relacionados conmigo) centrados en ayudar a sitios de diversas industrias (como comercio electrónico, bienes raíces, etc.) a obtener un mejor rendimiento (porque un mejor rendimiento significa más conversiones), donde esos artículos se recomendaban a los sitios que reemplazan las etiquetas de script con llamadas $ LAB, y muchas personas en esos hilos de comentarios han respondido afirmativamente que les ayudó.

Si esos artículos hubieran dicho "Está bien, lo que debe hacer para obtener un mayor rendimiento es contratar a un administrador del servidor que entienda gzip y pueda instalar ruby ​​o node.js para que pueda realizar algunos procesos de compilación automatizados ...". leer esos artículos se habría vuelto vidrioso y se habría ido sin pensarlo más. Pero me gusta creer que "Oye, reemplaza <script> con script ()" fue un mensaje bastante fácil de entender y conectar.

Lo que quería para LABjs es una solución simple que alguien pueda colocar fácilmente para reemplazar sus etiquetas de script sin pensar demasiado. Reconozco que si puede consultar personalmente con un sitio y descubrir las mejores optimizaciones, puede exprimir mucho más el rendimiento de muchos sitios. Pero también reconozco que esto está mucho más allá de mi capacidad como una persona para hacer durante la larga cola de Internet, y de manera similar, decirle a todos esos sitios familiares "oye, busca un sistema de compilación automatizado y asegúrate de que use gzip" es como hablándoles un idioma extraño. OTOH, ha tenido bastante éxito decir "Oye, toma esas 3 etiquetas de script y hazlas 3 llamadas de script (). ¿Ves lo fácil que fue?"

En pocas palabras, mi enfoque con LABjs fue llegar a la fruta madura.

Nada de eso sugiere que no sean posibles enfoques más sofisticados de optimización; claramente lo son, y cuando tengo la oportunidad de consultar, definitivamente los exploro. Es solo para decir que para gran parte de la web, es más complicado de lo que están dispuestos o pueden conseguir. Y solo estoy tratando de ayudar a _esos_ sitios a mejorar de una manera que sea más fácil de entender para ellos.

@ jashkenas--

potencialmente literalmente segundos más rápido de lo que LABjs permitiría, entonces le conviene mantener la mente abierta y reconocer que la técnica más fácil y menos frágil también es más eficaz.

Nunca ha habido ninguna evidencia establecida que sugiera que LABjs esté ralentizando significativamente cualquier sitio. Hay MUCHAS pruebas comprobadas de que está ayudando a muchos sitios. Así que no me lo trago, de lo que estás hablando es de una premisa falsa asumiendo hechos que no son evidencia.

@paulirish encontró una publicación que señala problemas con el atributo defer :
http://hacks.mozilla.org/2009/06/defer/

Desde una perspectiva de rendimiento móvil, como dijo @jashkenas , siempre es mejor concatenar, gzip y enviarlo a través de la línea como un paquete que tener múltiples solicitudes http debido a la latencia incurrida por las conexiones de red 3g.

Se están realizando muchas investigaciones sobre el uso de técnicas de inserción en las que codifica imágenes en base64 en cadenas y luego las almacena como pares clave: valor en localStorage solo para reducir las solicitudes http y aprovechar el 'almacenamiento en caché': http://channel9.msdn.com/Events / MIX / MIX11 / RES04 es una gran presentación de James Mickens de Microsoft Research.

Aquí hay una presentación bastante buena sobre el rendimiento móvil con solicitudes http y sus efectos en la experiencia del usuario: http://davidbcalhoun.com/present/mobile-performance/

Trabajo en RequireJS y quiero hacer una aclaración de lo que RequireJS pretende hacer:

1) Muestre el camino para el código modular en JS que funciona bien en todos los lugares donde se ejecuta JS.
2) Cargar scripts.

La parte de "cargar scripts" es una parte necesaria para lograr el primer objetivo. En desarrollo, no es una buena idea concatenar todos los scripts porque dificulta la depuración, los números de línea no coinciden. Los cargadores de scripts también facilitan el uso de una API JS para cargar código a pedido. Para las aplicaciones del tamaño de un correo web, esta es una parte necesaria de la historia de desempeño. Sin embargo, concatenar los scripts en una o en una pequeña cantidad de solicitudes suele ser la mejor opción de implementación.

Pero el objetivo de requirejs es ser shim / polyfill / anything para mostrar cómo crear y hacer referencia a unidades de código modular que se pueden compartir con otros de una manera que desalienta los globales y fomenta las dependencias explícitas.

Utiliza la API de AMD que se ha elaborado con otras personas que hacen cargadores de scripts modulares (incluye pruebas de cumplimiento ), con el objetivo de ayudar a informar cualquier discusión sobre un formato de módulo en JS. Este enfoque, al realizar implementaciones en el mundo real y llegar a un acuerdo con otros sobre la API, es la forma en que se avanza.

En particular, dada la naturaleza de red de JS y su relación con los documentos / aplicaciones web, la API del complemento de cargador es algo que debería ser compatible de alguna manera con los módulos de ES Harmony, y estoy trabajando en la creación de

Para la gente del espectáculo :

  • Hay algunas opciones para cargadores que admiten AMD ( curl , Dojo 1.7 , loadrunner , requirejs), incluso una muy pequeña que se puede usar para la optimización de "todos los scripts en un archivo JS" realizada para la implementación. Por lo tanto, es posible obtener un gran rendimiento al mismo tiempo que se fomentan las mejores prácticas de codificación: un intercambio de código más fácil al evitar los globales, utilizando dependencias explícitas.
  • El optimizador requirejs se ejecuta muy rápido en Node y puede ejecutarse en Rhino. Es una herramienta de línea de comandos, pero el último código de la rama maestra lo exporta como un módulo utilizable en Node, por lo que, por ejemplo, se puede ejecutar a través de un servidor http basado en Node que puede realizar la compilación sobre la marcha . Por lo tanto, siempre puede desarrollar en el modo de "descarga de un solo script siempre" si lo prefiere, pero luego elija omitir uno o dos módulos fuera de ese archivo optimizado, para que pueda depurarlos fácilmente.

En el contexto de este ticket : la elección de un cargador compatible con AMD (no tiene que ser requirejs) encaja con los objetivos del modelo HTML: señalar el camino hacia las mejores prácticas, tanto en código como en rendimiento. Sin embargo, agradezco que tratar de elaborar una plantilla HTML es algo muy difícil de hacer, hay intereses en competencia, algunos de estilo, por lo que agradezco no querer hacer una recomendación en esta área en este momento.

Solo quiero dejar en claro que el objetivo de los requirejs y los cargadores que implementan la API de AMD brindan un beneficio mayor que simplemente cargar algunos scripts que descargan globales y obligan al desarrollador a resolver el árbol de dependencias completo, a veces implícito. Esos objetivos se logran con soluciones que tienen perfiles de desempeño sólidos.

Para reenfocar desde antes ... comparando la prueba defer con la prueba LABjs ... (e ignorando el hecho de que defer no funciona en bloques de script en línea), ¿alguien está viendo que el ¿La prueba de LABjs está funcionando peor que la prueba defer ? Lo probé en varios navegadores, e incluso en mi dispositivo móvil, y sigo viendo números aproximadamente iguales.

http://labjs.com/dev/test_suite/test-script-defer-tags.php

http://labjs.com/dev/test_suite/test-LABjs.php

@getify

No tengo idea de por qué o cómo puede optimizar esto, pero tengo, en mi máquina MacBook de más de 3 años, una diferencia constante de 3000 entre las dos, lo que favorece @defer .

Sin embargo, solo lo he probado con Firefox.

@ espadrine-- bastante extraño. Me encantaría llegar al fondo de eso. ¿Con qué versión de Firefox estás probando? ¿me pueden enviar una captura de pantalla de los resultados?

Simplemente concatene y minimice todo su JS y CSS e incorpórelo directamente en su página HTML y listo. ¡Petición HTTP única FTW! :PAG

Sin embargo, en serio, hay muchos problemas más importantes en los que deberíamos centrarnos en esta comunidad que solo en cómo se cargará su aplicación. Lo más probable es que el método más simple (etiquetas de script en la parte inferior) sea lo suficientemente rápido. Simplemente escriba aplicaciones geniales y lidie con el rendimiento de carga al final. Hacer cualquier otra cosa es optimizar prematuramente.

¿Existe un consenso general de la gente en este hilo de que AMD debería ser el estándar de oro para la organización del código JS? Realmente no he visto otras opciones, pero estoy de acuerdo en que el Boilerplate sería un gran comienzo para configurar a la gente en la organización del código.

Canal de actualización de Firefox UX 8.0a1 (2011-08-07).

defer
LABjs

Nuevamente, no tengo idea de por qué, y esto probablemente sea muy específico. LABjs probablemente sea muy bueno con los navegadores heredados.

Por favor, no uses la página de prueba de

<script defer src = "http://labjs.xhr.me/dev/test_suite/testscript1.php?_=4911710&delay=5"> <script defer src = "http://labjs.xhr.me/dev/test_suite /testscript2.php? _ = 6146431 & delay = 3 "> <script defer src =" http://labjs.xhr.me/dev/test_suite/testscript3.php?_=9499116&delay=1 ">

@getify , si quieres hacer una prueba real, siéntete libre de bifurcar el repositorio AssetRace de @SlexAxton y agregar una versión LABjs ... o hacer una página de prueba que use _real_ de archivos JavaScript, con latencias reales.

Además, asegúrese de concatenar el JS para una sola etiqueta de script: defer o no. El punto es que el mismo contenido servido en 1 solicitud HTTP supera al mismo contenido servido en 10 solicitudes HTTP.

Nunca ha habido ninguna evidencia establecida que sugiera que LABj sea significativamente
ralentizando cualquier sitio. Hay MUCHAS pruebas comprobadas de que está ayudando mucho
de sitios. Así que no me lo trago. De lo que estás hablando es de una premisa falsa, asumiendo
hechos que no están en evidencia.

Lo que se demostró anteriormente es que LABjs de hecho está ralentizando significativamente los sitios, al hacer que su JS compita en muchas solicitudes HTTP con sus imágenes, CSS y otros activos. @getify : Me encantaría ver un enlace a un sitio que crea que se demostró en gran medida a partir de su conversión a LABjs. Quizás podamos descargar una copia de eso y usarlo como un caso de prueba que respetarás.

Para que conste, creo que sería prudente obtener algunas imágenes más en la página de prueba del repositorio de AssetRace. Pero ciertamente es una buena línea de base en este momento.

@artzstudio organizar su JS con un cargador AMD es de hecho el estándar de oro, al menos hasta que los módulos de Harmony estén terminados y sean ampliamente compatibles. Luego, habrá una ruta de migración clara de los módulos AMD a los módulos nativos.

Que los módulos AMD sean el estándar de oro es sin duda una opinión (una que puedo compartir). Sin embargo, hay muchas personas inteligentes (me vienen a la mente Yehuda Katz y Dan Webb) a quienes no les gusta y ofrecen otras soluciones.

El loadrunner de @danwrong puede hacer ambas cosas, si ese es tu bolso también: https://github.com/danwrong/loadrunner

Hay algunas cosas bastante buenas ahí. Potencialmente un poco más práctico también para gente que no es JS. Me gustan los módulos AMD para mis cosas, pero no todo el mundo quiere dedicar tiempo a convertir cada versión de las bibliotecas que utilizan en módulos.

Sé que @strobecorp está trabajando en su propia solución que no requiere mucho código adicional que requieren los módulos AMD.

Si bien me encantaría que AMD sea el predeterminado, probablemente no sea prudente desde el punto de vista de múltiples bibliotecas / newb, por mucho que desearía que fuera.

@ jashkenas--

Por favor, no uses la página de prueba de

Si no puede ser cortés, no tengo ningún deseo de discutir nada más con usted. Actúo de buena fe. Agradecería un poco de decencia común.

@getify , si quieres hacer una prueba real

Seguro que me gustaría que me explicaras por qué lo que estoy haciendo es tan loco, ridículo e inválido. Tomé el enfoque directamente de Steve Souders, quien (en su gran experiencia y sabiduría) sugirió en todas sus pruebas que usara la sincronización del servidor para controlar los scripts, reduciendo la cantidad de variación en sus pruebas. Eso es exactamente lo que estoy haciendo.

Una prueba más controlada es una prueba de referencia válida. Esa es una práctica científica establecida. Eso no significa que las pruebas del mundo real no sean también útiles, pero tampoco significa que puedas dispararme y decir "ríete de él, qué idiota porque hace sus pruebas de manera diferente que creo que debería estar hecho."

siéntase libre de bifurcar el repositorio de

Felizmente lo haré. Pero no porque esté de acuerdo en que mis otras pruebas no son válidas. Si tiene algunos argumentos razonados y sensatos sobre por qué mi configuración de prueba no es válida, por favor comparta. Pero deja de ser tan idiota al respecto.

@ jashkenas--

El punto es que el mismo contenido servido en 1 solicitud HTTP supera al mismo contenido servido en 10 solicitudes HTTP.

Sé que usted (y otros) siguen despotricando sobre cómo esta discusión debería ser sobre concat versus no concat. Si leyó mucho antes en el hilo, admití que había dos preguntas que debían abordarse. Las dos cuestiones son, en lo que a mí respecta, ortogonales. La primera es si las etiquetas de secuencia de comandos en el marcado pueden ser tan buenas (o mejores) que los elementos de secuencia de comandos dinámicos utilizados en un cargador de secuencias de comandos paralelo. ESA PREGUNTA es lo que todavía estoy tratando de abordar con mis pruebas.

La segunda pregunta, a la que no hemos llegado todavía, es si script-concat siempre es mejor. Sé que ya estás convencido de ello, pero tengo pruebas contrarias que sugieren que no es tan simple. Esa pregunta también debe probarse a fondo. Pero no es lo que estoy tratando de resolver en este momento en este hilo.

Si continúa insistiendo en que su camino es el mejor, hará que todo el debate sea menos agradable de participar. Todo lo que intento hacer es establecer metódicamente alguna evidencia para cada una de esas dos preguntas principales, para que podamos dejar de adivinar y estar más informados. ¿Por qué no es algo en lo que puedas ayudar, en lugar de tratar de ser un idiota conmigo porque no estás de acuerdo conmigo?

Con respecto a la prueba defer frente a la prueba LABjs, acabo de hacer una captura de pantalla rápida de probar los dos cara a cara en IE9, FF8 (nocturno) y Chrome15 (canario).

http://www.screenr.com/icxs

Para responder a la pregunta anterior de @paulirish (https://github.com/paulirish/html5-boilerplate/issues/28#issuecomment-1765361) sobre defer peculiaridades, observe cómo se comporta "DOMContentLoaded" en IE, Chrome y Firefox en la prueba defer .

En IE9 y Chrome15, el evento DOMContentLoaded se retiene (bloquea) y no se activa hasta que se ejecutan los scripts. En FF, sin embargo, el evento DOMContentLoaded no se detiene, se dispara de inmediato y los scripts comienzan a ejecutarse después de él. Esa es una gran inconsistencia en los navegadores modernos, y una de las razones por las que no creo que defer sea ​​suficiente.

Por lo que puedo decir al leer las especificaciones, no estoy seguro de qué comportamiento es el correcto. Pero sí sé que es claramente peculiar e inconsistente entre navegadores.

@getify No estoy tratando de ser un idiota. Me disculpo sinceramente por herir tus sentimientos.

Naturalmente, lo que usted ve como despotricar, lo veo como el punto de la discusión ... y lo que veo como aceite de serpiente, lo ve como un útil paso adelante.

Las dos cuestiones son de hecho ortogonales (lenguaje que usé en mi publicación original).

La primera es si las etiquetas de script en el marcado pueden ser tan buenas (o mejores) que
elementos de secuencia de comandos dinámicos utilizados en un cargador de secuencias de comandos paralelo.

Estamos completamente de acuerdo sobre este tema, no importa. Por supuesto, la carga paralela será más rápida que la carga secuencial para más de un script. Y, por supuesto, hacerlo sin bloqueo, ya sea al final de la etiqueta <body> , o con defer , o con un cargador de scripts, será mejor que bloquear en <head> .

Pero esto pierde el sentido. Poner etiquetas de secuencia de comandos secuenciales es una comparación, porque nadie que se preocupe por el rendimiento de su JavaScript usaría ese enfoque. ¿Adivina qué es también más rápido que las etiquetas de secuencia de comandos secuenciales? _Cualquier cosa_.

La segunda pregunta, a la que todavía no hemos llegado, es si
script-concat siempre es mejor.

Hemos "llegado a" esta pregunta. De hecho, es la pregunta de

Esa pregunta también debe probarse a fondo.

Para repetirme, aquí hay un caso de prueba (justo). Los mismos 5 scripts del mundo real, cargándose en una página de tamaño mediano con otros activos presentes, uno usa las mejores prácticas de LABj para asegurar el orden de carga y el otro usa un único script concatenado:

http://jashkenas.s3.amazonaws.com/misc/snake-oil/labjs.html

http://jashkenas.s3.amazonaws.com/misc/snake-oil/vanilla.html

Si tiene otro caso de prueba que le gustaría examinar, o un sitio web real que utiliza LABjs con el que le gustaría experimentar, por favor compártalo.

@SlexAxton Gracias. Tendría curiosidad por escuchar la opinión de Yehuda al respecto y otras opiniones sólidas (aparte de que es demasiado difícil de refactorizar). Encontré esto pero no la charla.

Para aclarar el comentario de @geddesign : a partir de hoy , parece que los módulos AMD se pueden convertir con bastante facilidad en módulos de armonía, pero la propuesta de módulos de armonía que considero aún está en proceso de cambio, podría cambiar más adelante. Aún no ha pasado por una rigurosa prueba de implementación, pero está empezando a tener algunas patas. En el lado positivo, los complementos de cargadores + cargadores de AMD pueden brindar comentarios sólidos para probar algunas de las ideas de armonía.

Para el comentario de @SlexAxton :

Para loadrunner: no me queda claro que la sintaxis sea mejor, simplemente diferente. Es compatible con AMD, por lo que todavía funciona.

Para luz estroboscópica: todavía tengo que ver el código de ellos. Parecen bastante enfocados hacia adentro, aunque aprecio el trabajo que Yehuda ha hecho para abrir ese desarrollo. Alex, si tienes sugerencias sobre lo que están pensando, te agradecería que las recibas.

Si el enfoque va a permitir dependencias anidadas (que es necesario para un amplio intercambio de código), necesita una sintaxis que:

  • da un nombre a una unidad de código
  • una forma de especificar dependencias
  • una función que envuelve ese código para asegurarse de que no se ejecute hasta que las dependencias estén listas. O siempre solicite una compilación o acceso XHR, que no es escalable en todo el espectro del desarrollo de JS.

Esto es lo que proporciona AMD, y la sintaxis es lo más delgada posible. Cualquier otra cosa es simplemente pelear por nombres y posiblemente algunos tipos de puntuación. En algún momento, es necesario elegir algo, y hasta ahora no he escuchado de Dan Webb o Yehuda acerca de las debilidades estructurales que hacen que AMD sea insostenible. Algunos cargadores AMD, como requirejs, pueden cargar scripts normales, no tienen que ser módulos.

Es muy fácil pensar en la sintaxis del código, particularmente para los módulos, y puedo apreciar que todos tienen sus propias preferencias personales. Sin embargo, AMD tiene un historial bastante profundo de hacer el arduo trabajo de obtener algún tipo de acuerdo y, lo que es más importante, código real e implementación para respaldarlo. Siento que ahora los demás tienen la responsabilidad de ser realmente claros y claros sobre por qué AMD no es una buena opción (este boleto no es el lugar para hacerlo, no dude en ponerse en contacto conmigo fuera de la lista o usar la lista de implementación amd ) .

Pero aprecio la opinión de @SlexAxton . Estandarizar en un enfoque AMD para HTML repetitivo podría ser prematuro, y estoy completamente de acuerdo con eso. Si el proyecto estándar decide que quiere elegir uno, AMD es una opción sólida que se adapta a un amplio espectro de desarrollo JS.

@SlexAxton Estoy contigo. Mi propio código es AMD hasta el final. Si bien me gustaría que todos escribieran módulos en lugar de scripts, afortunadamente RequireJS puede cargar tanto scripts simples como módulos.

Si te refieres a las plantillas de handlebars.js de Yehuda, funcionan muy bien con RequireJS. Especialmente si escribe un complemento que compila / almacena en caché la plantilla y devuelve su función de plantilla.

define(['tmpl!navigation.html'], function(nav){
   $('body').append(nav(data));
});

Sin embargo, no estoy de acuerdo con esta afirmación:

Si bien me encantaría que AMD sea el predeterminado, probablemente no sea prudente desde el punto de vista de múltiples bibliotecas / newb, por mucho que desearía que fuera.

Los Newbs necesitan la estructura limpia que proporciona AMD incluso más que un desarrollador experimentado, ya que son más propensos a colisiones de variables globales, una organización de código terrible que conduce a archivos JS desordenados que nadie quiere tocar por temor a tener que lidiar con conflictos de fusión. Las bibliotecas se benefician enormemente de los módulos, por lo que los próximos Dojo 1.7 y Mootools 2.0 se están trasladando a AMD. Espero que jQuery se sume; una de sus mayores quejas es que es "todo o nada". No puede usar su excelente manipulación DOM sin cargar también su animación, ajax, eventos, etc.en la página también. Así que sí, AMD es beneficioso para todos. Si HTML5 Boilerplate quiere orientar a las personas hacia las mejores prácticas, sería una pena dejar de lado a AMD. Resuelve con elegancia muchos de los problemas de JavaScript.

Para ser claro. Estoy de acuerdo. Desearía que usaran require todo el camino.

Simplemente no creo que lo hagan.

No creo que la gente se dé cuenta todavía de que AMD es una palabra de moda, una "cosa" que todo desarrollador serio necesita saber. Una vez que lo hagan, querrán decirle a sus jefes y futuras entrevistas que lo saben y lo usan.

Si todos hacemos nuestra parte y decimos "mira, es fácil, mejor e importante" y lo convertimos en una palabra de moda, los rebaños los seguirán por el bien de sus carreras.

@ jashkenas--

La primera es si las etiquetas de secuencia de comandos en el marcado pueden ser tan buenas (o mejores) que los elementos de secuencia de comandos dinámicos utilizados en un cargador de secuencias de comandos paralelo.

Estamos completamente de acuerdo sobre este tema, no importa.

En realidad, comencé mi participación en este hilo asumiendo que todos estaban de acuerdo en que la carga dinámica de elementos de script conduciría a un mejor rendimiento que las etiquetas de script. Pero tanto @paulirish como @slexaxton han cuestionado esa suposición en _este_ hilo.

@paulirish ha sugerido que defer es una forma suficiente de hacer que la etiqueta de script simple sea tan buena (o mejor) que la alternativa de carga de elementos de script dinámico. No estoy de acuerdo con que defer sea ​​suficiente, y ahora he establecido varias razones.

Entonces, creo que ES válido que hayamos examinado la primera pregunta y explorado si defer era mejor que los cargadores de scripts. Puede haber algunos casos limitados en los que puede salirse con la suya con defer , pero en lo que respecta al caso generalizado, los cargadores de scripts manejan / normalizan todas las peculiaridades, mientras que defer expone a esos problemas.

Todavía no estoy seguro de que todos vean o estén de acuerdo con por qué defer no es suficiente.

Para repetirme, aquí hay un caso de prueba (justo). Los mismos 5 scripts del mundo real, cargándose en una página de tamaño mediano con otros activos presentes, uno usa las mejores prácticas de LABj para asegurar el orden de carga y el otro usa un único script concatenado:

Esta es su premisa de prueba falsa (y la de otros). Nunca jamás dije que cargar 5 scripts en lugar de 1 iba a ser más rápido. Nunca. Siempre. ¿Puedo ser más claro? La premisa nunca ha sido 5 contra 1.

La primera prueba fue probar 3 etiquetas de script frente a 3 llamadas script() , porque es una prueba justa. Y creo que el video y las pruebas ilustran que la carga del script, en ESE escenario, es beneficiosa.

La segunda pregunta, y mucho más compleja de probar, es si hay alguna forma de mejorar el rendimiento de un sitio que ya está cargando todo su JS en un solo archivo. La mayoría de la gente dice que es imposible mejorar eso. Estoy en desacuerdo.

NOTA: la razón por la que esta pregunta es ortogonal es que puede cargar este único archivo concat ya sea con una etiqueta de script o usando la carga dinámica de tipo document.createElement("script") . De cualquier manera, la cuestión de un solo archivo concat es una pregunta válida, pero separada de si las etiquetas de script o la carga dinámica de script son mejores.

Lo que me han escuchado decir varias veces en este hilo, y también en muchos otros contextos (incluidas todas mis conferencias sobre el tema, publicaciones de blog, etc.), es que creo que es posible que pueda mejorar el archivo JS único concat. enfoque "fragmentando" (es decir, dividiendo el archivo concat grande) en 2 o 3 fragmentos (como máximo). Si los fragmentos son de ~ el mismo tamaño y se cargan en paralelo, entonces es posible que la página se cargue más rápido, incluso con la sobrecarga HTTP adicional, debido a la conexión "Keep-Alive", el efecto de carga en paralelo, etc.

De hecho, escribí sobre este tema hace MUCHO tiempo, en noviembre de 2009, poco después del primer lanzamiento de LABjs: http://blog.getify.com/2009/11/labjs-why-not-just-concat/

En esa publicación de blog, y desde entonces, he dicho que SI estás en una posición (no todos lo están ... de hecho, la mayor parte de la web no lo está) para usar procesos de compilación para concat, deberías hacerlo asi que. Período. Siempre. Siempre concat archivos desde 10-20 archivos locales hasta muchos menos.

PERO, también digo que una vez que tenga ese único archivo concat, también podría ser beneficioso intentar cargar su único archivo en 2-3 fragmentos, cargados en paralelo (usando un cargador de scripts).

¿Por qué esto podría ser mejor? Lo delineé en esa publicación del blog, pero en resumen:

  1. El efecto de carga paralela es real. pregunte a los usuarios de bit-torrent sobre esto. la sobrecarga de HTTP también es real y actúa para contrarrestar y eliminar ese beneficio. Pero no significa que sea imposible beneficiarse. Usando la conexión Keep-Alive, es posible que pueda obtener 2 o 3 conexiones simultáneas (sin 2-3 penalizaciones por sobrecarga de conexión completa) y cargar su código en un período de tiempo más corto. ¿Será 1/3 del tiempo (60-70% más rápido) si lo carga en 3 partes? No absolutamente no. Pero puede ser un 20-30% más rápido.
  2. Servir todo su código en un solo archivo le impide hacer diferentes encabezados de caché para diferentes códigos de por vida. Por ejemplo, jquery es muy estable y nunca es necesario volver a descargarlo. pero su código centrado en UX en su sitio puede ser muy volátil (puede modificarlo una vez por semana o más). Hacer pequeños encabezados de almacenamiento en caché en un único archivo concat es una estupidez, porque obliga a realizar descargas más frecuentes de código estable innecesariamente. Hacer largos encabezados de almacenamiento en caché en un solo archivo concat también es estúpido, porque lo obliga a invalidar el archivo en caché (parámetro de busto de caché, etc.) y forzar una nueva descarga completa de todo el archivo, cuando solo modifica un solo byte de su código más volátil. Por lo tanto, dividir su archivo concat grande en 2 partes, una para el código estable y otra para el código volátil, le permite tener diferentes encabezados de almacenamiento en caché para cada parte. Esto hace un uso más efectivo de la caché y conduce a un rendimiento potencialmente mejor durante períodos de tiempo, a medida que los usuarios visitan su sitio repetidamente.
  3. Los estudios han demostrado que, en promedio, una sola vista de página usa mucho menos del 100% del JS que se carga en la página (algunas estimaciones lo sitúan alrededor del 20-30% del código). Cargar todo su código de una sola vez, todo a la vez, al comienzo de la carga de la página, congestiona la línea innecesariamente para empujar el 70-80% del archivo que no se necesita en ese momento (y puede que "nunca" sea necesario). Si tiene su código en 2 fragmentos (uno que es el código más crítico y otro que es el código menos crítico), y carga el primer fragmento de inmediato y carga el segundo fragmento unos segundos después de la carga de la página, puede liberar la tubería para las imágenes / css y el contenido mucho más importantes. En esencia, la fragmentación le permite priorizar su código.

En pocas palabras ... sobre el tema de concat vs. paralelo ... Yo _siempre_ le digo a la gente: ambos.

@getify bien dicho.

LABjs de Kyle tiene mi apoyo.
Como consultor que ayuda a los sitios a mejorar el rendimiento, he visto que los LABj funcionan bien muchas veces.
No solo mejoró el rendimiento de manera significativa (no solo 100 ms, sino más de 1 segundo), sino que también les gustó a los desarrolladores.
Fácil de entender, fácil de implementar.

Y aprovecharé esta oportunidad para decir públicamente "Gracias Kyle, por el gran apoyo en LABjs. Has superado mis expectativas varias veces".

Usando la conexión Keep-Alive, es posible que pueda obtener 2 o 3 conexiones simultáneas (sin 2-3 penalizaciones por sobrecarga de conexión completa)

HTTP no mezcla / intercala respuestas, por lo que no puede tener descargas paralelas sin abrir varias conexiones primero. El caso ideal de conexión persistente y canalizada es igual a la descarga contigua de un solo archivo (+ algunos encabezados).

@ pornel--

He visto de primera mano y validado que los navegadores pueden abrir múltiples conexiones en paralelo a un solo servidor, donde con Connection Keep-Alive en juego, la sobrecarga para la segunda y tercera conexiones es drásticamente menor que para la primera. Ese es el efecto del que estoy hablando.

@getify Fantastic, creo que hemos llegado a algún tipo de consenso. Para refrescar tu memoria:

Puedo anticipar un contraargumento sobre la carga de sus scripts en partes y piezas ...
pero eso es completamente ortogonal a la técnica de carga del script, así que déjelo fuera
de la discusión.

Sí, estoy de acuerdo en que cargar sus scripts volátiles en un archivo JS diferente al de sus scripts permanentes es genial. Cargar el script que solo es necesario para una página específica, solo en esa página específica, es igualmente genial.

Entonces, si soy un desarrollador web y tengo una página con un montón de JavaScripts, ¿qué debo hacer? Use LABjs o concatene mis scripts permanentes en un archivo y mis scripts volátiles en otro, y cargue ambos en la parte inferior de la etiqueta del cuerpo con <script defer="true"> ?

¿Por qué debería someter mi aplicación a problemas de almacenamiento en caché, incompatibilidades del navegador, carrera contra las imágenes en la página y el resto de los problemas que trae consigo un cargador de scripts?

Si toda la premisa de usar un cargador de secuencias de comandos para el rendimiento es que es más fácil y simple que usar dos etiquetas de secuencia de comandos ... Tengo un puente en Brooklyn para venderle.

@getify haber implementado un servidor web más de una vez: keep-alive no afecta las solicitudes concurrentes de ninguna manera y solo reduce los costos de las solicitudes posteriores. Un cuerpo dividido con dos solicitudes posteriores con Keep-Alive sigue siendo más caro que una sola solicitud. Tener dos solicitudes simultáneas para las dos partes del cuerpo probablemente funcionará mejor, pero tenga en cuenta que el navegador solo abrirá un número limitado de solicitudes simultáneas (según el navegador y la configuración, algo alrededor de 5, creo), lo cual está bien si todo lo que hace es cargar sus tres archivos js, pero es, como @jashkenas señaló más de una vez, un problema si tiene otros activos, como imágenes o archivos css.

@ jashkenas-

Entonces, si soy un desarrollador web y tengo una página con un montón de JavaScripts, ¿qué debo hacer? Use LABjs o concatene mis scripts permanentes en un archivo y mis scripts volátiles en otro, y cargue ambos en la parte inferior de la etiqueta del cuerpo con <script defer = "true">?

TL; DR: ambos

En primer lugar, muchos sitios en la web son ensamblados por CMS, lo que significa que tener bloques de scripts en línea esparcidos por toda la página es común y MUY difícil de resolver en cuanto al mantenimiento con solo decir "mover todo ese código a un archivo". Por lo tanto, creo que la premisa de que la mayoría de los sitios pueden escapar sin tener ningún "código en línea" para ejecutar después de que se cargue y ejecute otro script externo es poco probable, en el mejor de los casos.

En segundo lugar, he demostrado que defer actúa de manera diferente con respecto a DOMContentLoaded en varios navegadores. En algunos navegadores, las secuencias de comandos van antes que DOM-ready, en otros navegadores, van después de DOM-ready. Si tiene un código en sus scripts que depende de que suceda antes o después de que esté listo para DOM, usar defer puede ser un problema. Es especialmente cierto que es un área sensible con muchos malentendidos y confusión, por lo que rápidamente se convierte en "esta no es una solución sencilla y sencilla". Se necesita pensar mucho más.

En tercer lugar, creo que para muchos sitios, cambiar su marcado para usar $LAB.script() lugar de &lt;script> es mucho más fácil que explicarles cómo instalar algún proceso bulid automatizado (o manual) en su servidor. Especialmente si ese sitio está en alojamiento compartido (la mayor parte de la web lo está), y realmente no controlan gran parte de su servidor, pedirles que averigüen los procesos de compilación para que el mantenimiento de su código no se pierda es ... bueno. .. no trivial.

¿Se pueden superar estas cosas? Sí. Por supuesto que pueden. Pero requieren mucho trabajo. En algunos casos (como en el caso de que esté listo para DOM), es posible que requieran un ajuste minucioso de su código. Se necesita una persona con esfuerzos dedicados y mucha experiencia y pasión en esta área para resolverlo todo.

Por el contrario, pueden obtener una "ganancia rápida" en LABjs en lugar de la etiqueta &lt;script> . Hay poco en lo que tienen que pensar (excepto document.write() ). La mayoría de las veces, "simplemente funciona". Y la mayoría de las veces, ven un aumento inmediato de la velocidad en la carga de la página. Para la mayoría de los sitios, eso es una gran victoria.

Entonces, para responder a su pregunta, diría, como dije antes, haga ambas cosas ... Primero use LABjs, vea algunos aumentos inmediatos de velocidad. Ahora, considere seriamente los beneficios de usar un proceso de compilación para moverlo de 15 archivos a 2 archivos (1 archivo fragmentado por la mitad). Cuando haga eso (si lo hace, que como dije, la mayoría no lo hará), puede deshacerse de los LABj si realmente lo desea. Pero no hay ningún daño real (es pequeño y se almacena bien en caché, incluso en dispositivos móviles). Continuará cargando bien sus dos fragmentos de archivo, Y lo hará sin las peculiaridades que podría causar defer .

Además, tener LABjs ya allí hace que sea estúpidamente simple para usted hacer el paso 3, que es comenzar a averiguar qué código puede "cargar de forma diferida / bajo demanda" más tarde. No puede hacer eso sin un cargador de scripts. Tener LABjs ya ahí y familiar significa que no tiene que preocuparse por cómo cargar ese script bajo demanda en absoluto, ya está resuelto.

@ rkh--

Me había demostrado (específicamente en Apache, con alternar la configuración Keep-Alive) cómo se vieron afectadas múltiples solicitudes paralelas (positivamente cuando Keep-Alive estaba allí). No soy un experto en esta área, por lo que discutir los detalles exactos de cómo funciona o no está fuera de mi alcance. Puedo decir que el momento de la solicitud n. ° 2 fue menor que el momento de la solicitud n. ° 1, cuando Keep-Alive estaba allí. Cómo el navegador y el servidor hicieron eso, solo puedo hacer conjeturas parcialmente informadas.

Un cuerpo dividido con dos solicitudes posteriores con Keep-Alive sigue siendo más caro que una sola solicitud.

Nunca he argumentado que la segunda solicitud sea gratuita. Argumenté que la segunda solicitud no es tan cara como la primera. Entonces, si asumimos que se debe realizar al menos una solicitud, tener una segunda solicitud en paralelo NO es lo mismo que tener dos conexiones completamente independientes al mismo servidor, en términos de costos generales o de tiempo.

A modo de estimación, parecía que la Solicitud n. ° 1 era X para el servicio y la n. ° 2 en paralelo con Keep-Alive presente era 0,7X. Se me explicó que el servidor pudo utilizar parte de la sobrecarga de conexión existente para atender la segunda solicitud, lo que la hizo un poco más barata. Con Keep-Alive desactivado, la segunda solicitud no tuvo tal disminución medible.


Sin embargo, toda esta discusión es una madriguera muy profunda. No soy un experto en servidores. No tengo por qué serlo. Solo puedo explicar que realmente he visto (y creado pruebas) en torno a este tema exacto ... ¿puedo probar ese tiempo de carga de un solo archivo de 100k frente a cargar dos mitades de ese mismo archivo en paralelo, y la segunda prueba será medible? cantidad más rápido. Como dije, vi, entre un 15 y un 25% más rápido con la prueba fragmentada en paralelo. Cómo lo hizo, y se las arregló para superar de alguna manera el terrible efecto "OMG HTTP RESPONSE OVERHEAD IS TERRIBLE" y aún así beneficiarse de dos cargas paralelas, creo que no estoy calificado para demostrarlo científicamente. Pero definitivamente lo hizo por observación.

Cristo, ustedes escriben rápido. Termino de leer, recargo la página y hay como nueve comentarios más.

Necesito ayuda. Intenté precisar exactamente en qué parte de este hilo pasamos de discutir _qué funciona mejor para un archivo HTML repetitivo_ a discutir _si los cargadores de scripts son, en todos los casos, aceite de serpiente_.

@getify , ciertamente deberías defender LABjs y responder a críticas específicas hechas por otros en el hilo, pero (excepto @jashkenas) creo que aquellos que critican LABjs lo están haciendo para demostrar que no es la mejor solución para una repetición. Usted argumenta que es más fácil convertir páginas heredadas a LABjs que a script[defer] , y eso podría ser cierto, pero ¿cómo se aplica eso a un archivo HTML repetitivo (que, por definición, comienza desde cero)?

Dice que está diseñado para personas que no tienen procesos de compilación sofisticados, pero también parece abogar por la concatenación, la división en partes del mismo tamaño y la carga en paralelo. ¿No es esa una tarea para un script de compilación? Una vez más, parece una elección incorrecta para un modelo estándar diseñado para ofrecer al usuario valores predeterminados inteligentes. Si un usuario desea ese supuesto aumento de velocidad del 20-30%, puede optar por actualizar más tarde lo que ofrece el modelo estándar, pero esa no es una tarea trivial.

Habiendo dicho todo eso, si quieren continuar con el tema general ("Cargadores de guiones: ¿herramienta valiosa o aceite de serpiente?"), Estaré feliz y haré palomitas de maíz.

@getify : Estoy de acuerdo en que la segunda y la tercera conexiones podrían abrirse más rápido que la primera: la primera espera el DNS y posiblemente el enrutamiento del primer paquete al servidor es un poco más lento que enrutar el resto a lo largo de la misma ruta. En HTTPS, la caché de sesión SSL ayuda mucho a las conexiones posteriores.

Sin embargo, no veo la relevancia de Keep-Alive en esta situación. Las _requests_ subsiguientes en la misma conexión se inician más rápido con Keep-Alive, pero esas solicitudes son en serie dentro de la conexión.

Estoy a punto de terminar aquí - acabo de llegar a mi momento "loco como el infierno y no voy a soportarlo más" con respecto a los cargadores de scripts.

Dicho esto, creo que este hilo, para un festival de llamas, en realidad ha sido bastante productivo. Si LABjs quiere reclamar los sitios web desafortunados e incompetentes, y dejar a las personas que realmente quieren que sus sitios se carguen rápidamente solos, es un gran paso adelante.

escalofrío amigo

@ savetheclocktower--

Preguntas justas.

No comencé mi participación en este hilo defendiendo fuertemente que LABjs (o cualquier cargador de scripts) se incluyera en h5bp. Creo que es útil (ver más abajo), pero no me preocupaba mucho que estuviera perdiendo el sueño. Claramente, este hilo se ha transformado en un ataque total a todo lo que es "carga de script". Eso es, obviamente, algo que me importa un poco más.

Dice que está diseñado para personas que no tienen procesos de compilación sofisticados, pero también parece abogar por la concatenación, la división en partes del mismo tamaño y la carga en paralelo. ¿No es esa una tarea para un script de compilación?

En primer lugar, recomiendo mover todas sus docenas de etiquetas de script a un cargador de script paralelo como LABjs. Esto no requiere más que la capacidad de ajustar su marcado. Ese es un paso mucho más fácil / menos intimidante que decirle a un sitio familiar que use un sistema de compilación automatizado basado en node.js, por ejemplo.

Y para aquellos que PUEDEN hacer compilaciones de sus archivos, defiendo que LABjs todavía tiene beneficios, porque puede ayudarlo a cargar esos fragmentos en paralelo. Si no está de acuerdo con que los fragmentos sean útiles de alguna manera, entonces no verá ninguna razón para usar LABjs por encima de defer . Pero si puede ver por qué fragmentar _puede ser_ útil, debería deducirse que un cargador de scripts _ también puede ayudar_ en ese proceso.

Una vez más, parece una elección incorrecta para un modelo estándar diseñado para ofrecer al usuario valores predeterminados inteligentes.

La única razón por la que creo que un cargador de scripts (específicamente uno que está diseñado, como LABjs, para tener un mapeo uno a uno entre las etiquetas de script y las llamadas script() ) tiene un beneficio en un texto estándar es que en un texto estándar , a menudo ves una instancia de algo (como una etiqueta), y tu tendencia al construir tu página es simplemente copiar y pegar el duplicado tantas veces como lo necesites. Por lo tanto, si tiene un patrón de bajo rendimiento (etiqueta de secuencia de comandos) en el modelo estándar, la tendencia de las personas será duplicar la etiqueta de secuencia de comandos una docena de veces. Creo que, en promedio, si en su lugar duplicaron la llamada $LAB.script() varias veces, existe una posibilidad decente de que su rendimiento no sea tan malo como hubiera sido.

Esa es la única razón por la que comencé a participar en este hilo. Es la única razón por la que discrepé con el @paulirish MUY arriba aquí en el hilo.

Taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah


Creo que está claro que esta discusión ha avanzado mucho más allá de si un cargador de scripts es apropiado para el proyecto h5bp. Pero eso es bueno, ya que vale la pena explorar este tema.


Independientemente, estoy muy interesado en casos de prueba reproducibles junto con los resultados de las pruebas.

También parece que la especificación de @defer se escribió para proteger algunos de los comportamientos erráticos que los navegadores ofrecen junto con ella. Ese comportamiento debe documentarse. Puedo ayudar a migrarlo al MDC cuando esté listo.

Necesitamos documentación directa sobre estos comportamientos que capture todos los navegadores, diferentes tipos de conexión y efectos de red. No estoy seguro de si una plataforma de prueba debería usar cuzillion o assetrace, pero eso se puede determinar.

Configuré un ticket para generar interés en https://github.com/paulirish/lazyweb-requests/issues/42

Únase a mí allí si está en las tareas _superfun_ de investigación webperf y documentación de evidencia.

Consideremos este hilo cerrado, señores.

La carga diferida no es el beneficio principal de los módulos AMD como @jrburke en sus comentarios. La razón principal por la que elijo usar módulos AMD tanto como pueda es porque mejora la estructura del código. Mantiene los archivos de origen pequeños y concisos, más fáciles de desarrollar y mantener, de la misma manera que usar css @import durante el desarrollo y ejecutar una compilación automatizada para combinar hojas de estilo también se recomienda para proyectos grandes ...

Siento que esta publicación que escribí el año pasado encaja con el tema: El dogma del desempeño : no se trata solo del desempeño y asegúrese de que no está perdiendo el tiempo "optimizando" algo que no hace ninguna diferencia _real_ ...

Y estoy con @SlexAxton , quiero AMD, pero las etiquetas de script simples probablemente sean suficientes para la mayoría de las personas. Tal vez un enfoque válido sería agregar una nueva configuración para elegir el proyecto AMD y ejecutar el optimizador RequireJS en lugar de las tareas _concat_ (

Consideremos este hilo cerrado, señores.

@paulirish ¿Qué tal si se incluye la compatibilidad con AMD? ¿Dónde deberíamos discutir eso?

@benatkin abre un nuevo boleto hermano.

@paulirish OK, gracias. @jrburke , ¿podría abrir un nuevo ticket para continuar la discusión que inició? Creo que agregaré un comentario, pero no creo que pueda presentar un caso para el soporte de AMD tan bien como usted puede.

Entretenido e informativo. Gracias chicos.

Creo que alguien necesita iniciar un nuevo proyecto de cargador de scripts y lo llamó "Issue28". :)

Para una compatibilidad más amplia, se puede obtener un rendimiento rápido colocando el script en la parte inferior, minify, gzip, pero sin aplazar. Al menos no hasta que la compatibilidad del navegador sea constante durante algunos años seguidos.

Los cuellos de botella pueden provenir de anuncios, demasiado javascript, HTML inflado, demasiado CSS, demasiados iframes, demasiadas solicitudes, latencia del servidor, javascript ineficiente. Las aplicaciones que usan una gran cantidad de bibliotecas de terceros tienen problemas causados ​​no solo por demasiado javascript, sino más que eso, tienden a tener muchos otros problemas, principalmente HTML inflado, HTML inválido, demasiado CSS y javascript ineficiente. Twitter viene a la mente, con dos versiones de jQuery y dos controladores de desplazamiento que provocan un rebote en el desplazamiento de la columna derecha.

El truco es que si sabe lo que está haciendo, puede evitar esos problemas. No necesita cosas como jQuery o subrayado, por lo que sus scripts son mucho más pequeños. Escribe HTML y CSS limpio, simple y válido. En consecuencia, sus páginas se cargan más rápido, la aplicación es más flexible en términos de cambio y el SEO mejora. Entonces, el uso de un cargador de scripts solo agrega complejidad y gastos generales injustificados.

https://github.com/BroDotJS/AssetRage

¡AUGE! Cierro los palos y cierro los hilos.

Qué hilo ... wow.

Imo, la discusión comenzó en el contexto de h5bp, que pretende ser un punto de partida para los desarrolladores web.
Como tal, puede afirmar que el webdev que usa h5bp realmente tendrá HTML limpio, CSS limpio, un buen .htaccess, etc. y _ tal vez_ ni siquiera _no_ sufra de demasiadas imágenes, JS ineficaz, muchos JS de terceros de mierda, etc. porque el desarrollador web elige usar h5bp de alto rendimiento y por eso está preocupado por el rendimiento, y prestará atención a las cosas que no son de h5bp y que van a la (s) página (s).

A partir del hilo, y en este contexto, creo que lamentablemente no hay pruebas suficientes para sacar una conclusión final.
Estoy con Paul para poner en marcha la investigación y documentar lo que se necesita documentar.
Cuéntame en Paul.

Nota al margen. No estoy muy familiarizado con AMD y, a primera vista, me parece intimidante, o al menos no es algo que pueda captar con mucha facilidad. Creo que la mayoría de los desarrolladores web "normales" estarán de acuerdo.
El material que ve en h5bp debe tener una barrera de entrada baja, o no se utilizará y la absorción de h5bp puede ser más lenta de lo que podría ser sin él.
Dudo que algo como AMD pertenezca al h5bp.
Mantenlo simple.

Y otro comentario ....
'Poner scripts en la parte inferior' y 'Concatenar archivos JS en un solo archivo' ha ocupado un lugar destacado en la lista de mejores prácticas de rendimiento web durante muchos años. Entonces, ¿por qué> 90% de los sitios promedio, creados por desarrolladores internos y por las principales agencias de marcas, todavía tienen múltiples etiquetas de script en HEAD? ¿Enserio? Qué es eso?

Y el otro 9% tiene un solo archivo JS concatenado ... en HEAD.
Rara vez veo un sitio "normal" que _no_ está construido por algún desarrollador de rendimiento web superior con un script en la parte inferior.

Los desarrolladores siguen construyendo sitios como lo han hecho durante años.
Los propietarios de sitios se preocupan más por el diseño y las características, por lo que los desarrolladores dedican su tiempo a eso.

Cambiar una forma de trabajar, un sistema de construcción, el código ... tiene que ser fácil, muy fácil o de lo contrario no sucederá.

He trabajado en muchos sitios donde combinar JS en HEAD en un solo archivo y cargarlo en la parte inferior de BODY rompió las páginas del sitio. ¿Y entonces que? En la mayoría de los casos, no es solo una hora de trabajo solucionarlo. Es necesario realizar una refactorización seria ... y esto no ocurre por falta de conocimiento y, sobre todo, por falta de tiempo.

(oh cierto, el hilo está cerrado ...)

Estamos hablando de una biblioteca construida sobre jQuery y Modernizr. Lo dice todo, de verdad. ¿Quién usa eso? Oh, mierda, lo olvido, Twitter.com, que usa dos jQuerys y también tiene en el código fuente lo siguiente:

 Línea 352, columna 6: div de etiqueta final visto, pero había elementos abiertos.
 Línea de error 350, columna 6: elemento sin cerrar ul.
 Línea de error 330, columna 6: elemento sin cerrar ul.

Y el problema de esperar que el navegador corrija los errores es que HTML4 no definió los mecanismos de corrección de errores y, por lo tanto, terminará con un quién sabe qué quién sabe dónde. Claro, HTML5 define el manejo de errores, pero no es retroactivo; todavía hay muchos navegadores "antiguos" por ahí.

Y hablando de mierda, ¿alguien aquí echó un vistazo a las cuñas jQuery ES5?

Por cierto, ¿tienes algo que agregar a esa declaración tuya de "que el webdev que usa h5bp tendrá HTML limpio", aaronpeters?

@GarrettS ok, ok, debería haber escrito "tendré _probably_ HTML limpio"

:-D ¡siempre podemos esperar!

Venciendo a un caballo muerto, lo sé ... pero resulta que al mismo tiempo que estábamos teniendo esta brillante discusión, la versión actual de LABjs en realidad tenía un error que causaba que JavaScript se ejecutara en el orden incorrecto en algunos navegadores: https: //github.com/getify/LABjs/issues/36

Oh, la ironía.

debe. resistir. destino. totalmente. [inapropiado. imagen. por. anterior. declaración .... aggggh! ¡AGONÍA!

Mi parte favorita fue cuando el tipo que hizo dhtmlkitchen.com (actualmente totalmente arruinado ) comenzó a hablar sobre errores de marcado.

Ese sitio ha sido cedido a Paulo Fragomeni. Sí, lo logré y estoy orgulloso de lo que escribí allí, como aquí. Ve a tomar una captura de pantalla de tu avatar débil, idiota.

... y después de que hayas terminado con eso, trata de sacar tu cabeza de tu trasero y entender la diferencia entre mi antiguo sitio web personal (que ya no es mantenido por mí) y uno que es desarrollado por un equipo y financiado por una empresa rentable de varios millones de dólares (aunque Twitter puede valer miles de millones AFAIK).

Me alegro de que sigamos manteniendo esta clase y _en el tema_, chicos.

jashkenas obtuvo la información relevante al principio de esta discusión.

Pero luego hubo una reacción violenta. ¡No! ¡No debe ser así! ¡Souders dijo que lo hiciera! Y estaba el mal consejo de usar diferir, sin importar cómo falla cuando falla.

Y luego, irónicamente, de la nada, surgió la afirmación de que los usuarios de h5bp estarían haciendo las cosas correctamente. Y esto es muy irónico porque este comentario vino _después_ de los comentarios de sus partidarios que evidentemente producen un marcado inválido y usan una carga de capas de abstracción de terceros (y horribles). Y después del comentario sobre el uso de diferir.

Entonces, ¿qué tiene todo esto que ver con que dhtmlkitchen.com esté inactivo? Nada de nada, obviamente. Eso fue solo un golpe débil de un bifurcador de h5bp que no puede soportar escuchar críticas.

Bros.
Tipo.
Bros.

Este hilo está cerrado. ¿Recordar? No tienes que ir a casa, pero no puedes incendiarte aquí.

Oigan, ¿recuerdan esa vez cuando hicimos un hilo épico en el que hubo múltiples debates, guerras personales, gente enojada por todos lados, una imagen obscena o dos, y un buen momento en general? No puedo creer que fuera gratis. Deberíamos hacerlo de nuevo en algún momento.

¿Fue útil esta página
0 / 5 - 0 calificaciones