web-dev-qa-db-fra.com

config.assets.compile = true dans la production Rails, pourquoi pas?

L'application Rails par défaut installée par Rails new a config.assets.compile = false en production.

Et la façon habituelle de faire les choses est d'exécuter rake assets:precompile avant de déployer votre application, afin de vous assurer que tous les actifs de pipeline d'actifs sont compilés.

Alors que se passe-t-il si je mets config.assets.compile = true en production?

Je n'aurai plus besoin de courir precompile. Ce que je crois se produira est la première fois qu'un actif est demandé, il sera compilé. Ce sera une performance frappée cette première fois (et cela signifie que vous avez généralement besoin d’un runtime js en production pour le faire). Mais à part ces inconvénients, une fois que l'actif a été compilé paresseusement, je pense tous les accès ultérieurs à cet actif auront non performance touchée, la performance de l'application sera exactement la même choseavec les ressources précompilées après cette compilation paresseuse initiale. Est-ce vrai?

Y a-t-il quelque chose qui me manque? Y a-t-il d'autres raisons de ne pas définir config.assets.compile = true en production? Si j'ai un environnement d'exécution JS en production et que je suis prêt à accepter le compromis de performances dégradées pour l'accès first d'un actif, en échange de ne pas avoir à exécuter precompile, cela a-t-il un sens?

170
jrochkind

J'ai écrit cette partie du guide.

Vous ne voulez certainement pas vivre la compilation en production.

Lorsque vous avez compilé, voici ce qui se passe:

Chaque demande de fichier dans/assets est transmise à Sprockets. Sur la demande première pour chaque élément d'actif, il est compilé et mis en cache dans le format utilisé par Rails pour le cache (généralement le système de fichiers).

Lors des demandes suivantes, Sprockets reçoit la demande et doit rechercher le nom du fichier avec empreinte digitale, vérifier que le fichier (image) ou les fichiers (css et js) qui composent l'actif n'ont pas été modifiés, puis si une version en cache le sert.

C'est tout dans le dossier des actifs et dans tous les dossiers fournisseur/actifs utilisés par les plugins.

Cela représente beaucoup de frais généraux car, pour être honnête, le code n’est pas optimisé pour la vitesse.

Cela aura une incidence sur la rapidité avec laquelle les ressources sont transmises au client et aura un impact négatif sur les temps de chargement des pages de votre site.

Comparez avec le défaut:

Lorsque les actifs sont précompilés et que la compilation est désactivée, ils sont compilés et empreints avec le code public/assets. Sprockets renvoie une table de mappage des noms de fichiers bruts en empreintes digitales à Rails, qui les écrit dans le système de fichiers. Le fichier manifeste (YML dans Rails 3 ou JSON avec un nom aléatoire dans Rails 4) est chargé en mémoire par Rails au démarrage et mis en cache pour être utilisé par les méthodes d'assistant d'actif.

Cela rend très rapide la génération de pages avec les ressources correctes avec les empreintes digitales correctes, et la distribution des fichiers eux-mêmes s'effectue rapidement sur le serveur Web à partir du système de fichiers. Les deux sont nettement plus rapides que la compilation en direct.

Pour tirer le meilleur parti du pipeline et des empreintes digitales, vous devez définir des en-têtes lointains sur votre serveur Web et activer la compression gzip pour les fichiers js et css. Sprockets écrit les versions des ressources compressées que vous pouvez configurer pour l’utilisation de votre serveur, ce qui vous évite de le faire pour chaque demande.

Les ressources sont ainsi transmises au client le plus rapidement possible et dans la plus petite taille possible, ce qui accélère l'affichage des pages côté client et réduit les demandes (avec un en-tête très lointain).

Donc, si vous compilez en direct, c’est:

  1. Très lent
  2. Manque de compression
  3. Impact sur le temps de rendu des pages

Versus

  1. Aussi vite que possible
  2. Comprimé
  3. Supprimez la compression entendue du serveur (facultatif).
  4. Minimiser le temps de rendu des pages. 

Edit: (Répondre au commentaire suivant)

Le pipeline pourrait être modifié pour précompiler à la première demande, mais certains obstacles majeurs l’empêchent de le faire. La première est qu'il doit y avoir une table de recherche pour les noms avec empreintes digitales ou les méthodes d'assistance sont trop lentes. Dans un scénario de compilation à la demande, il faudrait un moyen d’ajouter à la table de consultation chaque nouvelle ressource compilée ou demandée.

En outre, quelqu'un devrait payer le prix d'une livraison d'actifs lente pendant une période inconnue jusqu'à ce que tous les actifs soient compilés et en place.

La valeur par défaut, où le prix de la compilation de tout est payé en même temps hors ligne, n’a aucune incidence sur les visiteurs du public et garantit que tout fonctionne avant que les choses ne soient mises en ligne.

Le problème est que cela ajoute beaucoup de complexité aux systèmes de production. 

[Edit, June 2015] Si vous lisez ceci parce que vous recherchez une solution pour les temps de compilation lents lors d'un déploiement, vous pouvez envisager de précompiler les actifs localement. Les informations à ce sujet se trouvent dans le guide de pipeline d’actifs . Cela vous permet de précompiler localement uniquement en cas de modification, de le valider, puis de déployer rapidement sans étape de précompilation. 

244
Richard Hulse

Pour avoir moins de frais généraux avec la précompilation.

Precompile everything initially with these settings in production.rb
# Precompile *all* assets, except those that start with underscore
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/

vous pouvez ensuite simplement utiliser des images et des feuilles de style comme "/assets/stylesheet.css" dans * .html.erb ou "/assets/web.png"

7
dbKooper

Pour ceux qui utilisent Heroku:

Si vous déployez sur Herkou, il effectuera automatiquement la précompilation pendant le déploiement si les actifs compilés ne sont pas inclus (c'est-à-dire que public/assets n'est pas validé). Il n'est donc pas nécessaire d'utiliser config.assets.compile = true ni de valider les actifs précompilés.

Les documents de Heroku sont ici . Un CDN est recommandé pour supprimer la charge sur la ressource dynamique.

4
William Denniss

Définir config.asset.compile = false 

Ajouter à votre Gemfile 

group :assets do gem 'turbo-sprockets-Rails3' end 

Installer le paquet

Exécuter rake assets:precompile 

Puis démarrez votre serveur 

1
Mohammed Saleem

Ce ne sera pas la même chose que la précompilation, même après ce premier coup: parce que les fichiers ne sont pas écrits dans le système de fichiers, ils ne peuvent pas être directement servis par le serveur Web. Certains codes Ruby seront toujours impliqués, même s'il ne lit qu'une entrée de cache.

0
Frederick Cheung

Parce qu'il ouvre une vulnérabilité de traversée de répertoire - https://blog.heroku.com/Rails-asset-pipeline-vulnerability

0
Aurel Branzeanu

De l'officiel guide :

À la première demande, les actifs sont compilés et mis en cache, comme indiqué dans la section Développement ci-dessus, et les noms de manifeste utilisés dans les assistants sont modifiés pour inclure le hachage MD5.

Sprockets définit également l'en-tête HTTP Cache-Control sur max-age = 31536000. Cela signale à tous les caches entre votre serveur et le navigateur client que ce contenu (le fichier servi) peut être mis en cache pendant un an. Cela a pour effet de réduire le nombre de demandes de cet actif émanant de votre serveur. l'actif a de bonnes chances d'être dans le cache du navigateur local ou dans un cache intermédiaire.

Ce mode utilise plus de mémoire, fonctionne moins bien que le mode par défaut et n'est pas recommandé.

En outre, l'étape de précompilation ne pose aucun problème si vous utilisez Capistrano pour vos déploiements. Il s'en occupe pour vous. Tu viens de courir

cap deploy

ou (selon votre configuration)

cap production deploy

et vous êtes tous ensemble. Si vous ne l'utilisez toujours pas, je vous recommande vivement de le vérifier.

0
Sergio Tulentsev