Déplacez tous les éléments Javascript inclus vers avant </ body>

35

Est-ce que quelqu'un sait comment faire en sorte que toutes les balises de script JS de Magento, par exemple, soient rendues <script type="text/javascript" src="http://sitename.com/js/prototype/prototype.js"></script>avant la fermeture </body>?

J'ai déjà essayé cela une fois auparavant, mais une erreur m'a été signalée qui, selon moi, correspond au fait que la méthode addJS n'est pas disponible là où je l'ai utilisée, éventuellement dans le pied de page de référence.

Mark Weston
la source
4
Prenez la recommandation de GTMetix et YSlow avec une pincée de sel. Le temps que vous consacrez à cet investissement n'entraînera pas une augmentation notable des performances, mais il serait certainement préférable de passer au profilage de votre code (dégraissage) ou à la recherche d'un hôte meilleur / plus rapide.
Ben Lessani - Sonassi
1
@sonassi Bien qu'il soit valide, prendre une demi-heure pour implémenter la réponse de JMax ne nuit à rien et fait partie d'une sélection d'améliorations de performances frontales pouvant être incluses dans un thème de base.
Glo
1
@Glo Nous sommes tous pour l'amélioration des performances. Mais le "bénéfice" que cela va rapporter n'existe tout simplement pas. Le premier chargement de page est le seul moment où le JS sera chargé puis servi à partir du cache du navigateur. Le blocage lors du chargement initial est beaucoup plus susceptible d’être lié à une génération PHP lente qu’une livraison JS; Et même quand même, le transit du serveur ou la connectivité du dernier kilomètre des utilisateurs joueront un rôle plus important dans le temps nécessaire à la suppression.
Ben Lessani - Sonassi
1
@sonassi C'est comme dire que vous devriez ignorer les utilisateurs de la première visite car ils disposeront bientôt d'un cache apprêté. Bien sûr, certaines améliorations de PHP peuvent et doivent être apportées, mais en tant que leader, mon travail consiste à m'inquiéter de la manière dont je peux non seulement accélérer la livraison des ressources, mais aussi percevoir le temps de chargement de l'utilisateur et le chargement des scripts au bas de la page. la page pour empêcher le blocage du rendu fait partie de cette stratégie. Les navigateurs modernes peuvent gérer les scripts sans bloquer, mais vous savez aussi que moi que millisecondes == £ £ dans le commerce électronique. Bien entendu, il s’agit généralement d’un point discutable avec les chargeurs de scripts.
Glo
Je suis chez @Glo, c’est un petit réglage de l’efficacité, qui ne fait peut-être pas une différence jour et nuit, mais il ne faut pas l’ignorer. Obtenir du contenu à l'écran rapidement pour un premier visiteur est important.
STW

Réponses:

22

Cela dépend de votre demande. Par exemple, enfin, tous les scripts Prototype Homepagede la boutique Magento avaient été supprimés et je n’avais rencontré aucun problème. Mais comme je l'ai dit, cela dépend de votre thème, des extensions, etc.

Pour déplacer le script:

Trouvez la ligne suivante dans page.xmlvotre thème

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

Et insérez le texte suivant juste avant:

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

Pour Magento 1.9, utilisez ceci:

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

Créez le fichier de modèle dans app / design / frontend / [package] / [thème] /template/page/html/jsfooter.phtml et mettez ce qui suit

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

Ajoutez ci-dessous dans votre modèle juste avant la fermeture de la </body>balise.

<?php echo $this->getChildHtml('jsfooter') ?>
Oğuz Çelikdemir
la source
Êtes-vous sûr d' core/text_listavoir une addJs()méthode?
Alex
tu as raison @Alex, je me suis trompé, désolé pour ça!
Oğuz Çelikdemir
Vive l'homme, ça marche. En fait, je m'attendais à ce que, une fois que cela fonctionne, la fusion de JS est annulée, car le fichier fusionné est ensuite ajouté à la tête, mais ce que Magento semble avoir fait dans mon test est créez deux fichiers fusionnés, un pour chaque bloc page / html_head et le fichier fusionné pour le pied de page js est ajouté avant '</ body>'. C'est potentiellement utile. J'ai eu quelques problèmes avec la fusion de JS et jQuery qui consistait à ne pas inclure jQuery.noConflict. Maintenant, js ai fusionné en travaillant js avant '</ body>' pourrait être utile.
Mark Weston
20

Le déplacement de la balise pose deux problèmes. Le plus gros problème est que, pour une raison quelconque, Magento injecte beaucoup de JS dépendant du prototype directement dans la <body/>balise. Déplacer les scripts à la fin du document (bien que ce soit bon pour les temps de chargement), casserait beaucoup de pages dans Magento.

L'autre problème est en train de le faire. Il ne semble pas y avoir de <move />balise, ou une fonctionnalité similaire. Ce que j'ai fait pour les scripts personnalisés que j'ai créés, c'est en ajoutant des scripts comme celui-ci. C'est plus redondant, mais ça marche:

<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 chez SwiftOtter
la source
La mention @ Oğuz Çelikdemir est correcte car il a fourni la réponse plus détaillée qui fonctionne, mais vous avez en gros donné la même réponse, alors merci beaucoup, cela fonctionne.
Mark Weston
2
Pour une raison quelconque , vous utilisez un framework javascript, en fait plusieurs. Ils doivent être résidents au début pour un rendu de page correct. Il y a des raisons d'inclure certains javascripts avant body end. Si vous ne comprenez pas cela et que vous dirigez aveuglément tout cela vers le bas, vous vous engagez dans une programmation culte du fret. L'installation d'un petit hangar avec une radio fictive et des casques d'écoute se fait souvent avec Magento et parfois par des personnes supposées être des développeurs Web expérimentés. Certaines choses appartiennent exactement à l'endroit où elles ont été placées.
Fiasco Labs
15

Dans Magento 1.x, c'est une course de fou. Il y a tout simplement trop de scripts en ligne encombrés dans les modèles de fichiers dans Magento qui risquent de ne plus fonctionner correctement si vous déplaciez les fichiers JS principaux à partir du <head>. Potentiellement dans Magento 2, cette situation va changer, mais elle est à cheval entre Prototype et jQuery alors que Magento migre de Prototype.

Pour les autres scripts, vous devez les placer avant l' </body>élément. J'ai trouvé utile d'ignorer le code <action method="addJS|addItem">XML de Magento et de créer simplement un nouveau fichier de modèle pour chaque script, qui inclut une référence de script HTML simple, telle que:

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

Ensuite, vous pouvez incorporer ce fichier de modèle n'importe où (et toujours utiliser avant / après pour contrôler l'ordre) comme ceci:

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

Déplacer JavaScript externe vers le bas ne suffit pas dans la plupart des cas. Si vous utilisez des modèles avec du JavaScript intégré, comme dans les thèmes par défaut, vous devrez différer leur exécution jusqu'à ce que toutes les dépendances (prototype.js, varien.js, ...) soient chargées.

Une approche consiste à extraire tous les <script>éléments en ligne des blocs rendus à l'aide d'un observateur http_response_send_beforeet à les déplacer à la fin, juste après les scripts externes. Tant que vous y êtes, vous pouvez déplacer tous les éléments de script, pas seulement en ligne. Cela vous évite d'avoir à les déplacer via le modèle de présentation, ce qui n'était clairement pas l'intention de Magento.

Tom Robertshaw a créé une extension qui fait exactement cela, avec un seul observateur qui modifie la réponse HTML en utilisant des expressions régulières: https://github.com/bobbyshaw/magento-footer-js

Il utilise l' core_block_abstract_to_html_afterévénement mais n'agit que si le bloc actuel est le bloc racine. Cela signifie que l’observateur est appelé plus souvent, mais il doit exploiter dans une certaine mesure la mise en cache des blocs.

Fabian Schmengler
la source
L'extension Robertshaw fonctionne très bien sur tout le site, sauf sur le panneau de paiement du chariot OPC. Totalement vide le panneau. Je pense que c'est le script de validation de la passerelle de paiement. Il déplace tout vers le bas, juste avant la </body>balise de fermeture .
Fiasco Labs
2

Je recommande vivement le module pagespeed de mediarox pour vous aider à optimiser votre javascript (et css) et à améliorer le classement de Google pagespeed insight.

Cela fonctionne en analysant la sortie html de Magento, puis en effectuant une action copier / coller sur le code pour déplacer javascript au bas du code html. Le processus est rapide, mais il est préférable de l'utiliser conjointement avec un cache de page complet pour mettre en cache les modifications HTML.

Plus d'informations sur le fonctionnement de ce module et peuvent vous aider à améliorer le classement par vitesse de page ici:

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

paj
la source
-1

Pour Magento v1.6 + (nécessité de tester dans des versions plus anciennes);

1 - créer un fichier modèle page/html/footer/extras.phtmlavec ce contenu:

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

2 - Ajoutez ce noeud html à votre layout 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 - C'est ça!

Marcio Maciel
la source
-2

En raison d'un problème avec cet autre script (dans product / list.phtml), <script type="text/javascript"> decorateList('category-list', 'none-recursive') </script> j'ai dû déplacer un fichier JS à la fin de ma page.

Je n'ai pas réussi à faire fonctionner ce qui est indiqué ci-dessus, alors j'ai trouvé un autre moyen de réaliser:

Je remplace le Mage/page/Block/Html/Footer.php controlleren le recréant avec le même chemin dans app/local folder.

Voici le chemin complet à créer s'il n'existe pas:

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

Dans ce fichier, j'ajoute des fonctions de Head.php qui se trouvent dans le même dossier que le noyau de Magento (par exemple, Mage / page / Block / Html / Head.php).

Les fonctions dont vous avez besoin pour que cela fonctionne sont (évidemment la fonction complète, ici je viens d'indiquer le nom pour rester concis):

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)
{...}

Ensuite, j'ajoute à ma page (html / footer.phtml) personnalisée (celle de mon thème):

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

À la fin, je peux maintenant ajouter JS dans mon pied de page en l’appelant dans n’importe quelle mise en page.

<action method="addJs"><script>yourscript.js</script></action>
twi_cy
la source
Une approche intéressante, mais il s’agit d’une approche très très incorrecte pour l’architecture Magento.
benmarks