Mova todas as inclusões Javascript para antes </body>

35

Alguém sabe como ter todas as tags de script JS do Magento, por exemplo, <script type="text/javascript" src="http://sitename.com/js/prototype/prototype.js"></script>renderizadas antes do fechamento </body>?

Eu tentei isso uma vez antes, mas recebi um erro que, segundo as linhas do método addJS, não estava disponível onde eu o usei, possivelmente no rodapé de referência.

Mark Weston
fonte
4
Tome a recomendação do GTMetix e do YSlow com uma pitada de sal. O tempo que você gasta investindo nisso não resultará em um aumento perceptível no desempenho e quase certamente seria melhor gasto com a criação de perfil do seu código (eliminando a gordura) ou simplesmente encontrando um host melhor / mais rápido.
Ben Lessani - Sonassi
11
@sonassi Embora seja um ponto válido, levar meia hora para implementar a resposta do JMax não prejudicará nada e faz parte de uma seleção de aprimoramentos de desempenho de front-end que podem ser incluídos em um tema base.
Glo
11
@ Glo Somos todos a favor de melhorias de desempenho. Mas o "benefício" que isso renderá simplesmente não existe. O carregamento da primeira página é a única vez que o JS será carregado e, em seguida, servido a partir do cache do navegador. É muito mais provável que o bloqueio no carregamento inicial seja lento na geração de PHP do que na entrega de JS; e mesmo assim, o trânsito do servidor ou a conectividade de última milha dos usuários desempenharão um papel maior no tempo que leva para realmente diminuir.
Ben Lessani - Sonassi
11
@sonassi É como dizer que você deve ignorar os usuários da primeira visita, porque eles terão um cache preparado em breve. É claro que existem aprimoramentos no PHP que podem e devem ser realizados, mas, como front-end, é meu trabalho me preocupar em como não só posso acelerar a entrega de ativos, mas também o tempo de carregamento percebido para o usuário e o carregamento de scripts na parte inferior de a página para impedir o bloqueio da renderização faz parte dessa estratégia. Os navegadores modernos podem lidar com scripts sem bloquear, mas você sabe tanto quanto eu que milissegundos == ££ no comércio eletrônico. Obviamente, esse é geralmente um ponto discutível nos carregadores de scripts.
Glo
Estou com o @Glo, é um pequeno pedaço de ajuste de eficiência e pode não fazer diferença na noite e no dia, mas não deve ser ignorado. Obter conteúdo na tela rapidamente para um visitante pela primeira vez é importante.
STW

Respostas:

22

Depende do seu pedido. Por exemplo, por último, eu havia removido todos os scripts Prototype da Homepageloja Magento e não encontrei nenhum problema. Mas como eu disse, isso depende do seu tema, extensões etc.

Para mover o script:

Encontre a seguinte linha no page.xmlseu tema

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

E insira o seguinte 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 isto:

<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>

Crie o arquivo de modelo em app / design / frontend / [package] / [theme] /template/page/html/jsfooter.phtml e coloque o seguinte

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

Adicione abaixo no seu modelo antes de fechar a </body>tag.

<?php echo $this->getChildHtml('jsfooter') ?>
Oğuz Çelikdemir
fonte
você core/text_listtem certeza que tem um addJs()método?
Alex
você está certo @Alex, eu me enganei, desculpe por isso!
Oğuz Çelikdemir
Saúde, isso funciona. O que eu realmente esperava dizer depois de fazer isso funcionar é que, quando você tem a mesclagem de JS em execução, ela nega isso de qualquer maneira, porque o arquivo mesclado é anexado à cabeça, mas, na verdade, o que o Magento parece ter feito no meu teste é crie dois arquivos mesclados, um para cada bloco page / html_head e o arquivo mesclado para o rodapé js será anexado antes de '</body>'. Isso é potencialmente útil. Eu tive alguns problemas com a mesclagem de JS e o jQuery, que não incluíam o jQuery.noConflict. Agora eu tenho o JS mesclado trabalhando os js antes de '</body>' pode ser útil.
Mark Weston
20

Existem dois problemas ao mover a tag. O maior problema é que, por algum motivo, o Magento injeta muitas JS que dependem do protótipo diretamente na <body/>tag. Mover os scripts para o final do documento (embora seja bom para os tempos de carregamento), quebrará muitas páginas no Magento.

O outro problema é realmente fazê-lo. Parece não haver <move />tag ou funcionalidade semelhante. O que fiz para scripts personalizados que criei é adicionar scripts como este. É mais redundante, mas 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 na SwiftOtter
fonte
Marcado @ Oğuz Çelikdemir correto, porque ele forneceu a resposta mais detalhada que funciona, mas você basicamente deu a mesma resposta, então muito obrigado ele funciona.
Mark Weston
2
Por alguma razão é que você está usando uma estrutura javascript, de fato várias. Eles devem residir desde o início para a renderização adequada da página. Existem razões para incluir certos javascripts antes do final do corpo. Se você não entende isso e está cegamente empurrando tudo para o fundo, está envolvido na programação de cultos de carga. Configurar um pequeno galpão com um rádio e fones de ouvido fictícios é feito muito com o Magento e, às vezes, por pessoas que deveriam ser desenvolvedores web experientes. Algumas coisas pertencem exatamente onde foram colocadas.
Fiasco Labs
15

No Magento 1.x, essa é uma tarefa tola. Existem simplesmente muitos scripts embutidos espalhados pelos arquivos de modelo no Magento que serão quebrados se você realocar os arquivos JS principais do diretório <head>. Potencialmente no Magento 2, essa situação mudará, mas está abrangendo Prototype e jQuery à medida que o Magento migra para longe do Prototype.

Para outros scripts, você deve colocá-los antes do </body>elemento. Eu achei útil ignorar o <action method="addJS|addItem">XML do Magento e simplesmente criar um novo arquivo de modelo para cada script, que inclui uma referência simples de script HTML como:

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

Em seguida, você pode incorporar esse arquivo de modelo em qualquer lugar (e ainda usar antes / depois para controlar o pedido) da seguinte maneira:

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

Mover JavaScript externo para o final não é suficiente na maioria dos casos. Se você usar algum modelo com JavaScript embutido, como nos temas padrão, precisará adiar a execução deles até que todas as dependências (prototype.js, varien.js, ...) sejam carregadas.

Uma abordagem é extrair todos os <script>elementos embutidos dos blocos renderizados usando um observador para http_response_send_beforee movê-los para o final logo após os scripts externos. Enquanto você está nisso, você pode mover todos os elementos de script, não apenas inline. Isso evita o trabalho de movê-los através do modelo de layout, que claramente não foi planejado pelo Magento.

Tom Robertshaw criou uma extensão que faz exatamente isso, com um único observador que altera a resposta HTML usando expressões regulares: https://github.com/bobbyshaw/magento-footer-js

Ele usa o core_block_abstract_to_html_afterevento, mas só executa uma ação se o bloco atual for o bloco raiz. Isso significa que o observador é chamado com mais frequência, mas deve alavancar o cache do bloco até certo ponto.

Fabian Schmengler
fonte
A extensão Robertshaw funciona muito bem em todo o site, exceto no painel de pagamento do carrinho OPC. Apaga totalmente o painel. Eu acho que é o script de validação do Payment Gateway. Move tudo para o fundo logo antes da </body>tag de fechamento .
Fiasco Labs
2

Eu recomendo o módulo mediarox pagespeed para ajudar você a otimizar seu javascript (e css) e melhorar a classificação de insight do google pagespeed.

Ele funciona analisando a saída html do Magento e, em seguida, executando uma ação de recortar e colar no código para mover o javascript para a parte inferior do código html. O processo é rápido, mas é melhor usado em conjunto com um cache de página inteira para armazenar em cache as alterações html.

Mais informações sobre como este módulo funciona e podem ajudá-lo a melhorar a classificação da velocidade da página aqui:

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

paj
fonte
-1

Para Magento v1.6 + (necessidade de testar em versões mais antigas);

1 - crie um arquivo de modelo page/html/footer/extras.phtmlcom este conteúdo:

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

2 - Adicione este nó html ao seu xml de layout:

<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 - É isso aí!

Marcio Maciel
fonte
-2

Devido a um problema com este outro script (em product / list.phtml) <script type="text/javascript"> decorateList('category-list', 'none-recursive') </script> , tive que mover algumas JS no final da minha página.

Não consegui fazer com que o que foi indicado acima funcione, então encontro outra maneira de alcançar:

Eu substituo o Mage/page/Block/Html/Footer.php controllerrecriando-o com o mesmo caminho app/local folder.

Aqui está o caminho completo a ser criado, se não existir:

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

Neste arquivo, adiciono funções do Head.php, que podem ser encontradas na mesma pasta do núcleo do Magento (por exemplo, Mage / page / Block / Html / Head.php).

As funções que você precisa para fazer funcionar são (obviamente, a função completa, aqui apenas indico o nome 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)
{...}

Em seguida, adiciono à minha página personalizada (a do meu tema) / html / footer.phtml a chamada para isso:

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

No final, agora posso adicionar JS no rodapé chamando-o em qualquer layout,

<action method="addJs"><script>yourscript.js</script></action>
twi_cy
fonte
Abordagem interessante, mas essa é uma abordagem muito, muito incorreta para a arquitetura Magento.
benmarks