Mover todos los Javascript incluidos a antes </body>

35

¿Alguien sabe cómo tener todas las etiquetas de script JS de Magento, por ejemplo, <script type="text/javascript" src="http://sitename.com/js/prototype/prototype.js"></script>renderizar antes del cierre </body>?

He intentado esto una vez antes, pero recibí un error que creo que estaba en la línea del método addJS que no estaba disponible donde lo usé, posiblemente en el pie de página de referencia.

Mark Weston
fuente
44
Tome la recomendación de GTMetix y YSlow con una pizca de sal. El tiempo que invierta invirtiendo en esto no generará un aumento notable en el rendimiento y, casi con certeza, sería mejor dedicarle un perfil a su código (eliminar la grasa) o simplemente encontrar un host mejor / más rápido.
Ben Lessani - Sonassi
1
@sonassi Si bien es un punto válido, tomar media hora para implementar la respuesta de JMax no dañará nada y es parte de una selección de mejoras de rendimiento de front-end que se pueden incluir en un tema base.
Glo
1
@Glo Todos estamos para mejorar el rendimiento. Pero el "beneficio" que esto generará simplemente no existe. La primera carga de la página es la única vez que se cargará el JS y luego se servirá desde la memoria caché del navegador. Es mucho más probable que el bloqueo en la carga inicial sea una generación PHP lenta que la entrega JS; e incluso aún, el tránsito del servidor o la conectividad de última milla de los usuarios desempeñarán un papel más importante en el tiempo que lleva en realidad retirarse.
Ben Lessani - Sonassi
1
@sonassi Eso es como decir que debes ignorar a los usuarios de la primera visita porque pronto tendrán un caché preparado. Por supuesto, hay mejoras de PHP que pueden y deben llevarse a cabo, pero, como líder, es mi trabajo preocuparme por cómo no solo puedo acelerar la entrega de activos, sino también percibir el tiempo de carga para el usuario y cargar scripts en la parte inferior de La página para evitar el bloqueo de la representación es parte de esa estrategia. Los navegadores modernos pueden manejar scripts sin bloquear, pero usted sabe tan bien como yo que milisegundos == ££ en el comercio electrónico. Por supuesto, esto es generalmente un punto discutible con los cargadores de scripts.
Glo
Estoy con @Glo, es una pequeña pieza de ajuste de eficiencia, y puede que no haga una diferencia de día y noche, pero no debe ignorarse. Obtener contenido en la pantalla rápidamente para un visitante por primera vez es importante.
STW

Respuestas:

22

Depende de su solicitud. Por ejemplo, por último, me habían eliminado todos los scripts de Prototype Homepagede la tienda de Magento, lo que no tuve ningún problema. Pero como dije, depende de tu tema, extensiones, etc.

Para mover el guión:

Encuentra la siguiente línea page.xmlde tu tema

<block type="core/text_list" name="before_body_end" as="before_body_end" translate="label">

E inserte lo siguiente justo antes:

<block type="page/html_head" name="jsfooter" as="jsfooter" template="page/html/jsfooter.phtml">
   <action method="addJs"><script>your_script.js</script></action>
</block>

Para Magento 1.9 use esto:

<block type="page/html_head" name="jsfooter" as="jsfooter" template="page/html/jsfooter.phtml">
       <action method="addItem"><type>skin_js</type><name>js/yourskinfile.js</name><params/></action>
    </block>

Cree el archivo de plantilla en app / design / frontend / [package] / [theme] /template/page/html/jsfooter.phtml y coloque lo siguiente

<?php echo $this->getCssJsHtml() ?>

Agregue a continuación en su plantilla justo antes de cerrar la </body>etiqueta.

<?php echo $this->getChildHtml('jsfooter') ?>
Oğuz Çelikdemir
fuente
¿Estás seguro de que core/text_listtiene un addJs()método?
Alex
tienes razón @Alex, me equivoqué, ¡perdón por eso!
Oğuz Çelikdemir
Saludos hombre, esto funciona. Lo que realmente esperaba decir después de que esto funcionara es que cuando tienes la fusión JS ejecutándose, lo niega de todos modos porque el archivo fusionado se agrega a la cabeza, pero en realidad, lo que Magento parece haber hecho en mi prueba es cree dos archivos combinados, uno para cada bloque de página / html_head y el archivo combinado para el pie de página js se agrega antes de '</body>'. Eso es potencialmente útil. He tenido algunos problemas con la fusión de JS y jQuery, que no incluía jQuery.noConflict. Ahora tengo la fusión JS trabajando el js antes de que '</body>' pueda ser útil.
Mark Weston
20

Hay dos problemas al mover la etiqueta. El mayor problema es que, por alguna razón, Magento inyecta mucho JS que depende del prototipo directamente en la <body/>etiqueta. Mover los scripts al final del documento (aunque es bueno para los tiempos de carga), romperá muchas de las páginas en Magento.

El otro problema es hacerlo realmente. Parece que no hay <move />etiqueta o funcionalidad similar. Lo que he hecho para los scripts personalizados que he creado es agregar scripts como este. Es más redundante, pero funciona:

<block type="page/html_head" name="foot.scripts" template="page/template/foot-scripts.phtml">
    <action method="addJs"><script>jmax/global-min.js</script></action>
</block>
Joseph en SwiftOtter
fuente
Marcó @ Oğuz Çelikdemir correcto porque había proporcionado la respuesta más detallada que funciona, pero básicamente dio la misma respuesta, así que muchas gracias funciona.
Mark Weston
2
Por alguna razón es que está utilizando un framework javascript, de hecho varios. Deben ser residentes desde el principio para la representación adecuada de la página. Hay razones para incluir ciertos javascripts antes del final del cuerpo. Si no comprende esto y lo está empujando ciegamente al fondo, está participando en la programación de culto de carga. Configurar un pequeño cobertizo con una radio ficticia y auriculares se hace mucho con Magento y, a veces, por personas que se supone que son desarrolladores web experimentados. Algunas cosas pertenecen exactamente donde se colocaron.
Fiasco Labs
15

En Magento 1.x esta es una tarea de tontos. Simplemente hay demasiados scripts en línea esparcidos a través de los archivos de plantilla en Magento que se romperán si reubica los archivos JS principales de <head>. Potencialmente en Magento 2, esta situación cambiará, pero se extiende entre Prototype y jQuery a medida que Magento se aleja de Prototype.

Para otros scripts, debe colocarlos antes del </body>elemento. Me pareció útil ignorar el <action method="addJS|addItem">XML de Magento y simplemente crear un nuevo archivo de plantilla para cada script, que incluye una referencia de script HTML simple como:

<script src="<?php echo $this->getSkinUrl('js/hobbiton.js'); ?>"></script>

Luego puede incrustar este archivo de plantilla en cualquier lugar (y aún usarlo antes / después para controlar el orden) de esta manera:

<block type="core/template name="jquery.hobbiton" after="-" template="custom/jquery/hobbiton.phtml" />
Brendan Falkowski
fuente
6

Mover JavaScript externo al final no es suficiente en la mayoría de los casos. Si utiliza alguna plantilla con JavaScript en línea, como en los temas predeterminados, deberá retrasar la ejecución de estos hasta que se carguen todas las dependencias (prototype.js, varien.js, ...).

Un enfoque consiste en extraer todos los <script>elementos en línea de los bloques renderizados utilizando un observador http_response_send_beforey moverlos hasta el final justo después de los guiones externos. Mientras lo hace, puede mover todos los elementos del script, no solo en línea. Esto le ahorra la molestia de moverlos a través del modelo de diseño, que claramente no fue diseñado por Magento.

Tom Robertshaw creó una extensión que hace exactamente esto, con un solo observador que cambia la respuesta HTML utilizando expresiones regulares: https://github.com/bobbyshaw/magento-footer-js

Utiliza el core_block_abstract_to_html_afterevento pero solo toma medidas si el bloque actual es el bloque raíz. Esto significa que se llama al observador con más frecuencia, pero debería aprovechar el almacenamiento en caché de bloque hasta cierto punto.

Fabian Schmengler
fuente
La extensión Robertshaw funciona realmente bien en todo el sitio, excepto en el panel de pago del carrito OPC. Pone totalmente en blanco el panel. Creo que es el script de validación de Payment Gateway. Mueve todo al final justo antes de la </body>etiqueta de cierre .
Fiasco Labs
2

Recomiendo encarecidamente el módulo de velocidad de páginas mediarox para ayudarlo a optimizar su javascript (y css) y mejorar el ranking de información de velocidad de páginas de google.

Funciona analizando la salida html de Magento y luego realizando una acción de cortar y pegar en el código para mover javascript al final del código html. El proceso es rápido, pero se usa mejor junto con una caché de página completa para almacenar en caché los cambios html.

Más información sobre cómo funciona este módulo y puede ayudarlo a mejorar el rango de velocidad de página aquí:

http://blog.gaiterjones.com/magento-google-pagespeed-jscsshtmlminify-optimisation/

paj
fuente
-1

Para Magento v1.6 + (necesita probar en versiones anteriores);

1 - crea un archivo de plantilla page/html/footer/extras.phtmlcon este contenido:

<?php echo $this->getCssJsHtml() ?>

2 - Agregue este nodo html a su diseño xml:

<reference name="before_body_end">
<block type="page/html_head" name="extra_js" as="extraJs" after="-" template="page/html/footer/extras.phtml">
    <action method="addItem"><type>skin_js</type><name>js/jquery.min.js</name></action>
</block>

3 - ¡Eso es!

Marcio Maciel
fuente
-2

Debido a un problema con este otro script (en product / list.phtml) <script type="text/javascript"> decorateList('category-list', 'none-recursive') </script> tuve que mover algunos JS al final de mi página.

No pude hacer que lo que se indica arriba funcione así que encuentro otra forma de lograrlo:

Anulo el Mage/page/Block/Html/Footer.php controllerrecreándolo con la misma ruta en app/local folder.

Aquí está la ruta completa que se creará si no existe:

app / local / Mage / page / Block / Html / Footer.php

En este archivo, agrego funciones de Head.php que se pueden encontrar en la misma carpeta del núcleo de Magento (es decir, Mage / page / Block / Html / Head.php).

Las funciones que necesita para que funcione son (obviamente, la función completa, aquí solo indico el nombre para permanecer conciso):

public function addItem($type, $name, $params=null, $if=null, $cond=null)
{...}

public function addJs($name, $params = "")
{...}

public function getCssJsHtml()
{...}

protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems, $mergeCallback = null)
{...}

protected function _separateOtherHtmlHeadElements(&$lines, $itemIf, $itemType, $itemParams, $itemName, $itemThe)
{...}

protected function _prepareOtherHtmlHeadElements($items)
{...}

Luego agrego a mi página personalizada (la de mi tema) / html / footer.phtml la llamada para esto:

<?php echo $this->getCssJsHtml() ?>

Al final, ahora puedo agregar JS en mi pie de página al llamarlo en cualquier diseño

<action method="addJs"><script>yourscript.js</script></action>
twi_cy
fuente
Enfoque interesante, pero este es un enfoque muy, muy incorrecto para la arquitectura Magento.
Benmarks