Blog
Optimizar archivos es un factor importante que todo desarrollador web debe tener en cuenta ya sea el mismo servidor donde se encuentra alojada la página web o un servidor externo que usemos para guardar los archivos multimedia que mostrará nuestro sitio web, ya sean imágenes, audio o vídeos.
Pero para este caso, como nuestro sitio web simplemente permite la carga de imagenes, este será nuestra área de enfoque. Debemos optimizar dichas imágenes para que no ocupen tanto espacio dentro de nuestro servidor.
Importancia de optimizar los archivos cliente-servidor
Las app crecen a lo largo del tiempo cuando son lanzadas finalmente, los usuarios cada día se registran y comparten más y más contenido. Supongamos que este es el caso de nuestra app, entonces imagina que un usuario comparte una foto de casi 15mb, lo cual es posible con las cámaras profesionales que existen actualmente en el mercado. Nosotros podemos permitir dicha carga de la imagen como lo hace nuestra app hasta ahora, entonces una vez se suba esa imagen supongamos que otra persona que se encuentra en otra ubicación esta siguiendo a ese usuario y esta por ver esa publicación, pero el internet de este usuario no es tan rápido como el usuario que subió dicha fotografía de 15mb.
Lo que pasará es que la experiencia de esta persona en nuestra app, se verá afectada porque debe esperar que su navegador descargue esa imagen para poderla mostrar en el post, esto es algo que debemos solucionar ya que no todos contamos con la misma velocidad de internet.
Además de optimizar los archivos para que tengan menos peso en nuestro servidor, también estaremos optimizando la carga de los mismos en nuestro sitio web a la hora de que un usuario tenga que descargar el contenido de esa imagen que se encuentre anexada al post. Por otro lado existe el factor SEO, sabemos que a google no le gustan las páginas que carguen lento, por ende una solución es optimizar el contenido multimedia que en la mayoría de los casos es lo que causa un gran impacto para que la web se cargue rápidamente.
Para poder optimizar estas imagenes haremos uso de la librería Pillow de python, aquí tienes la documentación si te interesa trabajar más a fondo con esta librería para procesar tu imagenes. Pillow viene instalada por defecto en las últimas versiones de python. Pero recomiendo utilizar igualmente su comando de instalación, tanto para el python instalado en nuestro sistema operativo como para el python instalado en nuestro entorno virtual:
pip install Pillow
Muy bien, una vez hecho esto vamos a ver como funciona. Vamos a abrir la consola de python con flask shell y escribiremos lo siguiente en nuestra consola:
>>> from PIL import Image >>> import os >>> mi_imagen = Image.open("C:\\Users\\MiUsuario\\Pictures\\background-desktop.jpg") >>> # Información sobre la imagen, modo de imagen, tamaño y formato >>> mi_imagen <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=5760x3840 at 0x24D0A25BA88> >>> # Ver solamente el ancho de la imagen >>> mi_imagen.width 5760 >>> # Ver solamente lo alto de la imagen >>> mi_imagen.height 3840 >>> # Ver solamente el formato de la imagen >>> mi_imagen.format 'JPEG' >>> # Ver el peso de la imagen, este método devuelve el peso en bytes entonces lo multiplicamos por 0.00001 para obtener su peso en mb >>> peso_imagen = os.path.getsize("C:\\Users\\MiUsuario\\Pictures\\background-desktop.jpg")*0.000001 >>> tamaño_imagen 3.213387
Esta imagen que estamos analizamos tiene un peso de 3.2 mb, imagina que a diario se suban 1000 imagenes y suponiendo que todas tienen este mismo peso, esto haría que se ocupe mucho espacio en nuestro servidor ya que es un total de 3.2gb. Entonces vamos a proceder a utilizar los datos que recientemente obtuvimos, puedo ver que esta imagen tiene un tamaño de 5760×3840 lo cual es extremandamente grande, entonces yo quiero decirle que reduzca su tamaño a 1980×1080 con la función .resize()
ya que a esta calidad las imagenes se ven bastante bien, por otro lado también utilizaremos los atributos quality
y optimize
, entonces vamos a proceder a hacerlo:
>>> imagen_optimizada = mi_imagen.resize((1980, 1080)) >>> imagen_optimizada <PIL.Image.Image image mode=RGB size=1980x1080 at 0x24D0A2A3608> # Como ven, ahora la imagen paso de tener el tamño de 5760x3840 a 1980x1080 y ahora procedemos a guardar la imagen imagen_optimizada.save('C:\\Users\\MyUsuario\\Desktop\\imagen_optimizada.jpg', optimize=True) # Obtenemos ahora el tamaño de la imagen que acabamos de optimizar tamañoImagen_optimizada = os.path.getsize('C:\\Users\\gamersnautas\\Desktop\\imagen_optimizada.jpg')*0.000001 >>> tamañoImagen_optimizada 0.212271
Listo, ahora nuestra imagen tiene un peso de 0.2 mb lo que equivale a 200kb y si volvemos a sacar las cuentas ahora si se suben 1000 imagenes con este mismo peso cada una hacen un total de 200mb, lo cual es un impacto de reducción de espacio bastante grande ya que pasamos de 3.2gb a tan solo 200mb. Esto en terminos de espacio en nuestro servidor, pero ahora a estas imagenes también se cargarán de manera más rápida en nuestro sitio web cuando un usuario desee verla.
También puedes ir a comparar las diferencias de calidad entre la imagen original con la imagen optimizada y la verdad es que la diferencia es prácticamente nula, así que no te preocupes por la calidad ya que esta no se ve afectada en lo absoluto.
Implementando esta función en nuestra app
Para implementarla es muy sencillo, vamos a ir a nuestro archivo de rutas.py y le implementamos los siguientes cambios en la ruta obtener_post
:
from PIL import Image @app.route('/obtener_post', methods=["POST"]) def obtener_post(): form = Publicaciones() if form.validate_on_submit(): post = Pubs(cuerpo=form.post.data, autor=current_user) imagen = form.imagen.data nombre_imagen = secure_filename( current_user.username + '_' + imagen.filename) ruta_imagen = os.path.abspath( 'app\\static\\uploads\\{}'.format(nombre_imagen)) ruta_html = '../static/uploads/{}'.format(nombre_imagen) imagen.save(ruta_imagen) if imagen.filename != '': imagen = Image.open(ruta_imagen) if imagen.width > 1980 and imagen.height > 1080: reducirTamaño_imagen = imagen.resize((1980, 1080)) reducirTamaño_imagen.save(ruta_imagen, optimize=True) post.post_imagen = ruta_html else: imagen.save(ruta_imagen, optimize=True) post.post_imagen = ruta_html else: pass bdd.session.add(post) bdd.session.commit() return "Success"
Analizando el código una vez la imagen se recibe en el backend, este lo que hace es verificar si la imagen supera los tamaños de 1980×1080 pero si los supera, va a redimensionar la imagen a 1980×1080 y si no los supera solo guardará la imagen con sus dimensiones originales, además hacemos uso en cada una de las dos condiciones el atributo optimize para reducir el peso del contenido de la imagen.
Ahora nuestra app mantendrá optimizada cada una de las imágenes que sean subidas por los usuarios, por lo cual esto causara menos impacto en la velocidad de cargas de las misma, en este momento me voy a dirigir a la app y probaré a subir la misma imagen de 3.2 mb que usamos al principio de la lección, una vez se suba puedo ir a la carpeta uploads y ver el tamaño y el peso que tiene una vez se haya subido al servidor:
Si voy a ahora a la carpeta de uploads que es donde mi servidor recibe las imágenes podré ver la imagen que acabo de subir y al inspeccionarla veré que ha sido optimizada porque de tener un peso de 3.2mb paso a tener un peso de 207kb:
Te invito a que lo pruebes tu mismo, buscate la imagen con mayor resolución que tengas y que tenga un peso por encima de unos 4 o 5mb, cárgala al servidor y luego ve a la carpeta uploads y ve el trabajo que realiza esta fantástica librería. Listo hasta aquí llega esta lección la cual es muy importante para sitios web que acepten contenido multimedia, en este caso hemos tratado solo imágenes ya que es lo único que acepta nuestra app. Pero también se pueden optimizar vídeos e incluso archivos de audio.
➡ Continúa aprendiendo con nuestro Curso de Flask – Python: