config.assets.compile = true en la producción de Rails, ¿por qué no?

185

La aplicación predeterminada de Rails instalada por rails newtiene config.assets.compile = falseen producción.

Y la forma habitual de hacer las cosas es ejecutar rake assets:precompileantes de implementar su aplicación, para asegurarse de que se compilan todos los activos de canalización de activos.

Entonces, ¿qué pasa si me pongo config.assets.compile = trueen producción?

No tendré que correr precompilemás. Lo que creo que sucederá es la primera vez que se solicita un activo, se compilará. Este será un éxito de rendimiento la primera vez (y significa que generalmente necesita un tiempo de ejecución js en producción para hacerlo). Pero aparte de estos inconvenientes, después de que el activo se compiló perezosamente, creo que todo el acceso posterior a ese activo no tendrá ningún impacto en el rendimiento, el rendimiento de la aplicación será exactamente el mismo que con los activos precompilados después de esta compilación perezosa inicial del primer golpe. ¿Es esto cierto?

¿Hay algo que me falta? ¿Alguna otra razón para no poner config.assets.compile = trueen producción? Si tengo un tiempo de ejecución JS en producción, y estoy dispuesto a tomar el equilibrio del rendimiento degradado por el primer acceso de un activo, a cambio de no tener que ejecutarlo precompile, ¿tiene sentido?

jrochkind
fuente
1
Advertencia, las versiones anteriores de las ruedas dentadas contienen un error y si config.assets.compile está configurado como verdadero, existe el riesgo de vulnerabilidad trasversal del directorio ( blog.heroku.com/rails-asset-pipeline-vulnerability )
Mauro
Así es exactamente como se supone que funciona Stackoverflow. Una pregunta bien escrita y una respuesta bien escrita. Los amo a ambos op y @ richard-hulse.
schmijos

Respuestas:

259

Escribí esa parte de la guía.

Definitivamente no quieres vivir compilar en producción.

Cuando ha compilado, esto es lo que sucede:

Cada solicitud de un archivo en / assets se pasa a Sprockets. En la primera solicitud para todos y cada uno de los activos, se compila y almacena en caché en lo que sea que Rails esté usando para caché (generalmente el sistema de archivos).

En solicitudes posteriores, Sprockets recibe la solicitud y tiene que buscar el nombre de archivo con huellas digitales, verificar que el archivo (imagen) o los archivos (css y js) que componen el activo no se modificaron, y luego, si hay una versión en caché, sirva eso.

Eso es todo en la carpeta de activos y en cualquier proveedor / carpeta de activos utilizada por los complementos.

Eso es una gran carga, ya que, para ser sincero, el código no está optimizado para la velocidad.

Esto tendrá un impacto en la rapidez con la que los activos se transfieren al cliente y afectará negativamente los tiempos de carga de la página de su sitio.

Comparar con el valor predeterminado:

Cuando los activos están precompilados y la compilación está desactivada, los activos se compilan y se toman las huellas digitales en el public/assets. Sprockets devuelve una tabla de mapeo de los nombres de archivo sin formato a huellas digitales a Rails, y Rails escribe esto en el sistema de archivos. El archivo de manifiesto (YML en Rails 3 o JSON con un nombre aleatorio en Rails 4) se carga en la memoria Rails al inicio y se almacena en caché para su uso por los métodos de ayuda de activos.

Esto hace que la generación de páginas con los activos de huellas dactilares correctas sea muy rápida, y el servicio de los archivos en sí mismos es un servidor web del sistema de archivos rápido. Ambos dramáticamente más rápido que la compilación en vivo.

Para obtener la máxima ventaja de la canalización y las huellas digitales, debe configurar encabezados en el futuro en su servidor web y habilitar la compresión gzip para archivos js y css. Sprockets escribe versiones comprimidas de activos que puede configurar su servidor para usar, eliminando la necesidad de que lo haga para cada solicitud.

Esto permite que los activos lleguen al cliente lo más rápido posible y en el menor tamaño posible, acelerando la visualización de las páginas en el lado del cliente y reduciendo las solicitudes (con encabezado en el futuro).

Entonces, si estás compilando en vivo es:

  1. Muy lento
  2. Carece de compresión
  3. Afectará el tiempo de renderizado de las páginas

Versus

  1. Tan rápido como sea posible
  2. Comprimido
  3. Elimine la compresión escuchada del servidor (opcionalmente).
  4. Minimice el tiempo de renderizado de las páginas.

Editar: (respuesta al comentario de seguimiento)

La tubería podría cambiarse para precompilar en la primera solicitud, pero existen algunos obstáculos importantes para hacerlo. La primera es que tiene que haber una tabla de búsqueda de nombres de huellas digitales o los métodos auxiliares son demasiado lentos. En virtud de un senario de compilación a pedido, debería haber alguna forma de agregar a la tabla de búsqueda a medida que se compila o solicita cada nuevo activo.

Además, alguien tendría que pagar el precio de la entrega lenta de activos por un período de tiempo desconocido hasta que todos los activos estén compilados y en su lugar.

El valor predeterminado, donde el precio de compilar todo se paga fuera de línea al mismo tiempo, no afecta a los visitantes públicos y garantiza que todo funcione antes de que las cosas se activen.

El factor decisivo es que agrega mucha complejidad a los sistemas de producción.

[Edición, junio de 2015] Si está leyendo esto porque está buscando una solución para tiempos de compilación lentos durante una implementación, entonces podría considerar precompilar los activos localmente. La información sobre esto se encuentra en la guía de canalización de activos . Esto le permite precompilar localmente solo cuando hay un cambio, confirmarlo y luego tener una implementación rápida sin etapa de precompilación.

Richard Hulse
fuente
1
Gracias, acepté tu respuesta. Pero ahora mi pregunta es, está bien, no lo hace ahora, pero posiblemente piense que Asset Pipeline podría tener una característica donde se compila perezosamente en la primera solicitud, haciéndolo exactamente como la precompilación, que incluye escribir en ./public y actualizar el manifiesto de huella digital?
jrochkind
Véase más arriba. ¿Es esto un problema porque Capistrano no funciona para ti?
Richard Hulse
Yo no uso Capistrano. No lo he necesitado antes, la complejidad añadida no valió la pena. Quizás la cartera de activos es la gota que colma el vaso y lo requiere. En su opinión, ¿no es factible administrar las implementaciones de Rails con una canalización de activos sin capistrano o similar? Es una pena, para configuraciones simples no solía ser un gran problema hacerlo a mano.
jrochkind
Realmente necesitas Capistrano para Rails 3.1. Los activos se compilan en un nuevo directorio público mientras su aplicación anterior aún se está ejecutando. Cuando se realiza la compilación, la nueva versión se vincula y el servidor se reinicia automáticamente.
Richard Hulse
"Para obtener la máxima ventaja de la canalización y las huellas digitales, debe establecer encabezados en el futuro en su servidor web y habilitar la compresión gzip para archivos js y css". ¿esta?
Isaac Betesh
7

Tener menos gastos generales con la cosa de precompilación.

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

entonces puede simplemente usar imágenes y hojas de estilo como "/assets/stylesheet.css" en * .html.erb o "/assets/web.png"

dbKooper
fuente
6

Para cualquiera que use Heroku:

Si realiza el despliegue en Herkou, realizará la precompilación automáticamente durante el despliegue si los activos compilados no se incluyen (es decir, public/assetsno se comprometen), por lo que no es necesario config.assets.compile = trueni comprometer los activos precompilados.

Los documentos de Heroku están aquí . Se recomienda una CDN para eliminar la carga en el recurso dyno.

William Denniss
fuente
1

No será lo mismo que la precompilación, incluso después de ese primer golpe: debido a que los archivos no se escriben en el sistema de archivos, el servidor web no puede servirlos directamente. Siempre habrá algún código ruby, incluso si solo lee una entrada de caché.

Frederick Cheung
fuente
Hmm, pensé que con precompile=truelos activos compilados se escribirían en el sistema de archivos. ¿Estás seguro? Déjame comprobar ...
jrochkind
1
Bah, creo que tienes razón: ESTÁN escritas en el sistema de archivos, pero parece tmp/cacheque public/assetsno está en un lugar, así que no es un lugar que el servidor web pueda ver, todavía serán atendidas por la aplicación de rieles. El servidor web. paja. ¿es eso cierto?
jrochkind
Correcto. No será tan rápido como hacer que el servidor web los recoja de inmediato. No importa si pones un CDN como Cloudfront delante de tu aplicación
Frederick Cheung
1

Conjunto config.asset.compile = false

Añadir a su Gemfile

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

Instalar el paquete

correr rake assets:precompile

Luego, inicie su servidor

Mohammed Saleem
fuente
Por lo que he establecido el config.asset.compile = true in production.rbarchivo, porque no se agrega ningún mecanismo de precompletar. Debido a eso cada vez que iniciamos el servidor, lleva demasiado tiempo cargar la página (cuando la solicitud golpea tanto el procesamiento de la solicitud como la compilación de activos). Ahora lo turbo-sprockets-rails3incluí en Gemfile y ejecuté el comando para que rake assets:precompilecompile los activos previamente. Ahora configuro config.asset.compile = false in production.rbe inicio el servidor, la página se carga sin demora. (Solo procesando la solicitud sin compilación de activos)
Mohammed Saleem
2
Vale la pena decir que turbo-sprockets-rails3solo es necesario en Ruby 3
Andre Figueiredo
0

De la guía oficial :

En la primera solicitud, los activos se compilan y almacenan en caché como se describe en el desarrollo anterior, y los nombres de manifiesto utilizados en los ayudantes se modifican para incluir el hash MD5.

Sprockets también establece el encabezado HTTP Cache-Control en max-age = 31536000. Esto indica a todas las memorias caché entre su servidor y el navegador del cliente que este contenido (el archivo servido) puede almacenarse en la memoria caché durante 1 año. El efecto de esto es reducir el número de solicitudes de este activo desde su servidor; el activo tiene una buena posibilidad de estar en la memoria caché del navegador local o en alguna caché intermedia.

Este modo usa más memoria, funciona peor que el predeterminado y no se recomienda.

Además, el paso de precompilación no es ningún problema si usa Capistrano para sus implementaciones. Se encarga de ti. Solo corres

cap deploy

o (dependiendo de su configuración)

cap production deploy

y ya está todo listo Si aún no lo usa, le recomiendo que lo revise.

Sergio Tulentsev
fuente
Entonces, ¿crees que el lenguaje de la guía oficial está de acuerdo conmigo? He visto esa guía, no estoy muy seguro de si significa lo que sugiero arriba, ¿qué te parece? Esa es mi pregunta
jrochkind
Sí, dices básicamente lo mismo. Sugiero que no active la compilación en vivo.
Sergio Tulentsev