como-servir-contenido-comprimido-en-gzip-con-esp8266

Cómo servir contenido comprimido en Gzip con ESP8266 o ESP32

Continuamos con las entradas del ESP8266 y el ESP32, esta vez viendo cómo servir contenido estático comprimido en Gzip desde la memoria SPIFFS.

Haremos referencia al ESP8266, pero el mismo código es compatible para el ESP32, ajustando el nombre de las librerías. Al final tenéis el código tanto para el ESP8266 como para el ESP32.

En la entrada anterior hemos visto cómo servir ficheros (html, js, css, o cualquier otro) desde el sistema de ficheros SPIFFS. Ya adelantamos que era la forma adecuada de servir contenido estático.

Sin embargo, conviene que optimicemos el tamaño de los ficheros servidos. Especialmente es importante en cualquier tipo de servidor, pero aún más en un procesador de baja potencia como el ESP8266.

Existen varias opciones como minificar el contenido servido. Otra de las más habituales y convenientes es comprimir los ficheros servidos habitualmente en formato Gzip.

De hecho, la mayoría de los servidores sirven los ficheros comprimidos, y los navegadores modernos están preparados para descomprimir los ficheros de forma transparente para el usuario.

Servir ficheros comprimidos permite enviar ficheros entre 2 a 5 veces más pequeños (aprox), lo cual es menor carga para el servidor, menor ancho de banda y mejor velocidad de transmisión. El esfuerzo de descomprimir es pequeño y recae sobre los clientes, no sobre el servidor.

¿Es posible modificar nuestro servidor desde SPIFFS para servir ficheros Gzip? Por supuesto que sí. De hecho, funciona a las mil maravillas y es una medida muy conveniente para mejorar significativamente el rendimiento del ESP8266 como servidor. De hecho, es muy sencillo.

El Sketch principal queda igual al ejemplo anterior, con el siguiente contenido.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>   // Include the SPIFFS library
 
#include "config.h"  // Sustituir con datos de vuestra red
#include "Server.hpp"
#include "ESP8266_Utils.hpp"

void setup(void)
{
  Serial.begin(115200);
  SPIFFS.begin();
  
  ConnectWiFi_STA();
  
  InitServer();
}

void loop(void)
{
  server.handleClient();
}

Tenemos que modificar nuestra definición del comportamiento del servidor en ‘Server.hpp’ para que use la nueva y mejorada versión.

ESP8266WebServer server(80);

#include "ESP8266_Utils_Server.hpp"

void handleNotFound() {
  server.send(404, "text/plain", "Not found");
}

void InitServer()
{
   server.onNotFound([]() {
      if (!HandleFileReadGzip(server.uri()))
         handleNotFound();
   });
  
   server.begin();
   Serial.println("HTTP server started");
}

El mayor cambio lo tenemos en el fichero ‘ESP8266_Utils_Server.hpp’, donde hemos añadido la función HandleFileReadGzip que nos va a permitir gestionar las peticiones de ficheros Gzip.

Como vemos, esta función comprueba si existe el fichero solicitado. Si no existe, comprueba si existe la versión comprimida (.gz). Si tampoco lo encuentra, devuelve ‘File Not Found’.

bool HandleFileReadGzip(String path) 
{ 
  if (path.endsWith("/")) path += "index.html";
  Serial.println("handleFileRead: " + path);
  
  if (SPIFFS.exists(path)) 
  {
    ServeFile(path, GetContentType(path));
    return true;
  }
  else 
  {
      String pathWithGz = path + ".gz";
      if(SPIFFS.exists(pathWithGz)) 
      {
        ServeFile(pathWithGz, GetContentType(path));
        return true;
      }
  }
  Serial.println("\tFile Not Found");
  return false;
}

Por otro lado, cogemos los ficheros de nuestra carpeta ‘data’ y los comprimimos en formato Gzip, por ejemplo, empleando el programa 7-Zip por ejemplo.

Resultado

Lo subimos todo y accedemos a la página servida para comprobar que, efectivamente, funciona y estamos sirviendo ficheros comprimidos. ¡Así de sencillo!

esp8266-servidor-spiffs-hello-world

Comprimir los ficheros es una mejora muy importante, sobre todo si incluimos en nuestro código librerías y frameworks en JavaScript “pesados”. Notaremos una mejora de rendimiento muy importante.

Este es ya un ejemplo bastante funcional y apropiado de cómo servir contenido estático con el ESP8266. Pero ¿es posible mejorarlo? Por supuesto que sí. Y lo veremos en la próxima entrada haciendo un servidor asíncrono. ¡Hasta pronto!

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github.

github-full

Versión para el ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples

Versión para el ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples