config.assets.compile = true w produkcji Railsów, dlaczego nie?

185

Domyślna aplikacja Railsów zainstalowana przez rails newma config.assets.compile = falsew produkcji.

A zwykłym sposobem na wykonanie czynności jest uruchomienie rake assets:precompileprzed wdrożeniem aplikacji, aby upewnić się, że wszystkie zasoby potoku zasobów są skompilowane.

Co się stanie, jeśli ustawię config.assets.compile = trueprodukcję?

Nie będę już musiał biec precompile. Co ja wierzę stanie się to po raz pierwszy dany składnik aktywów jest wymagane, zostanie skompilowany. Będzie to hit wydajności po raz pierwszy (i oznacza to ogólnie, że potrzebujesz do tego środowiska uruchomieniowego js). Ale oprócz tych wad, po leniwym skompilowaniu zasobu, myślę, że cały późniejszy dostęp do tego zasobu nie będzie miał negatywnego wpływu na wydajność, wydajność aplikacji będzie dokładnie taka sama jak w przypadku wstępnie skompilowanych zasobów po tej pierwszej leniwej kompilacji. czy to prawda?

Czy czegoś mi brakuje? Czy są jakieś inne powody, aby nie wprowadzać do config.assets.compile = trueprodukcji? Jeśli mam środowisko uruchomieniowe JS w produkcji i jestem gotów skorzystać z obniżonej wydajności przy pierwszym dostępie do zasobu w zamian za brak konieczności uruchamiania precompile, czy ma to sens?

jrochkind
źródło
1
Uwaga, starsze wersje zębatek zawierają błąd, a jeśli config.assets.compile jest skonfigurowany na wartość true, istnieje ryzyko podatności na uszkodzenie katalogu ( blog.heroku.com/rails-asset-pipeline-vulnerability )
Mauro
Dokładnie tak powinien działać Stackoverflow. Dobrze napisane pytanie i dobrze napisana odpowiedź. Kocham was zarówno op, jak i @ richard-hulse.
schmijos

Odpowiedzi:

259

Napisałem ten fragment przewodnika.

Na pewno nie chcesz kompilować na żywo podczas produkcji.

Po kompilacji dzieje się tak:

Każde żądanie pliku w / zasobach jest przekazywane do Sprockets. Na pierwsze żądanie dla każdego zasobu jest on kompilowany i buforowany w cokolwiek, czego Rails używa do buforowania (zwykle system plików).

Przy kolejnych żądaniach Sprockets odbiera żądanie i musi wyszukać nazwę pliku odcisków palców, sprawdzić, czy plik (obraz) lub pliki (css i js), które tworzą zasób, nie zostały zmodyfikowane, a następnie, jeśli istnieje wersja buforowana, obsługuj to.

To wszystko w folderze zasobów i we wszystkich folderach dostawców / zasobów używanych przez wtyczki.

Jest to duże obciążenie, ponieważ, szczerze mówiąc, kod nie jest zoptymalizowany pod kątem szybkości.

Będzie to miało wpływ na szybkość przesyłu danych do klienta i wpłynie negatywnie na czas ładowania strony w Twojej witrynie.

Porównaj z domyślnymi:

Gdy zasoby są wstępnie kompilowane, a kompilacja wyłączona, zasoby są kompilowane i pobierane odciskami palców do pliku public/assets. Sprockets zwraca Railsowi tabelę mapowania zwykłych na nazwy plików odcisków palców, a Railsy zapisują to w systemie plików. Plik manifestu (YML w Railsach 3 lub JSON z losową nazwą w Railsach 4) jest ładowany do pamięci przez Railsy podczas uruchamiania i buforowany w celu użycia przez metody pomocnika zasobów.

To sprawia, że ​​generowanie stron z prawidłowymi zasobami odcisków palców jest bardzo szybkie, a same serwery plików są szybko obsługiwane przez serwer WWW z systemu plików. Oba są znacznie szybsze niż kompilowanie na żywo.

Aby uzyskać maksymalne korzyści z potoku i pobierania odcisków palców, musisz ustawić dalekosiężne nagłówki na swoim serwerze internetowym i włączyć kompresję gzip dla plików js i css. Sprockets zapisuje skompresowane wersje zasobów, które możesz ustawić dla swojego serwera, eliminując potrzebę, aby robił to dla każdego żądania.

Dzięki temu zasoby są wysyłane do klienta tak szybko, jak to możliwe, w możliwie najmniejszym rozmiarze, przyspieszając wyświetlanie stron po stronie klienta i zmniejszając (przy pomocy nagłówków w przyszłości).

Jeśli więc kompilujesz na żywo, jest to:

  1. Bardzo wolno
  2. Brak kompresji
  3. Wpłynie na czas renderowania stron

Przeciw

  1. Tak szybko, jak to możliwe
  2. Sprężony
  3. Usuń podsłuchaną kompresję z serwera (opcjonalnie).
  4. Minimalizuj czas renderowania stron.

Edycja: (odpowiedź na komentarz uzupełniający)

Rurociąg może zostać zmieniony w celu prekompilacji na pierwsze żądanie, ale istnieją pewne poważne przeszkody, aby to zrobić. Po pierwsze, musi istnieć tabela odnośników dla nazw odcisków palców lub metody pomocnicze są zbyt wolne. W senario kompilacji na żądanie musiałby istnieć sposób dołączenia do tabeli odnośników, ponieważ każdy nowy zasób jest kompilowany lub żądany.

Ponadto ktoś musiałby zapłacić cenę powolnego dostarczania aktywów przez nieznany okres czasu, dopóki wszystkie aktywa nie zostaną skompilowane i wdrożone.

Domyślnie, gdy cena kompilacji wszystkiego jest płacona jednorazowo w trybie off-line, nie ma wpływu na odwiedzających i gwarantuje, że wszystko zadziała, zanim wszystko zacznie działać.

Przełomem jest to, że bardzo komplikuje systemy produkcyjne.

[Edytuj, czerwiec 2015 r.] Jeśli czytasz to, ponieważ szukasz rozwiązania na długie czasy kompilacji podczas wdrażania, możesz rozważyć lokalną prekompilację zasobów. Informacje na ten temat znajdują się w przewodniku potoku zasobów . Umożliwia to lokalną prekompilację tylko w przypadku zmiany, zatwierdzenie jej, a następnie szybkie wdrożenie bez etapu prekompilacji.

Richard Hulse
źródło
1
Dziękuję, zaakceptowałem twoją odpowiedź. Ale teraz moje pytanie brzmi: OK, nie robi tego teraz, ale możliwe jest, że myślisz, że Asset Pipeline może mieć funkcję, w której leniwie kompiluje się na pierwsze żądanie, robiąc to dokładnie tak, jak prekompilacja, w tym pisanie do ./public i aktualizowanie manifest odcisku palca?
jrochkind
Patrz wyżej. Czy to problem, ponieważ Capistrano nie działa dla Ciebie?
Richard Hulse
Nie używam Capistrano. Nie musiałem wcześniej, dodatkowa złożoność nie była tego warta. Być może rurociągiem aktywów jest słoma, która rozbija wielbłądy i wymaga ich. Czy Twoim zdaniem nie jest możliwe zarządzanie wdrożeniami Railsów za pomocą potoku zasobów bez capistrano lub podobnego? Szkoda, bo w przypadku prostych konfiguracji nie było to dużym problemem ręcznie.
jrochkind
Naprawdę potrzebujesz Capistrano dla Rails 3.1. Zasoby są kompilowane w nowym katalogu publicznym, gdy stara aplikacja jest nadal uruchomiona. Po zakończeniu kompilacji nowa wersja jest dowiązana symbolicznie, a serwer restartuje się automatycznie.
Richard Hulse
„Aby uzyskać maksymalne korzyści z potoku i pobierania odcisków palców, musisz ustawić nagłówki w przyszłości na swoim serwerze internetowym i włączyć kompresję gzip dla plików js i css.” - Czy możesz podać jakieś instrukcje lub linki, jak to zrobić to?
Isaac Betesh
7

Aby mieć mniej kosztów ogólnych dzięki kompilacji wstępnej.

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

możesz wtedy po prostu użyć obrazów i arkuszy stylów jako „/assets/stylesheet.css” w * .html.erb lub „/assets/web.png”

dbKooper
źródło
6

Dla każdego używającego Heroku:

Jeśli wdrożysz w Herkou, automatycznie przeprowadzi dla ciebie prekompilację podczas wdrażania, jeśli skompilowane zasoby nie zostaną uwzględnione (tj. public/assetsNie config.assets.compile = truezostaną zatwierdzone ), więc nie będzie potrzeby lub nie zostanie zatwierdzone wstępnie skompilowane zasoby.

Dokumenty Heroku są tutaj . CDN zaleca się usunąć obciążenie zasobów hamowni.

William Denniss
źródło
1

Nie będzie to to samo, co prekompilacja, nawet po pierwszym trafieniu: ponieważ pliki nie są zapisywane w systemie plików, nie mogą być obsługiwane bezpośrednio przez serwer WWW. Zawsze zaangażowany będzie jakiś kod ruby, nawet jeśli po prostu czyta wpis z pamięci podręcznej.

Frederick Cheung
źródło
Hmm, myślałem, że przy precompile=truepomocy skompilowane zasoby MUSZĄ zostać zapisane w systemie plików. Jesteś pewny? Pozwól, że sprawdzę ...
jrochkind,
1
Bah, myślę, że masz rację - są zapisywane do systemu plików, ale wygląda tmp/cacheraczej na zamiast public/assets, więc nie jest to miejsce, które może zobaczyć serwer WWW, nadal będą obsługiwane przez aplikację railsową, a nie serwer WWW. bla. czy to prawda, myślisz?
jrochkind
Poprawny. Nie będzie tak szybkie, jak to, żeby serwer WWW je odebrał. Może nie ma znaczenia, że ​​umieścisz przed aplikacją CDN jak cloudfront
Frederick Cheung
1

Zestaw config.asset.compile = false

Dodaj do swojego Gemfile

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

Zainstaluj pakiet

Biegać rake assets:precompile

Następnie uruchom serwer

Mohammed Saleem
źródło
O ile mam ustawiony config.asset.compile = true in production.rbplik, ponieważ nie ma dodanego mechanizmu pre-comple. Z tego powodu za każdym razem, gdy uruchamiamy serwer, ładowanie strony zajmuje zbyt dużo czasu (gdy żądanie trafia zarówno do przetwarzania żądania, jak i do kompilacji zasobów). Teraz turbo-sprockets-rails3dołączam do Gemfile i uruchamiam wcześniej polecenie, które rake assets:precompilekompiluje zasoby. Teraz ustawiam config.asset.compile = false in production.rbi uruchamiam serwer, ładowanie strony bez opóźnień. (Przetwarzanie tylko wniosku bez kompilacji zasobów)
Mohammed Saleem
2
Warto powiedzieć, że turbo-sprockets-rails3jest to konieczne tylko w Ruby 3
Andre Figueiredo
0

Z oficjalnego przewodnika :

Na pierwsze żądanie zasoby są kompilowane i buforowane, jak opisano powyżej, a nazwy manifestów używane w helperach są zmieniane w celu włączenia skrótu MD5.

Sprockets ustawia również nagłówek HTTP Cache-Control na max-age = 31536000. Sygnalizuje to wszystkie pamięci podręczne między serwerem a przeglądarką klienta, że ​​ta zawartość (obsługiwany plik) może być buforowana przez 1 rok. Efektem tego jest zmniejszenie liczby żądań tego zasobu z twojego serwera; zasób ma duże szanse, że znajdzie się w lokalnej pamięci podręcznej przeglądarki lub w pośredniej pamięci podręcznej.

Ten tryb zużywa więcej pamięci, działa gorzej niż domyślny i nie jest zalecany.

Ponadto krok prekompilacji wcale nie jest kłopotliwy, jeśli używasz Capistrano do swoich wdrożeń. Dba o to dla ciebie. Po prostu biegniesz

cap deploy

lub (w zależności od konfiguracji)

cap production deploy

i wszystko gotowe. Jeśli nadal go nie używasz, gorąco polecam sprawdzenie.

Sergio Tulentsev
źródło
Czy uważasz, że język oficjalnego przewodnika jest ze mną zgodny? Widziałem ten przewodnik, nie jestem do końca pewien, czy to znaczy, co sugeruję powyżej, co myślisz? To moje pytanie.
jrochkind
Tak, mówisz w zasadzie to samo. Sugeruję, aby nie włączać kompilacji na żywo.
Sergio Tulentsev,