¿Cuál es el mejor nivel de compresión nginx gzip?

44

Estoy usando el caché de proxy inverso nginx con gzip habilitado. Sin embargo, tuve algunos problemas con las solicitudes de HTTP de las aplicaciones de Android a mi servicio web Rails JSON. Parece que cuando apago el caché de proxy inverso, funciona bien porque el encabezado de respuesta viene sin gzip. Por lo tanto, creo que el problema es causado por gzip. ¿Cuál es el nivel más apropiado de compresión gzip?

gzip               on;
gzip_http_version  1.0;
gzip_vary          on;
gzip_comp_level    6;
gzip_proxied       any;
gzip_types         text/plain text/css text/javascript application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss;
Chamnap
fuente

Respuestas:

18

El nivel de compresión gzip simplemente determina qué tan comprimidos están los datos en una escala del 1 al 9, donde 9 es el más comprimido. La desventaja es que la mayoría de los datos comprimidos generalmente requieren la mayor cantidad de trabajo para comprimir / descomprimir, por lo que si tiene una configuración bastante alta en un sitio web de alto volumen, puede sentir su efecto.

Parece que sus problemas están más relacionados con los encabezados HTTP en las solicitudes. Por lo general, el tráfico HTTP comprimido con gzip va acompañado del Content-Encoding: gzipencabezado. Si esto se cae en algún lugar, entonces el cliente podría no saber que tiene que descomprimir la respuesta.

crecer
fuente
¿Cómo deshabilitar la respuesta gzip usando el encabezado de solicitud http del cliente? Intento Accept-Encoding: '', pero no funciona.
Chamnap
De RFC2616 ( w3.org/Protocols/rfc2616/rfc2616-sec14.html ) Creo que solo quieres 'Accept-Encoding:' sin nada a continuación.
growse
Sí, agregué el encabezado Accept-Encoding con una cadena vacía con un complemento de póster en mozilla, y la respuesta de regreso sin Content-Encoding: 'gzip'. Sin embargo, en la aplicación de Android, siempre regresa en gzip. Verifiqué lo que se ha almacenado en caché en los directorios de la memoria caché de proxy, nginx almacena en caché el contenido de gzip, por lo que probablemente sean respuestas de vuelta en gzip. ¿Cómo resolver esto?
Chamnap
Algunas fuentes sugieren que los recursos de descompresión no aumentan a medida que aumenta el nivel de compresión. Los recursos en realidad disminuyen en algunos casos a medida que aumenta el nivel de compresión. stackoverflow.com/questions/28452429/…
user2208096
90

Probé esto en nginx 1.3.9 con dos archivos, y estos fueron los resultados que obtuve para los distintos niveles:


text/html - phpinfo ():

0    55.38 KiB (100.00% of original size)
1    11.22 KiB ( 20.26% of original size)
2    10.89 KiB ( 19.66% of original size)
3    10.60 KiB ( 19.14% of original size)
4    10.17 KiB ( 18.36% of original size)
5     9.79 KiB ( 17.68% of original size)
6     9.62 KiB ( 17.37% of original size)
7     9.50 KiB ( 17.15% of original size)
8     9.45 KiB ( 17.06% of original size)
9     9.44 KiB ( 17.05% of original size)

application/x-javascript - jQuery 1.8.3 (sin comprimir):

0    261.46 KiB (100.00% of original size)
1     95.01 KiB ( 36.34% of original size)
2     90.60 KiB ( 34.65% of original size)
3     87.16 KiB ( 33.36% of original size)
4     81.89 KiB ( 31.32% of original size)
5     79.33 KiB ( 30.34% of original size)
6     78.04 KiB ( 29.85% of original size)
7     77.85 KiB ( 29.78% of original size)
8     77.74 KiB ( 29.73% of original size)
9     77.75 KiB ( 29.74% of original size)

No estoy seguro de cuán representativo es esto, pero debería servir de ejemplo. Además, no he tenido en cuenta el uso de la CPU, pero a partir de estos resultados, el nivel de compresión ideal parece estar entre 4y 6.


Además, si usa el gzip_staticmódulo, puede precomprimir sus archivos (en PHP):

function gzip_static($path)
{
    if ((extension_loaded('zlib') === true) && (is_file($path) === true))
    {
        $levels = array();
        $content = file_get_contents($path);

        foreach (range(1, 9) as $level)
        {
            $levels[$level] = strlen(gzencode($content, $level));
        }

        if ((count($levels = array_filter($levels)) > 0) && (min($levels) < strlen($content)))
        {
            if (file_put_contents($path . '.gz', gzencode($content, array_search(min($levels), $levels)), LOCK_EX) !== false)
            {
                return touch($path . '.gz', filemtime($path), fileatime($path));
            }
        }
    }

    return false;
}

Esto le permite obtener la mejor compresión posible sin sacrificar la CPU en cada solicitud.

Alix Axel
fuente
esto concuerda con los resultados en weblogs.asp.net/owscott/iis-7-compression-good-bad-how-much que muestran una gran caída en los niveles de compresión después del nivel 5 y 6.
Jeff Atwood
6

Si realmente puede ahorrar recursos de la CPU, puede usar 9, pero para la mayoría de los sitios un valor de 2 es suficiente, ya que gzip no reduce el archivo mucho después del nivel 1.

Editar: Miré a Amazon CloudFront y parece que está usando el nivel 6, probablemente porque ese nivel es el que ejecuta la descompresión más rápido, lo que mejora el rendimiento del procesamiento de la página.

DiegoG
fuente
Esto no es correcto
calumbrodie
2
Cloud, ¿explicas qué hay de malo en eso? De todos modos, actualicé la respuesta, investigué un poco más y veo que sitios como Amazon CloudFront usan un nivel de compresión de 6, probablemente porque es mejor la velocidad de descompresión (por lo tanto, las páginas se cargarán más rápido).
DiegoG
1) La diferencia entre 2 y 6 no es trivial, puede llegar hasta el 10-15%, ver los datos o probarlo usted mismo. 2) el nivel de compresión no afecta la dificultad de descomprimir (ver stackoverflow.com/questions/28452429/… )
calumbrodie
0

Si tiene un sitio web de alto volumen y aún desea tener un nivel completo (9) de compresión, la mejor idea sería colocar su contenido estático en Amazon S3 o servicios de almacenamiento de objetos similares y cargar los archivos comprimidos.

Todavía querrás usar nginx para comprimir tu HTML, así que mejor mantener ese valor a la normalidad, uso 5 allí.

Aftab Naveed
fuente
Me gustaría utilizar su sugerencia, pero actualmente no he incluido un comp_levelen mi configuración, por lo que no puedo decir en qué nivel estoy actualmente. ¿Sabes cuáles son los valores predeterminados? ¿Fuente?
Hassan Baig