2012-10-02 11 views
6

Pregunta 1:¿Por qué necesito cargar el módulo de JavaScript y cuál es la diferencia entre todos estos cargadores?

¿Por qué necesito para cargar asynchrously mis archivos JavaScript en una página web? Puedo ver la razón de esto en el lado del servidor, pero si conozco todos los archivos que necesito cargar en el cliente, ¿por qué no debería concatenar todos mis archivos fuente en 1 archivo y cargar eso en la página cargada? ¿Es la primera carga de la página inicial tan importante que las operaciones futuras pueden ralentizarse debido a la latencia al recuperar cada archivo JS?

Pregunta 2:

Suponiendo que la respuesta a la pregunta 1 es que necesito para cargar archivos JS separado:

AMD cargas cada archivo JS asynchrously, cargas CommonJS forma sincrónica. Se requiere CJS para la carga del servidor (así es como funciona Node.js, si no me equivoco). AMD parece ser una mejor opción para el cliente. Por lo tanto, la única razón para usar CJS en el cliente es compartir el código con el servidor.

¿Hay alguna manera de hacer que AMD y CJS jueguen bien, para que los archivos JS del cliente se puedan cargar de forma asíncrona pero que aún tengan sintaxis CJS?

(¿Qué hace exactamente require.js hacer? No puedo por la vida de mí leer entre líneas en su página web.)

Respuesta

3

No "necesidad" para cargar los archivos de Javascript de forma asíncrona o por medio de algún cargador personalizado. Aquí hay algunas razones cuando asíncrono de carga o la costumbre de carga podría proporcionar un beneficio:

  • Cuando el archivo JavaScript normalmente no es necesario y es posible que desee cargar en la demanda en lugar de todo el tiempo
  • Cuando el archivo JavaScript no es necesario para la visualización de la página inicial y desea maximizar la velocidad de la primera pantalla para su página
  • Cuando desea controlar la sincronización de exactamente cuándo se carga el archivo javascript
  • Cuando está decidiendo, en función de alguna condición , ya sea para cargar el archivo JavaScript o no (por ejemplo, si la carga desde un CDN falló, carga de lucha desde una ubicación de copia de seguridad)
  • Cuando se desea proceder a la carga de la escritura en paralelo con otras cosas en lugar de uno tras otro en serie

Si usted no necesita cualquiera de estos beneficios o algún otro beneficio proporcionados por carga programática, entonces puede usar las etiquetas normales <script> y dejarlas cargar sincrónicamente.

+0

¿Sigue siendo así? –

+0

@JitendraVyas - Sí, es casi todo cierto. Los navegadores ahora tienen los atributos 'defer' y' async' para la etiqueta del script (sobre la que puedes leer [aquí] (http://stackoverflow.com/questions/10808109/script-tag-async-defer/10808243#10808243)) que le dan cierto control sobre el tiempo de una simple etiqueta de script sin usar un cargador, pero todavía hay casos para todos los anteriores que usan un cargador. – jfriend00

3

Parte del problema con la concatenación del archivo no es el tiempo de descarga, sino el tiempo dedicado a la compilación en cada página.

Si tiene un archivo de 20,000 líneas, y solo necesita 600 de esas líneas para poner todo en funcionamiento (asumiendo que todo está escrito para ser modular y asincrónico, usando cualquier patrón para administrar los recursos) , entonces usted se ahorrará lo que podría ser medio segundo o más, si sirve el programa principal y se extiende según sea necesario (o en un temporizador retrasado, sirviendo porciones grandes de funcionalidad que están estrechamente relacionadas entre sí).

El tiempo total dedicado a la descarga es mayor.
El número total de conexiones HTTP utilizadas es mayor.
Pero el tiempo requerido para hacer que la página sea visible para el usuario es menor.
El tiempo requerido para agregar funcionalidad básica a la página es menor.
Luego se puede transmitir una funcionalidad adicional, ya sea después de la carga e inicialización, o justo a tiempo, según lo solicitado por el usuario, y en ambos casos, siempre que el código que ha transmitido esté enfocado en hacer una cosa, y no es una media docena de otras dependencias, el tiempo entre la solicitud y la adición de la funcionalidad será mínimo.

RequireJS utiliza un sistema de promesa, básicamente.

Le permite declarar las dependencias por adelantado, y entregar el código (como una devolución de llamada) para ser implementado, después de que se hayan manejado todas sus dependencias.
Si esas dependencias tienen alguna dependencia, entonces ellos no se inicializarán hasta que se carguen sus dependencias.
Si solo quiere que se cargue y el orden no es importante, entonces no necesita darle dependencias.

La moraleja general es que si tienes un sistema donde todos tus archivos son pequeños, el peso total de JS en la página es muy pequeño, solo necesitas unos cientos de líneas para hacer todo lo que deseas en el página ... ... además, ya sabes dónde están todas tus dependencias, tienes un sistema en el servidor para asegurarte de que están en el orden correcto, etcétera (además de que tienes una gran documentación, o estás eres el único que toca este código, y vives dentro de él, día a día) ... ... entonces no hay nada malo en hacer lo que estás haciendo.

Es posible que no vea ninguna diferencia, si el tiempo de compilación se ve superado por la cantidad de solicitudes HTTP que realiza. Pero para aplicaciones generales que tienen decenas (o cientos) de miles de líneas de longitud, donde solo se necesita una fracción de esa funcionalidad en una página, puede haber grandes ahorros en términos de tiempo percibido entre cuando carga la página y cuándo la aplicación está "lista" para la interacción básica del usuario.

3

Si desea cargar toda su fuente de JavaScript para cada página, seguro, compílela en un solo archivo. Si carga un código diferente en función de las acciones que realiza el usuario o de la página cargada, utilice módulos cargados de AMD. La otra alternativa sería incluir una lista de etiquetas de script, que por supuesto solo se cargarían de una en una y podrían demorar un tiempo.

AMD no es una biblioteca específica, en realidad es un estándar para cargar módulos de JavaScript que utilizan la mayoría de los cargadores que mencionó. Esto significa que todos usan una sintaxis similar para definir y cargar módulos. Están considerando hacer AMD parte de la especificación de script ECMA. La utilidad de esto es que también puede definir dependencias, de modo que si su código requiere la ejecución de jQuery, puede listarlo como una dependencia y se cargará en el espacio de nombres de su módulo.

define([ 'jquery' ], function ($) { 
    // use jquery in here without clouding up the global namespace 

    return {}; // return your module for use in a different module or whatever 
}; 

En este ejemplo, el código en el módulo definido no se ejecutará hasta que el módulo de jQuery se ha descargado. A continuación, inyectará el módulo jquery directamente en su módulo recién definido como argumento $.

Ahora puede mantener su código prolijamente organizado en archivos que contienen módulos. Ninguno de sus módulos se nublará el espacio de nombres global. Es probable que todas sus dependencias se hayan cargado antes de que se ejecute su módulo (no se cargan errores de condición de carrera para piezas dependientes de código).

Otra ventaja es que puede configurar su cargador para utilizar diferentes rutas para el mismo módulo, por lo que puede definir la ruta para que el módulo jquery sea 'https://ajax.googleapis.com/ajax/libs/jquery /1.8.2/jquery.min.js 'en un punto de tu código aunque se pueda usar en casi todos los módulos. Ahora, cuando necesito actualizar mi versión de jquery a la 1.8.3, puedo simplemente cambiar la ruta en un punto de mi código, y usará esta ruta para cada módulo que use jquery como dependencia. Esto también puede ser útil para una fácil conmutación cuando se prueba cuando se utilizan resguardos de módulos o versiones de depuración de ciertos módulos.

Ahora esto no es necesariamente necesario para proyectos pequeños. Sin embargo, cuanto más grande sea tu proyecto, más sentido tiene comenzar este tipo de carga.

Cuestiones relacionadas