Die von installierte Standard-Rails-App rails new
befindet sich config.assets.compile = false
in der Produktion.
Die übliche Vorgehensweise besteht darin, sie rake assets:precompile
vor der Bereitstellung Ihrer App auszuführen , um sicherzustellen, dass alle Asset-Pipeline-Assets kompiliert werden.
Was passiert also, wenn ich config.assets.compile = true
in Produktion gehe?
Ich muss nicht precompile
mehr rennen . Ich glaube , dass ein Asset zum ersten Mal angefordert wird, wenn es angefordert wird. Dies ist beim ersten Mal ein Leistungseinbruch (und dies bedeutet, dass Sie in der Regel eine js-Laufzeit in der Produktion benötigen, um dies zu tun). Abgesehen von diesen Nachteilen denke ich, dass nach dem trägen Kompilieren des Assets alle nachfolgenden Zugriffe auf dieses Asset keinen Leistungseinbruch haben. Die Leistung der App ist genau die gleiche wie bei vorkompilierten Assets nach dieser ersten faulen Kompilierung mit dem ersten Treffer. Ist das wahr?
Fehlt mir etwas? Gibt es noch andere Gründe, nicht config.assets.compile = true
in Produktion zu gehen? Wenn ich eine JS-Laufzeit in der Produktion habe und bereit bin, den Kompromiss zwischen Leistungseinbußen beim ersten Zugriff auf ein Asset einzugehen, um nicht ausgeführt zu werden precompile
, ist dies sinnvoll?
Antworten:
Ich habe diesen Teil des Leitfadens geschrieben.
Sie möchten definitiv nicht live in der Produktion kompilieren.
Wenn Sie kompiliert haben, geschieht Folgendes:
Jede Anforderung für eine Datei in / Assets wird an Sprockets übergeben. Bei der ersten Anforderung für jedes einzelne Asset wird es kompiliert und in dem Rache zwischengespeichert, der von Rails für den Cache verwendet wird (normalerweise im Dateisystem).
Bei nachfolgenden Anforderungen empfängt Sprockets die Anforderung und muss den Dateinamen mit dem Fingerabdruck nachschlagen, überprüfen, ob die Datei (Bild) oder Dateien (CSS und JS), aus denen das Asset besteht, nicht geändert wurden, und wenn eine zwischengespeicherte Version vorhanden ist, wird dies bereitgestellt.
Das ist alles im Assets-Ordner und in allen Lieferanten- / Assets-Ordnern, die von Plugins verwendet werden.
Das ist viel Aufwand, da der Code ehrlich gesagt nicht auf Geschwindigkeit optimiert ist.
Dies wirkt sich darauf aus, wie schnell das Asset über die Leitung zum Client geleitet wird, und wirkt sich negativ auf die Ladezeiten Ihrer Website aus.
Vergleichen Sie mit der Standardeinstellung:
Wenn Assets vorkompiliert werden und die Kompilierung deaktiviert ist, werden Assets kompiliert und mit einem Fingerabdruck versehen
public/assets
. Sprockets gibt eine Zuordnungstabelle der einfachen Dateinamen mit Fingerabdruck an Rails zurück, und Rails schreibt diese in das Dateisystem. Die Manifestdatei (YML in Rails 3 oder JSON mit einem zufälligen Namen in Rails 4) wird beim Start von Rails in den Speicher geladen und zur Verwendung durch die Asset-Helper-Methoden zwischengespeichert.Dies macht die Generierung von Seiten mit den richtigen Fingerabdruck-Assets sehr schnell, und die Bereitstellung der Dateien selbst erfolgt schnell vom Webserver aus dem Dateisystem. Beides dramatisch schneller als Live-Kompilierung.
Um den maximalen Vorteil der Pipeline und des Fingerabdrucks zu erzielen, müssen Sie auf Ihrem Webserver Header für die Zukunft festlegen und die GZIP-Komprimierung für JS- und CSS-Dateien aktivieren. Sprockets schreibt komprimierte Versionen von Assets, die Sie für die Verwendung auf Ihrem Server festlegen können, ohne dass dies für jede Anforderung erforderlich ist.
Dadurch werden Assets so schnell wie möglich und in der kleinstmöglichen Größe an den Client gesendet, wodurch die clientseitige Anzeige der Seiten beschleunigt und Anforderungen (mit Header in ferner Zukunft) reduziert werden.
Wenn Sie also live kompilieren, ist dies:
Gegen
Bearbeiten: (Antwort auf nachfolgenden Kommentar)
Die Pipeline könnte bei der ersten Anforderung geändert werden, um vorkompiliert zu werden, aber es gibt einige wichtige Hindernisse dafür. Das erste ist, dass es eine Nachschlagetabelle für Namen mit Fingerabdrücken geben muss, oder die Hilfsmethoden sind zu langsam. Unter einem Compile-on-Demand-Szenario müsste es eine Möglichkeit geben, an die Nachschlagetabelle anzuhängen, wenn jedes neue Asset kompiliert oder angefordert wird.
Außerdem müsste jemand den Preis für eine langsame Lieferung von Vermögenswerten für einen unbekannten Zeitraum zahlen, bis alle Vermögenswerte zusammengestellt und vorhanden sind.
Die Standardeinstellung, bei der der Preis für die Kompilierung alles gleichzeitig offline bezahlt wird, wirkt sich nicht auf die öffentlichen Besucher aus und stellt sicher, dass alles funktioniert, bevor die Dinge live gehen.
Der Deal-Breaker ist, dass es Produktionssystemen viel Komplexität verleiht.
[Bearbeiten, Juni 2015] Wenn Sie dies lesen, weil Sie nach einer Lösung für langsame Kompilierungszeiten während einer Bereitstellung suchen, können Sie die Assets lokal vorkompilieren. Informationen hierzu finden Sie im Asset-Pipeline-Handbuch . Auf diese Weise können Sie nur dann lokal vorkompilieren, wenn eine Änderung vorliegt, diese festschreiben und dann eine schnelle Bereitstellung ohne Vorkompilierungsphase durchführen.
quelle
Weniger Aufwand beim Vorkompilieren.
Sie können dann einfach Bilder und Stylesheets als "/assets/stylesheet.css" in * .html.erb oder "/assets/web.png" verwenden.
quelle
Für alle, die Heroku verwenden:
Wenn Sie auf Herkou bereitstellen, wird die Vorkompilierung während der Bereitstellung automatisch für Sie durchgeführt, wenn kompilierte Assets nicht enthalten sind (dh
public/assets
nicht festgeschrieben sind), sodassconfig.assets.compile = true
die vorkompilierten Assets nicht erforderlich sind oder festgeschrieben werden müssen .Herokus Dokumente sind hier . Ein CDN wird empfohlen, um die Last auf der Dyno-Ressource zu entfernen.
quelle
Dies ist auch nach dem ersten Treffer nicht dasselbe wie Vorkompilieren: Da die Dateien nicht in das Dateisystem geschrieben wurden, können sie nicht direkt vom Webserver bereitgestellt werden. Es wird immer etwas Ruby-Code beteiligt sein, selbst wenn er nur einen Cache-Eintrag liest.
quelle
precompile=true
, die kompilierten Assets in das Dateisystem geschrieben werden würden. Bist du sicher? Lassen Sie mich überprüfen ...tmp/cache
anstattpublic/assets
, so keinen Platz , dass der Webserver sehen können, sie gehen nach wie vor von den Schienen bedient werden App nicht der Webserver. bla. ist das richtig, denkst du?einstellen
config.asset.compile = false
Fügen Sie Ihrem Gemfile hinzu
group :assets do gem 'turbo-sprockets-rails3' end
Installieren Sie das Bundle
Lauf
rake assets:precompile
Starten Sie dann Ihren Server
quelle
config.asset.compile = true in production.rb
Datei eingestellt habe, wird kein Pre-Comple-Mechanismus hinzugefügt. Aus diesem Grund dauert das Laden der Seite bei jedem Start des Servers zu lange (wenn die Anforderung sowohl die Verarbeitung der Anforderung als auch das Kompilieren von Assets betrifft). Jetzt habe ichturbo-sprockets-rails3
in Gemfile aufgenommen und den Befehl ausgeführt,rake assets:precompile
der die Assets zuvor kompiliert. Jetzt setzeconfig.asset.compile = false in production.rb
und starte ich den Server, die Seite wird ohne Verzögerung geladen. (Nur Bearbeitung der Anfrage ohne Zusammenstellung von Vermögenswerten)turbo-sprockets-rails3
nur für Ruby 3Aus dem offiziellen Leitfaden :
Außerdem ist der Vorkompilierungsschritt überhaupt kein Problem, wenn Sie Capistrano für Ihre Bereitstellungen verwenden. Es kümmert sich um Sie. Du rennst einfach
oder (abhängig von Ihrem Setup)
und du bist fertig. Wenn Sie es immer noch nicht verwenden, empfehle ich dringend, es auszuprobieren.
quelle
Weil es eine Directory Traversal-Sicherheitsanfälligkeit öffnet - https://blog.heroku.com/rails-asset-pipeline-vulnerability
quelle