Charger le JS uniquement quand la page est chargé?

WRInaute passionné
Bonjour,

Je tente d'optimiser la vitesse d'affichage d'un site en faisant en sorte que le Javascript soit chargé en dernier. Pour ce faire j'utilise un petit script trouvé sur le net qui est le suivant :
Code:
function loadjscssfile(filename, filetype){
	//extension js
	if (filetype=="js"){
		var fileref=document.createElement('script')
		fileref.setAttribute("type","text/javascript")
		fileref.setAttribute("src", filename)
	}
	//extension css
	else if (filetype=="css"){
		var fileref=document.createElement("link")
		fileref.setAttribute("rel", "stylesheet")
		fileref.setAttribute("type", "text/css")
		fileref.setAttribute("href", filename)
	}
	if (typeof fileref!="undefined")
	document.getElementsByTagName("head")[0].appendChild(fileref)
}
Ensuite on a juste à indiquer quel est (ou sont) le fichier à charger :
Code:
loadjscssfile("http://code.jquery.com/jquery-1.5.min.js", "js");

Le code semble fonctionner mais je rencontre un soucis si j'utilise cette technique avec le script Fancybox.

Mon teste est le suivant :
Code:
loadjscssfile("http://code.jquery.com/jquery-1.5.min.js", "js");
loadjscssfile("/fancybox/jquery.mousewheel-3.0.4.pack.js", "js");
/*Ci-dessous le fichier qu'il n'aime pas*/
loadjscssfile("/fancybox/jquery.fancybox-1.3.4.pack.js", "js");
loadjscssfile("/fancybox/jquery.fancybox-1.3.4.css", "css");

//Fenêtre Fancybox
$(document).ready(function() {
	$("a[rel=example_group]").fancybox({
		'width'				: '80%',
		'height'			: '80%',
		'autoScale'			: true,
		'transitionIn'		: 'elastic',
		'transitionOut'		: 'elastic',		
		'type'				: 'iframe',
		'titlePosition' 	: 'outside',
		'titleFormat'		: function(title) {
			return '<span id="fancybox-title-over">' + title + '</span>';
		}				
	});	
});

Ouverture de la fenêtre Fancybox :
Code:
<a rel="example_group" title="voir" href="/max469/3905.swf">Voir</a>

La fenêtre ou box ne s'ouvre pas si l'appel au code "/fancybox/jquery.fancybox-1.3.4.pack.js" se réalise dans la fonction comme ci-dessus. Par contre si je fais appel au script directement suite à la fonction :
Code:
<script type="text/javascript" src="/fancybox/jquery.fancybox-1.3.4.pack.js"></script>
...ça fonctionne 8O .

Ma question est donc : pourquoi la fonction ne fonctionne pas alors que tout les fichiers semble être chargés correctement?

Merci
 
WRInaute discret
Bonjour Tryan.

Je dis peut-être une grosse grosse bêtise mais je vois pas trop l'intérêt du truc : le plus simple ne serait-il pas de placer tes js juste avant la fermeture de ta balise body ? (à moins que tu n'ais pas la possibilité de le faire, pour une raison ou une autre).

@++!
 
WRInaute impliqué
Le fais d'insérer les balises de cette manière rend le chargement asynchrone. Le navigateur continue le chargement de la page sans attendre la fin de chargement des fichiers JS.
Comme le fait remarquer Supermaury, il suffit simplement de mettre tes balises script juste avant "</body>" pour que ta page soit optimisé.
 
WRInaute accro
tryan a dit:
La fenêtre ou box ne s'ouvre pas si l'appel au code "/fancybox/jquery.fancybox-1.3.4.pack.js" se réalise dans la fonction comme ci-dessus. Par contre si je fais appel au script directement suite à la fonction ...ça fonctionne 8O .
A vue de nez sans trop réfléchir je pense que c'est un problème de synchro.

Ton "chargeur de script" ne dois pas avoir fini son travail quand ton script Fancybox déclenche le travail. Bref tu risque d'appeler une fonction qui n'existe pas encore au moment de l'évènement "onload" de la page qui me semble retranscrit par cette appel ; "$(document).ready(function(){...});".

Soit tu temporise le déclenchement Fancybox, soit tu essaie de regrouper les deux a la suite (chargement des scripts plus lancement) dans une même fonction.

Toujours a l'arrache sans réfléchir essaie :
PHP:
<span class="syntaxdefault"></span><span class="syntaxcomment">// chargement des fichiers classiques<br /></span><span class="syntaxdefault">loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"http://code.jquery.com/jquery-1.5.min.js"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"js"</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"/fancybox/jquery.mousewheel-3.0.4.pack.js"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"js"</span><span class="syntaxkeyword">);<br /><br /></span><span class="syntaxcomment">//Fenêtre Fancybox<br /></span><span class="syntaxkeyword">$(</span><span class="syntaxdefault">document</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">ready</span><span class="syntaxkeyword">(function()</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">   </span><span class="syntaxcomment">// chargement des dépendances Fancybox<br /></span><span class="syntaxdefault">   loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"/fancybox/jquery.fancybox-1.3.4.pack.js"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"js"</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">   loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"/fancybox/jquery.fancybox-1.3.4.css"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"css"</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">   </span><span class="syntaxkeyword">$(</span><span class="syntaxstring">"a[rel=example_group]"</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">fancybox</span><span class="syntaxkeyword">({<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'width'</span><span class="syntaxdefault">            </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'80%'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'height'</span><span class="syntaxdefault">         </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'80%'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'autoScale'</span><span class="syntaxdefault">         </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> true</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'transitionIn'</span><span class="syntaxdefault">      </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'elastic'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'transitionOut'</span><span class="syntaxdefault">      </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'elastic'</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">      <br />      </span><span class="syntaxstring">'type'</span><span class="syntaxdefault">            </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'iframe'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'titlePosition'</span><span class="syntaxdefault">    </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'outside'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxstring">'titleFormat'</span><span class="syntaxdefault">      </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> function</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">title</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">         return </span><span class="syntaxstring">'<span id="fancybox-title-over">'</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> title </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> </span><span class="syntaxstring">'</span>'</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">      </span><span class="syntaxkeyword">}</span><span class="syntaxdefault">            <br />   </span><span class="syntaxkeyword">});</span><span class="syntaxdefault">   <br /></span><span class="syntaxkeyword">});</span><span class="syntaxdefault"> </span>

note que le fichier CSS changera pas grand chose c'est pas bloquant ....

si ça coince tu peut essayer un truc du genre qui devrait temporiser la fancybox (3 secondes dans cet exemple):
PHP:
<span class="syntaxdefault"></span><span class="syntaxcomment">// chargement des fichiers classiques<br /></span><span class="syntaxdefault">loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"http://code.jquery.com/jquery-1.5.min.js"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"js"</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"/fancybox/jquery.mousewheel-3.0.4.pack.js"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"js"</span><span class="syntaxkeyword">);<br /></span><span class="syntaxcomment">// chargement des dépendances Fancybox<br /></span><span class="syntaxdefault">loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"/fancybox/jquery.fancybox-1.3.4.pack.js"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"js"</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">loadjscssfile</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"/fancybox/jquery.fancybox-1.3.4.css"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"css"</span><span class="syntaxkeyword">);<br /><br /></span><span class="syntaxcomment">//Fenêtre Fancybox<br /></span><span class="syntaxkeyword">$(</span><span class="syntaxdefault">document</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">ready</span><span class="syntaxkeyword">(function()</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">   setTimeout</span><span class="syntaxkeyword">(function(){<br /></span><span class="syntaxdefault">      </span><span class="syntaxkeyword">$(</span><span class="syntaxstring">"a[rel=example_group]"</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">fancybox</span><span class="syntaxkeyword">({<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'width'</span><span class="syntaxdefault">            </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'80%'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'height'</span><span class="syntaxdefault">         </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'80%'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'autoScale'</span><span class="syntaxdefault">         </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> true</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'transitionIn'</span><span class="syntaxdefault">      </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'elastic'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'transitionOut'</span><span class="syntaxdefault">      </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'elastic'</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">      <br />         </span><span class="syntaxstring">'type'</span><span class="syntaxdefault">            </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'iframe'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'titlePosition'</span><span class="syntaxdefault">    </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> </span><span class="syntaxstring">'outside'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">         </span><span class="syntaxstring">'titleFormat'</span><span class="syntaxdefault">      </span><span class="syntaxkeyword">:</span><span class="syntaxdefault"> function</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">title</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">            return </span><span class="syntaxstring">'<span id="fancybox-title-over">'</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> title </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> </span><span class="syntaxstring">'</span>'</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">         </span><span class="syntaxkeyword">}</span><span class="syntaxdefault">            <br />      </span><span class="syntaxkeyword">});<br /></span><span class="syntaxdefault">   </span><span class="syntaxkeyword">},</span><span class="syntaxdefault">3000</span><span class="syntaxkeyword">);<br />});</span><span class="syntaxdefault">  </span>
Note bien que j'ai rien testé c'est juste le principe que j'ai regardé.
 
WRInaute passionné
l’intérêt de charger le JS en asynchrone est évident pour du JS externe qui risque de bloquer le chargement de la page en cas d'indisponibilité. C'est con de bloquer le chargement de la page pour un bouton FB ou TW.

Avec ton code je ne vois pas l'attribut async=true. C'est donc pas asynchrone. La difficulté avec le chargement asynchrone c'est de bien lancer certains codes d'initialisation quand tout est chargé et c'est là que ca se complique (surtout avec plusieurs JS).
 
WRInaute passionné
Whaouu, je ne m'attendais pas à autant de réponses :mrgreen: , merci à vous.
Pour répondre à @Supermaury et à @Blount : je ne suis pas un adepte du Javascript et ma logique (qui n'est sans doute pas la bonne) me dit que je ne peut pas faire appel à une fonction si celle-ci na pas été déclarée avant (comme php), d'ou mon acharnement à trouver une solution pour que les fonctions soient chargés un fois la page chargé complètement.

zeb a dit:
A vue de nez sans trop réfléchir je pense que c'est un problème de synchro.
Ton "chargeur de script" ne dois pas avoir fini son travail quand ton script Fancybox déclenche le travail.
En admettant que je laisse la page se charger tranquillement (1 bonne grosse minute pour voir large), théoriquement, tout les script sont chargées et prêt à l'emploie et donc Fancybox devrait fonctionner .. ou je me plante encore? En tout cas merci pour tes codes, je ferais un teste dans le courant du week-end :).

@forty : je ne cherche pas à faire de l'asynchrone, je veux juste différer l'analyse du code JavaScript comme le préconise Page Speed.

@spout : merci pour le tuto.
 
WRInaute impliqué
non en fait il te faut cette version améliorée de loadjscssfile car quand tu charges en asynchrone un js il te faut un callback quand celui ci est disponible (chargé), donc en gros tu fais :

Code:
loadjscssfile("/fancybox/jquery.fancybox-1.3.4.pack.js", "js", function() {
   $("a[rel=example_group]").fancybox({
      'width'            : '80%',
      'height'         : '80%',
      'autoScale'         : true,
      'transitionIn'      : 'elastic',
      'transitionOut'      : 'elastic',      
      'type'            : 'iframe',
      'titlePosition'    : 'outside',
      'titleFormat'      : function(title) {
         return '<span id="fancybox-title-over">' + title + '</span>';
      }            
});
loadjscssfile("/fancybox/jquery.fancybox-1.3.4.css", "css");

Code:
function loadjscssfile(filename, filetype)
{
  var fileref;
  var func = null;
  filename += filename.indexOf('?') < 0 ? '?v'+version : '&v'+version;
  if (filetype=="js" )
  {
    fileref = document.createElement('script');
    fileref.setAttribute("type","text/javascript");
    fileref.setAttribute("src", filename);
    if( arguments[2] != undefined )
    {
      func = arguments[2];
      if( fileref.readyState )
      {
        fileref.onreadystatechange = function()
        {
          if(fileref.readyState == "loaded" || fileref.readyState == "complete")
          {
            fileref.onreadystatechange = null;
            func();
          }
        }
      }
      else
      {
        fileref.onload = function()
        {
          func();
        }
      }
    }
  }
  else if (filetype=="css")
  {
    fileref = document.createElement("link");
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", filename);
  }
  document.getElementsByTagName("head")[0].appendChild(fileref);
}
 
Discussions similaires
Haut