Arrow Navigation - Parte 1: Creando mi primera biblioteca open source
5 may 2023
La biblioteca de la que voy a hablar en estos artículos es @arrow-navigation/core y su implementación para React @arrow-navigation/react. Actualmente, en sus versiones 1.2.6 y 1.0.3 respectivamente. La demo de la biblioteca se encuentra en: https://arrow-navigation-demo.vercel.app/
Los repositorios para que puedan mirar el código son:
- @borisbelmar/arrow-navigation
- @borisbelmar/arrow-navigation-react
- @borisbelmar/arrow-navigation-demo
Agradezco cualquier feedback, estrella ⭐️ o comentario. Sin nada más que agregar, comencemos con esta serie de artículos 🤟.
Desde que comencé a trabajar en Mediastream, me he enfrentado a problemas sumamente complejos. Estos desafíos han incluido desde el desarrollo de una guía electrónica de programas (EPG) hasta la creación de un core para un software low code destinado a la elaboración de aplicaciones OTT, abarcando también aplicaciones para dispositivos muy específicos, como los televisores.
Desarrollar aplicaciones para televisores no es tarea sencilla, especialmente cuando hay escasa documentación disponible y una comunidad muy reducida y cerrada. El reto estaba claro: generar una aplicación de TV para dispositivos LG y Samsung que pudiera integrar parte de nuestro núcleo desarrollado en ReactJS, utilizado en nuestras aplicaciones web.
Honestamente, la transición de nuestras soluciones web a las aplicaciones de TV no resultó tan complicada, ya que tanto WebOS (LG) como Tizen (Samsung) admiten aplicaciones web que se ejecutan en un navegador Chromium dentro del televisor. Esto es similar a cómo funcionaba Cordova en aquellos años, cuando podíamos hacer que las aplicaciones web se comportaran como aplicaciones nativas.
La aplicación se ejecutaba, pero surgieron varios problemas nuevos:
- Se presentaron claros problemas de rendimiento, ya que los recursos de hardware de los televisores son bastante limitados.
- La compatibilidad con algunas APIs, como intersectionObserver, dejaba mucho que desear en algunos dispositivos, debido a que las versiones de Chromium eran bastante antiguas.
- No podíamos mantener la misma experiencia de navegación web en la TV, puesto que la interacción con un control remoto es muy diferente a la experiencia con mouse y teclado, o con sistemas táctiles que ofrece la web.
Quiero centrarme en el tercer problema, ya que representa el mayor desafío al desarrollar para televisores: la experiencia de usuario en TV difiere significativamente de la que se tiene en otros dispositivos.
El problema de la navegación espacial
La navegación espacial ocurre cuando nos desplazamos por elementos de nuestra interfaz mediante flechas, como sucede con el control remoto de una TV o el gamepad de una consola. El inconveniente es que los navegadores web no ofrecen soporte real para este tipo de navegación (a diferencia de Android TV, por ejemplo), por lo que es necesario emular ese comportamiento de manera efectiva.
Inicialmente, utilizamos una biblioteca de código abierto de terceros para evitar reinventar la rueda. Sin embargo, esta biblioteca parecía obsoleta y no estaba siendo mantenida. Desafortunadamente, era lo único disponible en ese momento. Como mencioné antes, la comunidad en torno a estos dispositivos es casi inexistente y necesitábamos lanzar un producto rápidamente. Implementamos la biblioteca, pero la interfaz de usuario de nuestra aplicación era más compleja de lo habitual, lo que generó varios problemas en la implementación.
Cabe recordar que estamos utilizando React con un enfoque de aplicación de una sola página (SPA), por lo que el enrutador que empleamos es en memoria, montando y desmontando componentes de vista. Cuando esto ocurría, el foco se perdía y no había forma de recuperarlo. Además, la biblioteca no detectaba correctamente los nodos cercanos, a veces enfocando incluso nodos que no estaban en pantalla. Por ello, tuvimos que desarrollar una pequeña biblioteca interna para gestionar qué elementos debían recibir el foco. Otro problema era que esta biblioteca obligaba a los componentes a suscribirse a estados innecesarios, lo que generaba demasiadas actualizaciones de renderizado. A pesar de todas las limitaciones, logramos sacar el proyecto adelante y ya contamos con aplicaciones en producción, pero sabíamos que podíamos mejorarlo.
Arrow Navigation: desarrollando la solución perfecta que tenía en mente
Personalmente, me encanta resolver problemas. En ese momento, me prometí a mí mismo que desarrollaría una solución eficiente y escalable cuando adquiriera las habilidades necesarias para abordar el problema que me había causado tantos dolores de cabeza. Fue así como, hace un par de meses, comencé a esbozar y reflexionar sobre cómo desarrollar una solución que se ajustara perfectamente a todos los problemas que enfrenté y sigo enfrentando con la implementación que tuve que realizar en ese entonces.
Una vez que identifiqué todos los aspectos que debía abordar y había diseñado posibles soluciones, me puse manos a la obra con el código. Opté por programar como siempre me ha gustado, pero no había tenido muchas oportunidades de hacerlo: con TypeScript y utilizando el enfoque de Desarrollo Guiado por Pruebas (TDD).
Dado que se trataba de un proyecto paralelo en mi tiempo libre, me permití desarrollar la biblioteca a mi gusto y a mi propio ritmo. Disfruté escribiendo cada línea de código hasta el día de hoy, y la verdad, me siento orgulloso de los resultados.
Escribo esta serie de artículos con el propósito de documentar este proceso y explicar el pensamiento detrás de cada iteración y decisión que tomé al diseñar esta pieza de software. Hasta el momento en que escribo este artículo, sigo mejorando y manteniendo mi primera biblioteca de código abierto. Espero que sea de su interés y disfruten de este viaje.
Para leer la segunda parte visita el siguiente enlace: Arrow Navigation - Parte 2: El proceso de desarrollo