Optimización y Buenas Prácticas para Cloud Functions

Clase 21 de 22Curso de Firebase 5: Cloud Functions

Ahora hablaremos de buenas prácticas, soportes de lenguaje y optimización de las cloud functions:

Lenguajes Soportados

Las cloud functions pueden ser escritas en dos lenguajes de programación por ahora, en Javascript y Typescript. Si deseas usar Typescript puedes seleccionar el lenguaje cuando creas el proyecto y tendrás una estructura adecuada y transpilación transparente. Ahora si tienes un proyecto typescript y deseas desplegarlo como funciones tendrás que usar los “predeploy hook” [1]. Typescript es una buena opción ya que ofrece ventajas como el manejo más simple de código asíncrono con async/await lo cual simplifica el manejo de promesas y ya que es tipado evita muchos errores en ejecución [2].

Buenas prácticas y optimizaciones

  • Es importante administrar el ciclo de vida de las funciones para asegurarse que terminan correctamente para evitar que queden en ciclos infinitos o que duren mucho más de lo normal o que terminen antes que finalice correctamente, en algunas ocasiones podría causar cargos de pago extra.
  • Siempre retorna una promesa en una función asíncrona esto permite cerrar el ciclo de vida en el momento adecuado.
  • Siempre colocar return en una función síncrona esto permite cerrar el ciclo de vida en el momento adecuado.
  • Termina las funciones HTTP con res.redirect, o res.send() o resp.end() o resp.json().
  • Utiliza las promesas de Javascript el cual agrega mantenibilidad al código cuando se desarrolla funciones asíncronas.
  • Desarrolla pruebas unitarias de tus funciones.
  • Si la ejecución de una función asíncrona es muy importante, marca en la consola de Google Cloud Platform “Reintentar tras Fallo” esto volverá a intentar la ejecución de la función, hasta un máximo de siete(7) días. Recomendación aplica las buenas prácticas para ello. Puedes encontrar más info aquí [3].
  • Maneja siempre variables de entorno y no hagas “hardcoded” de valores, es buena práctica por seguridad y para que no tengas que desplegar de nuevo el código si requieres cambiar un valor. [4].
  • No hagas actividades en background, ya que una vez termina la ejecución de la función puede que no se termine lo que se dejó en background por eso siempre maneja promesas.
  • Si necesitas crear un archivo en una función debes hacerlo en el directorio de temporales y deben ser de tamaño pequeño ya que consumen memoria de la función, por eso elimínalos después de una invocación ya que podrían persistir en otras invocaciones o pásalo al storage.
  • En desarrollo trata de usar el emulador de cloud functions (shell o serve) ya que el despliegue puede demorar y se vuelve tedioso probar.
  • Importa las dependencias que verdaderamente usas en tu función, las que no usas elimínalas de tu archivo, ya que cuando se invoca por primera vez una función se carga los módulos importados y esto puede tomar un respectivo tiempo dependiendo del tamaño.
  • No hay garantía que el estado de una función persista para próximas invocaciones, sin embargo en algunas ocasiones se recicla entornos de ejecución de una previa invocación, así que si tu declaras variables globales, el valor puede ser reutilizado en otra invocación. De esta forma puedes guardar en caché objetos que son pesados de crear. Te recomiendo solo crees variables de forma global sin van a ser utilizadas por varias funciones, porque si no puede afectar el rendimiento cuando se tenga que crear el entorno por primera vez.
  • Si requieres hacer solicitudes HTTP desde una función puedes reutilizar la conexión generada por la función, así reduces el tiempo de CPU necesario para crear la nueva conexión. Recuerda que en Firebase se cobra por tiempo de uso de CPU. [5].
  • Si usas librerías clientes de google como Pub/Sub o alguna de Machine Learning, crea la constante que tiene el objeto cliente de manera global así no tiene que crear una conexión y consultas al DNS en cada invocación.
  • Si tienes muchas funciones, como buena práctica y por rendimiento despliega solo la función que modificaste o creaste, con el comando de firebase deploy --only functions:NOMBREFUNCION

Estas son algunas buenas prácticas para optimizar el rendimiento, despliegue y minimizar cobros por uso de recursos. Recuerda crear capas, módulos para tener un código más mantenible, como también automatizar tareas por medio de scripts de npm y realizar pruebas unitarias y de rendimiento a las funciones y evaluar su funcionamiento y cuotas de cobro.

Enlaces que van a servirte:

Referencias:

[1]. https://firebase.google.com/docs/cli/#predeploy_and_postdeploy_hooks [2]. http://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html [3]. https://firebase.google.com/docs/functions/retries [4]. https://firebase.google.com/docs/functions/config-env [5]. https://firebase.google.com/docs/functions/networking