Catégories
Astuces et Design

Lutte contre les actifs statiques et les fichiers multimédias (Partie 4) – Smashing Magazine

A propos de l'auteur

Philip Kiely écrit du code et des mots. Il est l'auteur de Writing for Software Developers (2020). Philip est titulaire d'un B.A. avec mention en informatique de…
Plus à propos
Philippe
Kiely

Les développeurs et concepteurs frontaux créent des ressources statiques incroyables pour les applications Web. Aujourd'hui, nous nous concentrons sur ce qui se passe après que le correctif de style ou le beau graphique que vous venez de terminer est poussé à maîtriser. Nous étudierons également la gestion des fichiers que les utilisateurs téléchargent, appelés fichiers multimédias. Ensemble, nous développerons une intuition pour les stratégies disponibles aux développeurs Django pour servir ces fichiers aux utilisateurs du monde entier de manière sécurisée, performante et rentable.

Les sites Web Django impliquent beaucoup de fichiers. Ce n'est pas seulement du code source pour la configuration, les modèles, les vues et les modèles, mais aussi des actifs statiques: CSS et JavaScript, images, icônes. Comme si cela ne suffisait pas déjà, parfois les utilisateurs viennent et souhaitent télécharger leurs propres fichiers sur votre site Web. Il suffit de rendre tout développeur incrédule. Des fichiers partout!

Voici où je souhaiterais pouvoir dire (sans réserves): "Ne vous inquiétez pas, Django vous soutient!" Mais malheureusement, lorsqu'il s'agit d'actifs statiques et de fichiers multimédias, il existe un lot de mises en garde à traiter.

Aujourd'hui, nous aborderons le stockage et la diffusion de fichiers pour des déploiements à serveur unique et évolutifs tout en tenant compte de facteurs tels que la compression, la mise en cache et la disponibilité. Nous discuterons également des coûts et des avantages des CDN et des solutions de stockage de fichiers dédiées.

Remarque: Ce n'est pas un tutoriel sur la façon de déployer un site Django sur une plateforme spécifique. Au lieu de cela, comme les autres articles de la série Django Highlights (voir ci-dessous), il est destiné à servir de guide aux développeurs et concepteurs frontaux pour comprendre d'autres parties du processus de création d'une application Web. Aujourd'hui, nous nous concentrons sur ce qui se passe après que le correctif de style ou le beau graphique que vous venez de terminer est poussé à maîtriser. Ensemble, nous développerons une intuition pour les stratégies disponibles aux développeurs Django pour servir ces fichiers aux utilisateurs du monde entier de manière sécurisée, performante et rentable.

Pièces précédentes Dans la serie:

  • Partie 1: Modèles d'utilisateurs et authentification
  • Partie 2: Le modèle sauve des lignes
  • Partie 3: Modèles, administration et exploitation de la base de données relationnelle

Définitions

La plupart de ces termes sont assez simples, mais cela vaut la peine de prendre un moment pour établir un vocabulaire partagé pour cette discussion.

Les trois types de fichiers dans une application Django en direct sont:

  1. Code source
    Les fichiers Python et HTML créés avec le framework Django. Ces fichiers sont au cœur de l'application. Les fichiers de code source sont généralement assez petits, mesurés en kilo-octets.
  2. Fichiers statiques
    Également appelés «actifs statiques», ces fichiers incluent CSS et JavaScript, tous deux écrits par le développeur de l'application et des bibliothèques tierces, ainsi que des fichiers PDF, des programmes d'installation de logiciels, des images, de la musique, des vidéos et des icônes. Ces fichiers sont uniquement utilisés côté client. Les fichiers statiques vont de quelques kilo-octets de CSS à des gigaoctets de vidéo.
  3. Fichiers multimédias
    Tout fichier téléchargé par un utilisateur, des images de profil aux documents personnels, est appelé fichier multimédia. Ces fichiers doivent être stockés et récupérés de manière sécurisée et fiable pour l'utilisateur. Les fichiers multimédias peuvent être de n'importe quelle taille, l'utilisateur peut télécharger quelques kilo-octets de texte en clair sur quelques gigaoctets de vidéo. Si vous êtes à la dernière extrémité de cette échelle, vous aurez probablement besoin de conseils plus spécialisés que celui que cet article est prêt à donner.

Les deux types de déploiements Django sont:

  1. Serveur unique
    Un déploiement Django à serveur unique est exactement ce à quoi il ressemble: tout vit sur un seul serveur. Cette stratégie est très simple et ressemble étroitement à l'environnement de développement, mais ne peut pas gérer efficacement des volumes de trafic importants ou incohérents. L'approche à serveur unique ne s'applique qu'aux projets d'apprentissage ou de démonstration, et non aux applications en mode réel qui nécessitent une disponibilité fiable.
  2. Évolutif
    Il existe de nombreuses façons différentes de déployer un projet Django qui lui permettent d'évoluer pour répondre à la demande des utilisateurs. Ces stratégies impliquent souvent la rotation de nombreux serveurs et l'utilisation d'outils tels que les équilibreurs de charge et les bases de données gérées. Heureusement, nous pouvons regrouper efficacement tout ce qui est plus complexe qu'un déploiement sur un seul serveur dans cette catégorie aux fins de cet article.

Option 1: Django par défaut

Les petits projets bénéficient d'une architecture simple. La gestion par défaut de Django des ressources statiques et des fichiers multimédias est tout simplement: simple. Pour chacun, vous avez un dossier racine qui stocke les fichiers et se trouve juste à côté du code source sur le serveur. Facile. Ces dossiers racine sont générés et gérés principalement via le votreprojet / settings.py configuration.

Actifs statiques

La chose la plus importante à comprendre lorsque vous travaillez avec des fichiers statiques dans Django est la python manage.py collectstatic commander. Cette commande passe à travers le statique dossier de chaque application dans le projet Django et copie tous les actifs statiques dans le dossier racine. L'exécution de cette commande est une partie importante du déploiement d'un projet Django. Considérez la structure de répertoires suivante:

- project
  - project
    - settings.py
    - urls.py
    - ...
  - app1
    - static/
      - app1
        - style.css
        - script.js
        - img.jpg
    - templates/
    - views.py
    - ...
  - app2
    - static/
      - app2
        - style.css
        - image.png
    - templates/
    - views.py
    - ...

Supposez également les paramètres suivants dans projet / settings.py:

STATIC_URL = "/static/"
STATIC_ROOT = "/path/on/server/to/djangoproject/static"

Exécution du python manage.py collectstatic La commande créera le dossier suivant sur le serveur:

- /path/on/server/to/djangoproject/static
  - app1
    - style.css
    - script.js
    - img.jpg
  - app2
    - style.css
    - image.png

Notez que dans chaque dossier statique, il existe un autre dossier portant le nom de l'application. Cela permet d'éviter les conflits d'espaces de noms après la collecte des fichiers statiques; comme vous pouvez le voir dans la structure de fichiers ci-dessus, cela conserve app1 / style.css et app2 / style.css distinct. À partir de là, l'application recherchera des fichiers statiques dans cette structure au STATIC_ROOT pendant la production. En tant que tel, référencez les fichiers statiques comme suit dans un modèle dans app1 / templates /:

{% load static %}

Django détermine automatiquement où obtenir le fichier statique en cours de développement pour modéliser ce comportement, vous n'avez pas besoin d'exécuter collectstatic pendant le développement.

Pour plus de détails, consultez la documentation Django.

Fichiers multimédias

Imaginez un site de réseautage professionnel avec une base de données d'utilisateurs. Chacun de ces utilisateurs aurait un profil associé, qui pourrait contenir, entre autres, une image d'avatar et un document de CV. Voici un court exemple de modèle de ces informations:

from django.db import models
from django.contrib.auth.models import User

def avatar_path(instance, filename):
    return "avatar_{}_{}".format(instance.user.id, filename)

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    resume = models.FileField(upload_to="path/string")
    avatar = models.ImageField(upload_to=avatar_path)

Pour que cela fonctionne, vous avez besoin des options suivantes dans projet / settings.py, comme pour les actifs statiques:

MEDIA_URL = "/media/"
MEDIA_ROOT = "/path/on/server/to/media"

Une ImageField hérite de FileField, il partage donc les mêmes paramètres et capacités. Les deux champs ont une option upload_to , qui prend une chaîne qui est un chemin d'accès et l'ajoute à la MEDIA_ROOT pour stocker le fichier, qui est ensuite accessible par le même chemin en haut de MEDIA_URL. le upload_to L'argument peut également prendre une fonction qui renvoie une chaîne, comme illustré avec le avatar_path fonction.

Assurez-vous d'omettre le répertoire des fichiers multimédias et son contenu du contrôle de version. Son contenu peut entrer en conflit lorsque deux développeurs testent la même application sur des machines différentes et, contrairement aux actifs statiques, il ne fait pas partie de l'application Django déployable.

Option 2: Django avec services

Ma philosophie d’orientation consiste à utiliser des outils dans lesquels ils sont les meilleurs. Django est un cadre incroyable, et il fournit d'excellents outils prêts à l'emploi pour l'authentification des utilisateurs, le rendu côté serveur, le travail avec les modèles et les formulaires, les fonctions administratives et des dizaines d'autres aspects essentiels de la création d'applications Web. Cependant, ses outils pour gérer les actifs statiques et les fichiers multimédias ne sont pas, à mon avis, bien adaptés à la production sur des sites évolutifs. Les développeurs principaux de Django reconnaissent que de nombreuses personnes choisissent des approches alternatives pour gérer ces fichiers en production; le cadre est très bon pour sortir de votre chemin lorsque vous le faites. La plupart des sites Django destinés à un usage général voudront incorporer des actifs statiques et gérer des fichiers multimédias en utilisant ces approches non spécifiques à Django.

Actifs statiques sur un CDN

Alors que les petits et moyens projets peuvent s'en tirer sans un, un CDN (réseau de diffusion de contenu) est facile à utiliser et améliore les performances des applications de toute taille. Un CDN est un réseau de serveurs, généralement dans le monde entier, qui distribue et sert du contenu Web, principalement des actifs statiques. Les CDN populaires incluent Cloudflare CDN, Amazon CloudFront et Fastly. Pour utiliser un CDN, vous téléchargez vos fichiers statiques, puis dans votre application, référencez-les comme suit:

Ce processus est facile à intégrer à vos scripts de déploiement Django. Après avoir exécuté le python manage.py collectstatic , copiez le répertoire généré sur votre CDN (un processus qui varie considérablement en fonction du service que vous utilisez), puis supprimez les actifs statiques du package de déploiement Django.

En développement, vous souhaiterez accéder à différentes copies de vos actifs statiques qu'en production. De cette façon, vous pouvez apporter des modifications localement sans affecter le site de production. Vous pouvez utiliser des ressources locales ou exécuter une deuxième instance du CDN pour remettre les fichiers. Configurer votreprojet / settings.py avec une variable personnalisée, comme CDN_URLet utilisez cette valeur dans vos modèles pour vous assurer que vous utilisez la bonne version des éléments en développement et en production.

Une dernière remarque est que de nombreuses bibliothèques pour CSS et JavaScript ont des CDN gratuits que la plupart des sites Web peuvent utiliser. Si vous chargez, par exemple, Bootstrap 4 ou underscore.js, vous pouvez éviter les tracas liés à l'utilisation de votre propre copie en développement et les frais liés à la diffusion de vos propres copies en production en utilisant ces CDN publics.

Fichiers multimédias avec un magasin de fichiers dédié

Aucun site Django de production ne devrait stocker les fichiers utilisateur dans un simple /médias/ dossier quelque part sur le serveur qui exécute le site. Voici trois des nombreuses raisons de ne pas le faire:

  1. Si vous avez besoin de faire évoluer le site en ajoutant plusieurs serveurs, vous avez besoin d'un moyen de copier et de synchroniser les fichiers téléchargés sur ces serveurs.
  2. Si un serveur tombe en panne, le code source est sauvegardé dans votre système de contrôle de version, mais les fichiers multimédias ne sont pas sauvegardés par défaut, sauf si vous avez configuré votre serveur pour le faire, mais pour cet effort, vous feriez mieux d'utiliser un serveur dédié filestore.
  3. En cas d'activité malveillante, il est préférable de conserver les fichiers téléchargés par les utilisateurs sur un serveur distinct de celui qui exécute l'application, bien que cela ne supprime en aucun cas l'exigence de valider les fichiers téléchargés par les utilisateurs.

L'intégration d'un tiers pour stocker vos fichiers téléchargés par l'utilisateur est vraiment facile. Vous n'avez pas besoin de changer quoi que ce soit dans votre code, sauf peut-être supprimer ou modifier le upload_to valeur de FileFields dans vos modèles et en configurant quelques paramètres. Par exemple, si vous envisagez de stocker vos fichiers dans AWS S3, vous souhaitez effectuer les opérations suivantes, qui sont très similaires au processus de stockage de fichiers avec Google Cloud, Azure, Backblaze ou des services concurrents similaires.

Tout d'abord, vous devrez installer les bibliothèques boto3 et django-storages. Ensuite, vous devez configurer un compartiment et un rôle IAM sur AWS, qui sort du cadre de cet article, mais vous pouvez voir les instructions ici. Une fois que tout cela est configuré, vous devez ajouter trois variables à votre projet / settings.py:

DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
AWS_STORAGE_BUCKET_NAME = "BUCKET_NAME"
AWS_S3_REGION_NAME = "us-east-2"

De plus, vous devrez configurer l'accès aux informations d'identification à votre compartiment AWS. Certains didacticiels montrent comment ajouter un ID et une clé secrète à votre fichier de paramètres ou en tant que variables d'environnement, mais ce sont des pratiques non sécurisées. Utilisez plutôt django-storages avec l'AWS CLI pour configurer les clés, comme décrit ici. Vous pouvez également être intéressé par le django-storages Documentation.

Vous ne voulez pas que les fichiers de développement ou de test soient mélangés avec les téléchargements d'utilisateurs réels. Il est assez simple d'éviter cela: configurez plusieurs compartiments, un pour le développement (ou un pour chaque développeur), un pour les tests et un pour la production. Ensuite, tout ce que vous devez changer est le AWS_STORAGE_BUCKET_NAME par environnement et vous êtes prêt à partir.

Performance et disponibilité

De nombreux facteurs affectent les performances et la fiabilité de votre site Web. En voici quelques-uns importants lors de l'examen des fichiers statiques et multimédias qui importent quelle que soit l'approche que vous adoptez pour les gérer.

Coût

Servir des fichiers à un utilisateur coûte de l'argent pour deux raisons: le stockage et la bande passante. Vous devez payer le fournisseur d'hébergement pour stocker les fichiers pour vous, mais vous devez également les payer pour servir les fichiers. La bande passante est beaucoup plus chère que le stockage (par exemple, AWS S3 facture 2,3 cents par gigaoctet pour le stockage contre 9 cents par gigaoctet de transfert de données vers Internet au moment de la rédaction). L'économie d'un magasin de fichiers comme S3 ou un CDN est différente de celle d'un hôte généralisé comme une gouttelette d'océan numérique. Profitez de la spécialisation et des économies d'échelle en déplaçant des fichiers coûteux vers des services conçus pour eux. En outre, de nombreux magasins de fichiers et CDN offrent des plans gratuits afin que les sites qui pourraient être assez petits pour s'en tirer sans les utiliser puissent le faire et en tirer les avantages sans coûts d'infrastructure supplémentaires.

Compression et transcodage

La plupart des problèmes causés par les ressources statiques comme les photos et les vidéos sont dus au fait qu'il s'agit de gros fichiers. Naturellement, les développeurs résolvent ce problème en essayant de réduire la taille de ces fichiers. Il existe plusieurs façons de le faire en utilisant un mélange de compression et de transcodage dans deux catégories générales: sans perte et avec perte. La compression sans perte conserve la qualité d'origine des actifs mais permet une diminution relativement modeste de la taille du fichier. La compression avec perte ou le transcodage dans un format avec perte permet des tailles de fichier beaucoup plus petites au détriment de la perte d'une partie de la qualité de l'artefact d'origine. Un exemple de ceci est le transcodage de la vidéo à un débit binaire inférieur. Pour plus de détails, consultez cet article sur l'optimisation de la diffusion vidéo. Lorsque vous servez de gros fichiers sur le Web, les vitesses de bande passante exigent souvent que vous serviez des artefacts hautement compressés, nécessitant une compression avec perte.

À moins que vous ne soyez sur YouTube, la compression et le transcodage ne se produisent pas à la volée. Les ressources statiques doivent être formatées de manière appropriée avant le déploiement, et vous pouvez appliquer des restrictions de type et de taille de fichier de base sur les téléchargements d'utilisateurs pour assurer une compression suffisante et une mise en forme appropriée dans les fichiers multimédias de vos utilisateurs.

Minification

Bien que les fichiers JavaScript et CSS ne soient généralement pas aussi volumineux que les images, ils peuvent souvent être compressés pour se réduire en moins d'octets. Ce processus est appelé minification. La minification ne modifie pas l'encodage des fichiers, ils sont toujours du texte et un fichier minifié doit toujours être un code valide pour sa langue d'origine. Les fichiers minifiés conservent leurs extensions d'origine.

La principale chose supprimée dans un fichier minifié est les espaces inutiles, et du point de vue de l'ordinateur, presque tous les espaces en CSS et JavaScript sont inutiles. Les schémas de minification raccourcissent également les noms de variables et suppriment les commentaires.

La minification par défaut obscurcit le code; en tant que développeur, vous devez travailler exclusivement avec des fichiers non minifiés. Une étape automatique au cours du processus de déploiement devrait réduire les fichiers avant qu'ils ne soient stockés et servis. Si vous utilisez une bibliothèque fournie par un CDN tiers, assurez-vous d'utiliser la version réduite de cette bibliothèque si elle est disponible. Les fichiers HTML peuvent être minifiés, mais comme Django utilise le rendu côté serveur, le coût de traitement de le faire à la volée dépasserait très probablement la petite diminution de la taille de la page.

Disponibilité globale

Tout comme il faut moins de temps pour envoyer une lettre à votre voisin que pour l'envoyer à travers le pays, il faut moins de temps pour transmettre des données à proximité qu'à travers le monde. L'une des façons dont un CDN améliore les performances des pages consiste à copier des actifs sur des serveurs à travers le monde. Ensuite, lorsqu'un client fait une demande, il reçoit les actifs statiques du serveur le plus proche (souvent appelé nœud périphérique), ce qui réduit les temps de chargement. L'un des avantages de l'utilisation d'un CDN avec un site Django est de découpler la distribution globale de vos actifs statiques de la distribution globale de votre code.

Mise en cache côté client

Quoi de mieux que d'avoir un fichier statique sur un serveur proche de votre utilisateur? Avoir le fichier statique déjà stocké sur l'appareil de votre utilisateur! La mise en cache est le processus de stockage des résultats d'un calcul ou d'une requête afin qu'ils soient accessibles plusieurs fois plus rapidement. Tout comme une feuille de style CSS peut être mise en cache dans le monde entier dans un CDN, elle peut être mise en cache dans le navigateur du client lors du premier chargement d'une page à partir de votre site. Ensuite, la feuille de style est disponible sur le périphérique lui-même dans les requêtes suivantes, de sorte que le client effectue moins de requêtes, améliore le temps de chargement des pages et diminue l'utilisation de la bande passante.

Les navigateurs effectuent leurs propres opérations de mise en cache, mais si votre site bénéficie d'un trafic important, vous pouvez optimiser votre comportement de mise en cache côté client à l'aide de l'infrastructure de cache de Django.

En conclusion

Encore une fois, ma philosophie directrice consiste à utiliser des outils pour ce qu'ils font de mieux. Les projets à serveur unique et les petits déploiements évolutifs avec uniquement des actifs statiques légers peuvent utiliser la gestion des actifs statiques intégrée de Django, mais la plupart des applications doivent séparer les actifs à servir sur un CDN.

Si votre projet est destiné à tout type d'utilisation réelle, ne stockez pas de fichiers multimédias avec la méthode par défaut de Django, utilisez plutôt un service. Avec suffisamment de trafic, où «suffisamment de trafic» est un nombre relativement faible à l'échelle d'Internet, les complications supplémentaires de l'architecture, du processus de développement et du déploiement en valent largement la peine pour les performances, la fiabilité et les économies de coûts liées à l'utilisation d'un CDN et solution de stockage de fichiers séparés pour les fichiers statiques et multimédias, respectivement.

lecture recommandée

  • Partie 1: Modèles d'utilisateurs et authentification
  • Partie 2: Le modèle sauve des lignes
  • Partie 3: Modèles, administration et exploitation de la base de données relationnelle
Smashing Editorial(dm, ra, yk, il)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *