Ressources Web - Conseils pour améliorer l'organisation et les performances

Vous souvenez-vous de l'époque où nous devions passer beaucoup de temps à optimiser les actifs de notre projet (images, CSS, etc.)? De nos jours, les utilisateurs ont une connexion Internet beaucoup plus rapide et il semble que nous puissions nous permettre d’utiliser des images plus grandes ou des fichiers flash plus volumineux contenant beaucoup de vidéos et d’images. Cependant, avec l'essor du développement mobile, nous nous retrouvons dans la même situation. Il est extrêmement important de créer des sites bien optimisés afin d'avoir des applications plus rapides, qui téléchargent moins de contenu et répondent immédiatement..


Images

Servir la bonne taille

Souvent, nous utilisons les mêmes images pour différentes parties de nos sites Web. Par exemple, dans une boutique en ligne, tous les produits ont une vue d’ensemble. Disons que nous avons trois pages où nous devons montrer ces images: une page pour énumérer les produits, une autre page pour les détails du produit et une troisième page qui montre uniquement la photo dans sa taille originale.

Nous avons donc besoin de trois tailles d'image différentes et si nous utilisons le même fichier pour les trois endroits différents, le navigateur téléchargera l'image en taille réelle, même pour la page de liste, où nous n'aurons peut-être besoin que d'une image 200x200. Si le fichier d'origine fait environ 1 Mo et que nous avons dix produits par page, l'utilisateur téléchargerait 10 Mo. Ce n'est pas une très bonne idée. Si vous le pouvez, essayez de générer différentes images pour les différentes parties de votre site, cela économisera beaucoup de Ko pour vos utilisateurs. Il est judicieux de garder à l’esprit la résolution actuelle de l’écran. Par exemple, si quelqu'un ouvre votre site sur son iPhone, il n'est pas nécessaire de diffuser l'image d'en-tête géante que vous utilisez normalement. En utilisant les requêtes de média CSS, vous pouvez envoyer une image avec une taille plus petite:

@media only screen et (min-device-width: 320px) et (max-device-width: 480px) .header background-image: url (… /images/background_400x200.jpg); 

Compression

Envoyer une image avec les dimensions appropriées ne suffit pas toujours. Certains formats de fichiers peuvent être beaucoup compressés sans perdre leur qualité. Il existe de nombreux programmes qui peuvent vous aider. Par exemple, Photoshop fournit une fonctionnalité intéressante appelée Enregistrer pour le Web et les périphériques:


Il y a beaucoup d'options dans cette boîte de dialogue, mais l'une des plus importantes est Qualité. En le réglant à quelque chose comme 80%, la taille du fichier pourrait être considérablement réduite.

Bien sûr, vous pouvez utiliser du code pour compresser les fichiers, mais je préfère personnellement Photoshop et je l’utilise autant que possible. Voici un exemple simple écrit en PHP:

fonction compressImage ($ source, $ destination, $ qualité) $ info = getimagesize ($ source); switch ($ info ['mime']) case "image / jpeg": $ image = imagecreatefromjpeg ($ source); imagejpeg ($ image, $ destination, $ qualité); Pause; case "image / gif": $ image = imagecreatefromgif ($ source); imagegif ($ image, $ destination, $ qualité); Pause; case "image / png": $ image = imagecreatefrompng ($ source); imagepng ($ image, $ destination, $ qualité); Pause;  compressImage ('source.png', 'destination.png', 85);

Sprites

Une des choses que vous pouvez faire pour augmenter les performances de votre application est de réduire le nombre de demandes adressées au serveur. Ainsi, chaque nouvelle image signifie une nouvelle requête. C'est une bonne idée de combiner vos images en une seule. L'image résultante s'appelle un lutin et en changeant le position de fond Style CSS, vous ne pouvez afficher que la partie de l’image dont vous avez besoin. Par exemple, Twitter Bootstrap utilise des sprites pour ses icônes internes:


Ensuite, dans le CSS, vous pouvez faire quelque chose comme ceci, pour montrer la portion de sprite que vous souhaitez:

.icon-edit background-image: url ("… /img/glyphicons-halflings-white.png"); position d'arrière-plan: -96px -72px; 

Caching

Le mécanisme de mise en cache du navigateur est votre ami. Oui, parfois pendant le développement, cela peut conduire à des marrant situations, mais cela aide vraiment à améliorer les performances de votre site. Chaque navigateur met en cache le contenu tel que des images, JavaScript ou CSS. Il existe plusieurs façons de contrôler la mise en cache et je vous suggère de consulter cet article pour un examen détaillé. En général, vous pouvez contrôler le processus en définissant des en-têtes, comme suit:

$ expire = 60 * 60 * 24 * 1; // secondes, minutes, heures, jours en-tête ('Cache-Control: maxage = ". $ expire); en-tête (" Expires:' .gmdate ('D, d MYH: i: s ', heure () + $ expire).' GMT '); en-tête ('Last-Modified:' .gmdate ('D, d M Y H: i: s'). 'GMT');

Prélecture

HTML5 progresse chaque jour. Il y a une fonctionnalité intéressante appelée prélecture ce qui indique au navigateur que vous aurez besoin de quelques ressources dans un proche avenir et qu'il convient de les télécharger maintenant, à l'avance. Par exemple:

Schéma d'URI de données / images en ligne

Il y a quelques années, j'ai dû développer une simple page Web, censée ne contenir qu'un fichier HTML. Bien sûr, il y avait plusieurs images, que je devais inclure. Les schémas Data URI m'ont aidé à résoudre le problème. L’idée est de convertir vos images en une chaîne encodée en base64 et de les placer dans le src attribut du img étiquette. Par exemple:

point rouge

En utilisant cette approche, votre image est en réalité dans le code HTML et vous enregistrez une requête HTTP. Bien sûr, si vous avez une grande image, la chaîne sera très longue. Voici un script PHP simple qui convertit les images en chaînes base64:

$ picture = fread ($ fp, taille du fichier ($ fichier)); fclose ($ fp); // base64 encode les données binaires, puis les divise // en morceaux conformément à la sémantique RFC 2045 $ base64 = base64_encode ($ picture); $ tag = ''; $ css = 'url (données: image / jpg; base64,'. str_replace ("\ n", "", $ base64). '); ';

Cela peut être utile dans certains cas, mais gardez à l’esprit que cela ne fonctionne pas très bien dans IE..


CSS

J'aime penser que l'écriture de CSS est comme écrire du code. Vous devez encore organiser vos styles, définir différents blocs et leur relation. C'est pourquoi je pense que la gestion des CSS est vraiment importante. Chaque partie de l'application doit avoir ses propres styles et doit être bien séparée. Garder tout dans des fichiers différents fournit une bonne organisation, mais pose aussi ses propres problèmes.

Nous savons tous que l’utilisation de la @importation déclaration n'est pas une très bonne idée. C'est parce que chaque nouvelle @importation signifie une nouvelle demande au serveur. Et si vous avez, par exemple, 20 différents .css fichiers cela signifie que le navigateur fera 20 demandes. Et le navigateur ne rend pas / affiche la page avant de télécharger tous les styles. Si certains de vos .css les fichiers sont manquants ou très volumineux, vous aurez un grand retard avant de voir quelque chose à l'écran.

Utiliser les préprocesseurs CSS

Les préprocesseurs CSS résolvent tous les problèmes ci-dessus. Vous divisez toujours vos styles en différents fichiers, mais à la fin, le préprocesseur compile le tout en un seul fichier. .css fichier. Ils offrent en fait un tas de fonctionnalités intéressantes comme les variables, les blocs imbriqués, les mixins et l'héritage. Le code ressemble toujours à du CSS, mais il est bien formaté / structuré. Il existe peu de préprocesseurs populaires qui valent la peine d’être vérifiés - Sass, LESS et Stylus. Voici un exemple simple écrit en LESS:

.position (@top: 0, @left: 0) position: absolute; en haut: @top; gauche: @left; text-align: left; taille de police: 24px;  .header .position (20px, 30px); .tips .position (10px, -20px);  .logo .position (10px, 20px); 

produira

.header position: absolute; en haut: 20px; à gauche: 30px; text-align: left; taille de police: 24px;  .header .tips position: absolute; en haut: 10 px; à gauche: -20px; text-align: left; taille de police: 24px;  .header .logo position: absolute; en haut: 10 px; à gauche: 20px; text-align: left; taille de police: 24px; 

Ou, par exemple, si vous avez un style pour un bouton et que vous voulez produire le même bouton mais avec une autre couleur pour le texte, vous pouvez le faire:

.bouton border: solid 1px # 000; rembourrage: 10px; arrière-plan: # 9f0; couleur: # 0029FF;  .active-button .button (); couleur: #FFF; 

CSS efficace

Normalement, la plupart des développeurs ne pensent pas à un CSS efficace. L'efficacité du CSS se reflète sur le rendu de la page. Si vos styles sont inefficaces, votre application sera restituée lentement par les navigateurs. Un fait intéressant est que les navigateurs analysent les sélecteurs CSS de droite à gauche. Ce qui signifie que le code suivant:

corps ul li a color: # F000; texte-décoration: aucun; 

… N'est pas efficace du tout. C’est parce que le moteur obtiendra tous les balises et devra évaluer chacun des éléments parents pour collecter le style souhaité. Vous devez également savoir qu'en termes d'efficacité, les sélecteurs sont en quelque sorte classés dans l'ordre suivant: ID, classe, étiquette et universel. Cela signifie qu'un élément avec un identifiant set sera rendu plus rapidement qu'un élément avec juste un sélecteur de balises. Bien sûr, il n’est pas judicieux d’ajouter des identifiants sur tous les éléments de l’arborescence DOM, mais vous devez absolument vérifier votre code et l’améliorer si possible. Par exemple, si vous avez quelque chose comme ceci:

ul #navigation li background: # ff0232; 

Vous devriez enlever le ul partie, parce que vous avez un seul #la navigation élément sur la page. Ou dans le sélecteur suivant:

body .content p taille de la police: 20px; 

Il est clair que le .contenu L'élément est un enfant du corps étiquette. Tous les éléments sont en réalité des enfants de cet élément.

Voici deux liens utiles sur le sujet: developers.google.com et css-tricks.com.

Taille du fichier

Comme nous l’avons mentionné ci-dessus, il est bon d’avoir le moins de code possible, car le navigateur ne restitue pas la page avant de télécharger le fichier CSS. Voici quelques astuces pour réduire la taille du fichier.

Combinez des styles similaires:

.en-tête taille de la police: 24px;  .content font-size: 24px; 

… Se transforme en:

.en-tête, .content taille de la police: 24px; 

Utilisez des raccourcis. Au lieu de:

.entête background-color: # 999999; background-image: url (… /images/header.jpg); position de fond: en haut à droite; 

Écrivez-le de cette façon:

.header background: # 999 url (… /images/header.jpg) en haut à droite; 

Minify votre code CSS. Vous pouvez le faire en utilisant un outil qui supprime généralement tous les espaces et les nouvelles lignes. Par exemple, CSSOptimiser ou Minifycss. Il est courant d’utiliser de tels instruments côté serveur de l’application, c’est-à-dire quelque chose d’écrit dans le langage du back-end. Normalement, ces composants réduisent votre code et le servent à l'utilisateur..

Mettez vos fichiers CSS dans le Étiquette

C'est une bonne pratique d'inclure votre .css fichiers dans le tête tag, de cette façon le navigateur le téléchargera en premier.


JavaScript

Réduire le nombre de requêtes HTTP

Identique à votre CSS - il est bon de réduire le nombre de requêtes envoyées au serveur. Dans la plupart des cas, le chargement des fichiers JavaScript n'arrêtera pas le rendu de la page, mais rendra certaines parties de la page non fonctionnelles..

Minify Votre Code

Il y a beaucoup de bibliothèques qui font la minification JavaScript. C'est quelque chose qui réduira la taille des fichiers, mais gardez à l'esprit que dans un environnement de développement, il est bon de garder votre code propre. La plupart de ces outils changent le nom de vos variables et convertissent le tout en une chaîne d'une ligne, ce qui rend le processus de débogage presque impossible..

CommonJS, AMD, RequireJS - Essayez-le

JavaScript nativement ne dispose pas d'un mécanisme de gestion des modules. Donc, toutes ces choses sont inventées pour résoudre ce problème. Ils fournissent une API que vous pouvez utiliser pour définir et utiliser des modules. Par exemple, voici un exemple tiré de http://requirejs.org/:

   Mon exemple de projet     

Mon exemple de projet

À l'intérieur de main.js, vous pouvez utiliser exiger() pour charger les autres scripts dont vous avez besoin:

require (["helper / util"], function (util) // Cette fonction est appelée lorsque scripts / helper / util.js est chargé. // Si util.js appelle define (), cette fonction n'est activée que Les dépendances de // util ont été chargées et l'argument util retiendra // la valeur de module pour "helper / util".);

Utiliser les espaces de noms

Si nous parlons d'organisation du code, nous ne pouvons pas ignorer la partie concernant les espaces de noms. Nativement, il n’existe pas de telle fonctionnalité en JavaScript, mais vous pouvez toujours obtenir la même chose avec un peu de code. Par exemple, si vous souhaitez créer votre propre framework MVC, vous aurez probablement les classes suivantes:

var model = function () …; var view = function () …; contrôleur var = fonction () …;

Si vous laissez les éléments tels qu'ils sont dans le code ci-dessus, ils deviennent alors publics et vos chances de générer des conflits avec d'autres bibliothèques de votre projet sont plus grandes. Donc, les regrouper dans un objet indépendant (espace de nom) rend le framework protégé:

var MyAwesomeFramework = modèle: fonction () …, vue: fonction () …, contrôleur: fonction () …

Suivre les modèles de conception

Il n'est pas nécessaire de réinventer la roue. JavasScript est devenu très populaire et il existe beaucoup de bonnes pratiques. Les modèles de conception sont des solutions réutilisables pour les problèmes courants de programmation. En suivant certains d’entre eux, vous pourrez construire une bonne application. Cependant, si j'essaie de les couvrir tous ici, je devrais écrire un livre, alors en voici quelques-uns:

Motif Constructeur

Utilisez ce modèle pour créer une instance d'un type d'objet spécifique. Voici un exemple:

var Classe = fonction (param1, param2) this.var1 = param1; this.var2 = param2;  Class.prototype = méthode: function () alert (this.var1 + "/" + this.var2); ;

Ou vous pouvez essayer ceci:

fonction Classe (param1, param2) this.var1 = param1; this.var2 = param2; this.method = function () alert (param1 + "/" + param2); ; ; var instance = new Class ("valeur1", "valeur2");

Modèle de module

Le modèle de module nous donne la possibilité de créer des méthodes privées et publiques. Par exemple, dans le code ci-dessous, la variable _indice et la méthode méthode privée sont privés. incrément et getIndex sont publics.

var Module = (function () var _index = 0; var privateMethod = function () return _index * 10; return increment: function () _index + = 1;, getIndex: function () return _index; ;) ();

Modèle d'observateur

Partout où vous voyez un abonnement ou une répartition d'événements, vous verrez probablement ce modèle. Il y a des observateurs qui s'intéressent à quelque chose lié à un objet spécifique. Une fois que l'action se produit, l'objet avertit les observateurs. L’exemple ci-dessous montre comment ajouter un observateur au Utilisateurs objet:

var Users = list: [], listeners: , ajouter: function (name) this.list.push (name: name); this.dispatch ("ajouté par l'utilisateur"); , on: function (nomEvénement, écouteur) if (! this.listeners [nomEvénement]) this.listeners [nomEvénement] = []; this.listeners [eventName] .push (écouteur); , dispatch: function (nom_événement) if (this.listeners [nom_événement]) pour (var i = 0; i 

Modèle d'enchaînement de fonction

Ce modèle est un bon moyen d’organiser l’interface publique de votre module. Cela fait gagner du temps et améliore la lisibilité:

var User = profil: , nom: fonction (valeur) this.profile.name = valeur; retournez ceci; , job: fonction (valeur) this.profile.job = valeur; retournez ceci; , getProfile: function () return this.profile; ; var profile = User.name ("Krasimir Tsonev"). job ("développeur Web"). getProfile (); console.log (profil);

Je recommande fortement de consulter ce livre de Addy Osmani. C'est l'une des meilleures ressources que vous puissiez trouver sur les modèles de conception en JavaScript..


Assets-Pack

Maintenant que nous approchons de la fin de cet article, je souhaite partager quelques réflexions sur la gestion du code CSS et JavaScript sur le serveur. C'est une technique très courante d'ajouter la fusion, la minification et la compilation dans la logique de l'application. Il existe souvent un mécanisme de mise en cache, mais tout se passe pendant l'exécution. Donc, vous avez probablement une certaine logique de code, qui gère la demande de .js ou .css fichiers et sert le contenu approprié. Derrière ce processus se trouve la compilation, la minification ou tout ce que vous utilisez pour stocker vos actifs..

Dans mes derniers projets, j'ai utilisé un outil appelé actifs-pack. C'est vraiment utile et j'expliquerai en détail ce qu'il fait exactement, mais la partie la plus intéressante est la façon dont je l'ai utilisé. Cette bibliothèque est destinée à être utilisée uniquement en mode de développement. Elle ne reste pas dans votre base de code et ne doit pas être déployée sur votre serveur de production..

L'idée est d'utiliser le packer uniquement pendant que vous travaillez sur les actifs (CSS, JS). En fait, il surveille les modifications dans des répertoires spécifiques et compile / empile le code dans un seul fichier. En utilisant cette approche, vous n'avez pas besoin de penser à la minification ou à la compilation. Tout ce que vous avez à faire est simplement d'envoyer le fichier statique compilé à l'utilisateur. Cela augmente les performances de votre application, car elle ne sert que des fichiers statiques et simplifie bien sûr les choses. Vous n'avez pas besoin de configurer quoi que ce soit sur votre serveur ou d'implémenter une logique inutile.

Voici comment vous pouvez configurer et utiliser actifs-pack.

Installation

Cet outil est un module Nodejs. Node doit donc déjà être installé. Si ce n'est pas le cas, rendez-vous sur nodejs.org/download et récupérez le package correspondant à votre système d'exploitation. Après ça:

npm install -g assetspack

Usage

Le module fonctionne avec la configuration JSON. Lorsqu'il est utilisé via la ligne de commande, vous devez placer vos paramètres dans un .JSON fichier.

Via la ligne de commande

Créé un assets.json Fichier et exécutez la commande suivante dans le même répertoire:

assetspack

Si votre fichier de configuration utilise un autre nom ou est dans un autre répertoire, utilisez:

assetspack --config [chemin d'accès au fichier json]

Dans du code

var AssetsPack = require ("assetspack"); var config = [type: "css", regardez: ["css / src"], sortie: "tests /itted / styles.css", minify: true, exclure: ["custom.css"]]; var pack = new AssetsPack (config, function () console.log ("AssetsPack regarde");); pack.onPack (function () console.log ("AssetsPack a fait le travail"););

Configuration

La configuration doit être un fichier / objet JSON valide. C'est juste un tableau d'objets:

[(objet de l'actif), (objet de l'actif), (objet de l'actif),…]

Objet d'actif

La structure de base de l’objet asset est la suivante:

type: (type de fichier / chaîne, pourrait être css, js ou moins par exemple), watch: (répertoire ou répertoires à surveiller / chaîne ou tableau de chaînes /), pack: (répertoire ou répertoires à emballer / chaîne ou tableau de chaînes /.), sortie: (chemin du fichier de sortie / chaîne /), minify: / boolean /, exclure: (tableau de noms de fichiers)

le pack la propriété n'est pas obligatoire. Si vous le manquez, sa valeur est égale à regarder. minifier par défaut est faux.

Voici quelques exemples:

CSS d'emballage

type: "css", regardez: ["tests / data / css", "tests / data / css2"], pack: ["tests / data / css", "tests / data / css2"], sortie: " tests / emballé / styles.css ", minify: true, exclure: [" header.css "]

Emballage JavaScript

type: "js", regarder: "tests / data / js", pack: ["tests / data / js"], sortie: "tests / emballés / scripts.js", minify: true, exclure: ["A .js "]

Emballage .Moins Des dossiers

L'emballage de .Moins fichiers est un peu différent. le pack la propriété est obligatoire et constitue essentiellement votre point d’entrée. Vous devriez importer tous les autres .Moins fichiers là-bas. le exclure la propriété n'est pas disponible ici.

type: "less", regardez: ["tests / data / less"], pack: "tests / data / less / index.less", sortie: "tests / emballés / styles-less.css", minify: true 

Si vous rencontrez des problèmes, veuillez vérifier la tests / emballage-moins.spec.js du dépôt dans GitHub.

Emballage d'autres formats de fichier

actifs-pack fonctionne avec n'importe quel format de fichier. Par exemple, nous pouvons combiner des modèles HTML dans un seul fichier en procédant comme suit:

type: "html", regardez: ["tests / data / tpl"], sortie: "tests /itted / template.html", excluez: ["admin.html"]

La seule chose que vous devriez savoir ici, c'est qu'il n'y a pas de minification.


Conclusion

En tant que développeurs Web frontaux, nous devons essayer d’offrir les meilleures performances possibles à nos utilisateurs. Les conseils ci-dessus ne sont pas censés couvrir tous les aspects de l'organisation et de la performance des actifs, mais ce sont ceux avec lesquels j'ai personnellement traité au cours de mon travail quotidien. N'hésitez pas à partager certains de vos conseils ci-dessous, dans les commentaires..