2012-06-17 16 views
8

Nota: tuve otra pregunta similar sobre cómo usar datos GZIP usando Ruby's zlib que técnicamente fue respondida y no sentí que podía comenzar a desarrollar la pregunta ya que había sido respondida aunque esta pregunta está relacionada, no es lo mismo ...Uso de la compresión gzip en Sinatra con Ruby

El siguiente código (creo) es GZIP un archivo CSS estático y almacena los resultados en la variable result. Pero, ¿qué hago con esto en el sentido de: cómo puedo enviar esta información al navegador para que se reconozca como GZIP en vez del tamaño original del archivo (por ejemplo, al verificar mi puntaje de YSlow, quiero verlo marcando correctamente para asegurarme de que tengo recursos estáticos GZIP).

z = Zlib::Deflate.new(6, 31) 
z.deflate(File.read('public/Assets/Styles/build.css')) 
z.flush 
@result = z.finish # could also of done: result = z.deflate(file, Zlib::FINISH) 
z.close 

... Una cosa a destacar es que en mi anterior pregunta el entrevistado aclaró que Zlib::Deflate.deflate no producirá datos codificado con Gzip. Solo producirá datos codificados en zlib y, por lo tanto, necesitaría usar Zlib::Deflate.new con el argumento windowBits igual a 31 para iniciar una transmisión gzip.

Pero cuando ejecuto este código, no sé realmente qué hacer con la variable result y su contenido. No hay información en Internet (que pueda encontrar) sobre cómo enviar recursos estáticos codificados GZIP (como JavaScript, CSS, HTML, etc.) al navegador, lo que hace que la página cargue más rápido. ¡Parece que cada artículo de Ruby que leo está basado en alguien que usa Ruby on Rails!

Cualquier ayuda realmente apreciada.

Respuesta

13

Después de comprimir el archivo, simplemente debe devolver el resultado y asegurarse de configurar el encabezado Content-Encoding: gzip para la respuesta. Google tiene una buena y pequeña introduction para comprimir gzip y lo que hay que tener en cuenta. Esto es lo que puedes hacer en Sinatra:

get '/whatever' do 
    headers['Content-Encoding'] = 'gzip' 
    StringIO.new.tap do |io| 
    gz = Zlib::GzipWriter.new(io) 
    begin 
     gz.write(File.read('public/Assets/Styles/build.css')) 
    ensure 
     gz.close 
    end 
    end.string 
end 

Sin embargo, una última palabra de advertencia. Probablemente deberías elegir este enfoque solo para el contenido que creaste sobre la marcha o si solo quieres usar la compresión gzip en algunos lugares.

Si, sin embargo, su objetivo es servir la mayoría o incluso todos sus recursos estáticos con compresión gzip habilitada, entonces será una solución mucho mejor confiar en lo que ya está soportado por su servidor web en lugar de contaminar su código con este detalle Hay muchas posibilidades de que pueda habilitar la compresión gzip con algunas configuraciones. Here's un ejemplo de cómo se hace para nginx.

Otra alternativa sería utilizar el middleware Rack::Deflater.

+1

Gracias por la respuesta detallada y el código de ejemplo. Tomé en cuenta tus comentarios y usé el 'Rack :: Deflater' en su lugar. Literalmente una línea de código en la parte superior de mi archivo de aplicación y funcionó: 'use Rack :: Deflater' – Integralist

+0

+1 para la opción nginx –

+0

Downvoted porque esto servirá contenido comprimido independientemente de lo que el cliente haya especificado que pueda aceptar en su El encabezado 'Accept-Encoding'. Esto es, por supuesto, una mala práctica y debe evitarse. – aidan

3

Sólo para resaltar 'rack :: deflactor' modo que una 'respuesta' ->

Como se menciona en el comentario anterior, sólo hay que poner la compresión en config.ru

use Rack::Deflater 

eso es prácticamente ¡eso!

+0

Esta es la mejor respuesta porque 'Rack :: Deflate' negociará y usará el mejor algoritmo de compresión que el cliente soporte – aidan

Cuestiones relacionadas