JS d'application et de page

Les portées du JS

Comme pour le CSS, les scripts peuvent avoir eux aussi :

  1. une portée de page : le script ne s'exécute que sur la page et n'est spécifique qu'à cette page. C'est le JS de page ;
  2. une portée globale : cela concerne généralement le chargement de bibliothèques telles que JQuery, AngularJS, etc. ou des fonctions utilitaires. C'est le JS d'application.

Le JS de page

Les même bonnes pratiques s'appliquent au CSS comme au Javascript :

  1. un code propre et surtout maintenable ne devrait pas mélanger les langages (HTML, CSS, Javascript et PHP), ou en tout cas le moins possible. Pour une page donnée, si le HTML (contenu) et le CSS possèdent leur propre fichier, alors pourquoi pas faire de même avec le Javascript ? Ici, avec le framework Adventy, c'est le cas. Nous avons un fichier pour le HTML, un autre pour le CSS, puis encore un autre pour le Javascript. Cette séparation des langages permet d'avoir une meilleure visibilité du code et une maintenance facilitée ;
  2. le JS est dédié à la page, mais aussi est séparé du HTML, ce qui permet la ré-utilisation du HTML comme vue. Par conséquent, du côté client, nous avons une séparation entre la présentation (HTML), la décoration (CSS) et le traitement (Javascript) ;
  3. le fichier Javascript ayant aussi l'extension PHP (*.js.php), cela permet donc la génération du code JS avec le langage PHP.

Pour plus de détail sur la création d'un JS de page, veuillez vous reporter à la partie Pages statiques : création du script js personnalisé de page.

Le JS d'application

Le JS d'application à une portée globale sur toute l'application, soit sur toutes les pages du site. Les scripts concernés sont généralement des frameworks JS, des bibliothèques, des plugins et fonctions utilitaires. Ces scripts sont souvent déclarés dans le bloc de la balise head du document HTML avec la syntaxe suivante : <script type="text/javascript" src="/xxx.js"></script>.

Comme avec la balise link pour le chargement d'une ressource CSS, la balise script, quant à elle, charge une ressource JS, et se concrétise donc aussi par une requête vers le serveur. Cela signifie aussi que s'il y a n ressources JS à charger, alors il y aura n requêtes à lancer vers le(s) serveur(s).

Le temps total de chargement des ressources JS est non négligeable, surtout si ce traitement retarde l'affichage du contenu, même pendant un court instant. Afin d'éviter ce moment de blanc, il existe une technique qui consiste dans un premier temps à afficher le visuel (structure HTML), puis vient le chargement des scripts (bibliothèques JS), et enfin terminer par l'exécution de ces derniers (tâches JS).

L'optimisation du JS d'application

L'optimisation de chargement des ressources JS implique :

  1. la réduction du nombre de requêtes au(x) serveur(s) : pour réduire le nombre de requêtes, il suffit tout simplement de fusionner toutes les ressources JS en un unique fichier, comme pour le CSS d'application. Pour cela, le framework Adventy propose le fichier de configuration /application/configuration/js.cfg.php qui déclare toutes les ressources JS à fusionner, et le web service /build/js,ws qui va exécuter cette opération de fusion et d'optimisation sur la taille de la ressource finale.
  2. la réduction de la taille des ressources à télécharger : optimiser la taille d'une ressource JS comprend la réécriture de code (renommage du nom des variables, arrangement syntaxique...), la suppression de caractères non interprétés (tabulation, retour chariot...), et enfin la conversion du format texte au format compressé (ici deflate).

Le fichier de configuration JS

Le fichier de configuration /application/configuration/js.cfg.php se présente exactement comme celui du CSS :

Nous commençons à initialiser le dossier racine des sources JS, le nom du fichier destination JS d'application, et l'option d'optimisation :

$_ENV['JS'] = array(
	'frameworkPath' => $_ENV['FRAMEWORK_ROOT'] . '/js',
	'applicationPath' => &$_ENV['ROOTS']['js'],
	'destinationFile' => 'core',
	'optimizationOnlineEnabled' => true
);
  1. frameworkPath : chemin du dossier racine des ressources JS du framework Adventy. Cette déclaration est optionnelle si ces ressources JS ne sont pas utilisées.
  2. applicationPath : chemin du dossier racine des ressources JS de l'application (/public/js).
  3. destinationFile : nom du fichier sans extension (ici core) résultant de la fusion des sources JS et de son optimisation. Ce fichier sera créé au format texte et sous sa forme compressée deflate, dans le dossier indiqué par la variable d'environnement $_ENV['JS']['applicationPath'] précédemment définie.
  4. optimizationOnlineEnabled : true pour optimiser le JS à l'aide de l'outil en ligne Closure Compiler. false permet seulement la suppression des indentations et des retours à la ligne.

La seconde initialisation correspond à la définition de la liste des ressources JS à fusionner. Par exemple :

$_ENV['JS']['files'] = array(
	//Framework JS files
	//This block can be replace by others JS frameworks or libraries: JQuery, AngularJS, ReactJS, ...
	$_ENV['JS']['frameworkPath'] . '/core-0.0.1.source.js',
	$_ENV['JS']['frameworkPath'] . '/selfcore.source.js',
	$_ENV['JS']['frameworkPath'] . '/dialog.source.js',

	//Application JS files
	//Here, customized JS
	$_ENV['JS']['applicationPath'] . '/source/ini.source.js'
);

Le JS d'application est habituellement déclaré dans le bloc de la balise head du document HTML de la façon suivante :

<script type="text/javascript" src="/core?v=1.js"></script>

Le paramètre v=1 désigne le numéro de version de la mise à jour des JS. Il est optionnel.

Cette déclaration, bien que correcte, présente un énorme défaut : pendant le chargement de la resource JS, le rendu est bloqué. Ce défaut peut être facilement corrigé en adoptant la technique du chargement de scripts en différé.

Le chargement du JS en différé

Cette technique consiste à :

  1. afficher le rendu le plus tôt possible pour donner l'impression à utilisateur d'attendre moins longtemps le chargement de toute la page ;
  2. cela implique de placer le chargement des JS tout à la fin du document HTML, donc après l'affichage de toute la structure HTML de la page ;
  3. créer dynamiquement l'insertion de la déclaration <script type="text/javascript" src="/core?v=1.js"></script> dans le bloc de la balise head.

Dans le template de page /template/default.template.php proposé par défaut dans le dossier du framework Adventy, tout à la fin du document HTML, la fonction Javascript _as a été implémentée à cet effet. Cette dernière permet de charger en asynchrone les ressources JS en générant dynamiquement les déclarations <script...></script> dans le bloc de la balise head.
Cette fonction est préfixé par le caractère "_" pour indiquer qu'elle est de type private, et as signifie Asynchronous Script.

La fonction _as reçoit en paramètre :

  1. l'URL de la ressource JS à charger ;
  2. le callback à exécuter après le chargement de la ressource JS. D'ailleurs, c'est dans cette fonction qu'est placé le JS de page.

La génération du JS d'application

La création du JS d'application se traduit par la fusion des ressources JS. Ces dernières sont listées dans le fichier de configuration /application/configuration/js.cfg.php. Pour générer les fichiers JS d'application, AF propose de lancer la requête https://myadventy.loc/build/js,ws (myadventy.loc étant votre nom de domaine en local) sur un navigateur. Comme pour le CSS d'application, cela va générer 2 fichiers avec l'extension adéquate :

  1. /public/js/core.js au format texte sans compression ;
  2. /public/js/core.js.deflate au format compressé.

Si le client accepte le format deflate, alors la version compression de la ressource JS lui sera envoyée, sinon c'est celle au format texte.