Búsqueda de sitios web

Servir CSS y JavaScript comprimidos con gzip desde Amazon CloudFront a través de S3


He estado buscando formas de hacer que mi sitio cargue más rápido y una forma que me gustaría explorar es hacer un mayor uso de Cloudfront.

Debido a que Cloudfront originalmente no fue diseñado como un CDN de origen personalizado y porque no soportaba compresión gzip, hasta ahora lo he estado usando para alojar todas mis imágenes, las cuales son referenciadas por su cname de Cloudfront en el código de mi sitio, y optimizadas con encabezados de futuros lejanos.

Los archivos CSS y javascript, por otro lado, se alojan en mi propio servidor, porque hasta ahora tenía la impresión de que no se podían servir comprimidos con gzip desde Cloudfront, y que la ganancia de comprimir con gzip (alrededor del 75 por ciento) supera a la de usar un CDN (alrededor del 50 por ciento): Amazon S3 (y por lo tanto Cloudfront) no admitía servir contenido comprimido con gzip de manera estándar utilizando el encabezado HTTP Accept-Encoding que envían los navegadores para indicar su soporte para la compresión gzip, y por lo tanto no podían comprimir con gzip y servir los componentes sobre la marcha.

Así que estaba bajo la impresión, hasta ahora, de que uno tenía que elegir entre dos alternativas:

  1. mueve todos los activos a Amazon CloudFront y olvídate de comprimir con GZip;

  2. mantener los componentes autoalojados y configurar nuestro servidor para detectar las solicitudes entrantes y realizar GZipping en tiempo real según sea apropiado, que es lo que he elegido hacer hasta ahora.

Hubo soluciones alternativas para resolver este problema, pero esencialmente estas no funcionaron. [link].

Ahora, parece que Amazon Cloudfront admite origen personalizado, y que ahora es posible usar el método estándar HTTP Accept-Encoding para servir contenido comprimido con gzip si está utilizando un Origen Personalizado [link].

Hasta ahora no he podido implementar la nueva función en mi servidor. La publicación del blog que enlacé arriba, que es la única que encontré que detalla el cambio, parece implicar que solo puedes habilitar la compresión gzip (salvo soluciones alternativas, que no quiero usar) si optas por un origen personalizado, lo cual preferiría no hacer: me parece más sencillo alojar los archivos correspondientes en mi servidor de CloudFront y enlazarlos desde allí. A pesar de haber leído cuidadosamente la documentación, no sé:

  • si la nueva función significa que los archivos deberían alojarse en mi propio servidor de dominio a través de un origen personalizado, y si es así, qué configuración de código logrará esto;

  • cómo configurar los encabezados de CSS y JavaScript para asegurarse de que se sirvan comprimidos en gzip desde Cloudfront.

Respuesta #1

ACTUALIZACIÓN: Amazon ahora soporta compresión gzip, por lo que esto ya no es necesario. Anuncio de Amazon

Respuesta original:

La respuesta es comprimir los archivos CSS y JavaScript con gzip. Sí, leíste bien.

gzip -9 production.min.css

Esto producirá production.min.css.gz. Elimina el .gz, súbelo a S3 (o al servidor de origen que estés usando) y establece explícitamente el encabezado Content-Encoding del archivo a gzip.

No es compresión gzip al instante, pero podrías integrarlo muy fácilmente en tus scripts de compilación/despliegue. Las ventajas son:

  1. No se requiere CPU para que Apache comprima el contenido con gzip cuando se solicita el archivo.
  2. Los archivos están comprimidos en gzip al nivel más alto de compresión (suponiendo gzip -9).
  3. Estás sirviendo el archivo desde un CDN.

Asumiendo que tus archivos CSS/JavaScript están (a) minimizados y (b) lo suficientemente grandes como para justificar la CPU requerida para descomprimirlos en la máquina del usuario, puedes obtener ganancias significativas de rendimiento aquí.

Solo recuerda: si realizas un cambio en un archivo que está en caché en CloudFront, asegúrate de invalidar la caché después de hacer este tipo de cambio.

Respuesta #2

Mi respuesta es una adaptación de esto: http://blog.kenweiner.com/2009/08/serving-gzipped-javascript-files-from.html

Basándote en la respuesta de Skyler, puedes subir una versión gzip y otra sin gzip del CSS y JS. Ten cuidado con los nombres y prueba en Safari. Porque Safari no manejará archivos .css.gz o .js.gz.

site.js y site.js.jgz y site.css y site.gz.css (necesitarás configurar el encabezado content-encoding al tipo MIME correcto para que se sirvan correctamente)

Luego, en tu página pon.

<script type="text/javascript">var sr_gzipEnabled = false;</script> 
<script type="text/javascript" src="http://d2ft4b0ve1aur1.cloudfront.net/js-050/sr.gzipcheck.js.jgz"></script> 

<noscript> 
  <link type="text/css" rel="stylesheet" href="http://d2ft4b0ve1aur1.cloudfront.net/css-050/sr-br-min.css">
</noscript> 
<script type="text/javascript"> 
(function () {
    var sr_css_file = 'http://d2ft4b0ve1aur1.cloudfront.net/css-050/sr-br-min.css';
    if (sr_gzipEnabled) {
      sr_css_file = 'http://d2ft4b0ve1aur1.cloudfront.net/css-050/sr-br-min.css.gz';
    }

    var head = document.getElementsByTagName("head")[0];
    if (head) {
        var scriptStyles = document.createElement("link");
        scriptStyles.rel = "stylesheet";
        scriptStyles.type = "text/css";
        scriptStyles.href = sr_css_file;
        head.appendChild(scriptStyles);
        //alert('adding css to header:'+sr_css_file);
     }
}());
</script> 

gzipcheck.js.jgz es solo sr_gzipEnabled=true; Esto prueba para asegurarse de que el navegador pueda manejar el código comprimido con gzip y proporcionar una copia de seguridad si no puede.

Luego haz algo similar en el pie de página suponiendo que todo tu js esté en un archivo y pueda ir en el pie de página.

<div id="sr_js"></div> 
<script type="text/javascript"> 
(function () {
    var sr_js_file = 'http://d2ft4b0ve1aur1.cloudfront.net/js-050/sr-br-min.js';
    if (sr_gzipEnabled) {
       sr_js_file = 'http://d2ft4b0ve1aur1.cloudfront.net/js-050/sr-br-min.js.jgz';
    }
    var sr_script_tag = document.getElementById("sr_js");         
    if (sr_script_tag) {
    var scriptStyles = document.createElement("script");
    scriptStyles.type = "text/javascript";
    scriptStyles.src = sr_js_file;
    sr_script_tag.appendChild(scriptStyles);
    //alert('adding js to footer:'+sr_js_file);
    }
}());
</script> 

ACTUALIZACIÓN: Amazon ahora admite la compresión gzip. Anuncio, por lo que esto ya no es necesario. Anuncio de Amazon

Respuesta #3

Cloudfront admite la compresión gzip.

Cloudfront se conecta a su servidor a través de HTTP 1.0. Por defecto, algunos servidores web, incluyendo nginx, no sirven contenido comprimido con gzip a conexiones HTTP 1.0, pero puede indicarle que lo haga añadiendo:

gzip_http_version 1.0

a tu configuración de nginx. La configuración equivalente podría establecerse para el servidor web que estés utilizando.

Esto tiene el efecto secundario de hacer que las conexiones keep-alive no funcionen para conexiones HTTP 1.0, pero dado que los beneficios de la compresión son enormes, definitivamente vale la pena el intercambio.

Tomado de http://www.cdnplanet.com/blog/gzip-nginx-cloudfront/

Editar

Servir contenido que está comprimido en gzip al vuelo a través de Amazon CloudFront es peligroso y probablemente no debería hacerse. Básicamente, si tu servidor web está comprimiendo el contenido en gzip, no establecerá un Content-Length y en su lugar enviará los datos en fragmentos.

Si la conexión entre Cloudfront y su servidor se interrumpe y se corta prematuramente, Cloudfront todavía almacena en caché el resultado parcial y lo sirve como la versión en caché hasta que expire.

La respuesta aceptada de comprimirlo primero en disco con gzip y luego servir la versión comprimida es una mejor idea, ya que Nginx podrá establecer el encabezado Content-Length, y así Cloudfront descartará las versiones truncadas.

Artículos relacionados