> For the complete documentation index, see [llms.txt](https://weekly-essay.mikey.wang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://weekly-essay.mikey.wang/es/2026/w03-lessons-from-advanced-troubleshooting.md).

# W03-Lecciones del diagnóstico avanzado de problemas

La semana pasada avanzamos mucho en un problema fantasma de Webpack que llevaba casi tres años acosándonos. Aprovecho para ordenar lo que he aprendido sobre las características de los problemas extraños y difíciles del frontend y sobre cómo abordarlos.

***

#### Los problemas extraños y difíciles se pueden dividir en dos clases, según si el código contiene o no un defecto

* En la primera, el código tiene un defecto de diseño muy oculto. Son fallos lógicos latentes que suelen manifestarse solo bajo condiciones especiales. Por ejemplo, una suposición incorrecta sobre asincronía, concurrencia o estado puede fallar únicamente en dispositivos poco potentes o con un orden de ejecución específico. Lo que más he encontrado en la práctica son condiciones de carrera. Más adelante daré ejemplos concretos.
* En la segunda, la causa raíz suele estar fuera del propio código. Hay que buscar la verdad dentro de un sistema lleno de incertidumbre. Ahí reside precisamente la parte avanzada del diagnóstico de problemas de frontend. No basta con escribir código correcto. También hay que entender en qué mundo va a ejecutarse. Podemos llamar a ese mundo un «entorno de ejecución incierto». Su grado de incertidumbre suele dificultar tanto la observación como la reproducción de los fallos.

***

#### Un entorno de ejecución incierto

Podemos entenderlo como una premisa técnica: suponer que, salvo el código, nada es fiable. El objetivo es preparar las defensas necesarias.

El entorno de ejecución incierto empieza en el momento en que se construye el código.

> Build (elecciones humanas) → Container (muy personalizado) → OS & Hardware (muy fragmentados) → User & Physical Context (fuera de nuestro control).

**1. Build: diferencias en la infraestructura y en los artefactos de compilación**

Las discrepancias de versión entre polyfills, bibliotecas de ejecución y configuraciones de compilación pueden hacer que una sintaxis nueva falle directamente en un entorno antiguo o que una inyección duplicada o incorrecta provoque anomalías.

> Hace poco, el servicio de pago mensual encontró un problema después de pasar de Webpack a Rspack. En dispositivos de gama baja, Promise/thenable se ejecutaban en un orden inesperado. La herramienta de compilación en sí podía no tener ningún error, pero las diferencias de comportamiento del runtime generado desencadenaban el problema. Webpack tiene un runtime complejo que utiliza Promise/thenable para coordinar el orden de carga de los módulos.
>
> En el checkout para comercios dentro de Kuailü encontramos un fallo al establecer cookies. Se debía al orden de ejecución entre distintos hilos del cliente.

**2. Container: diferencias entre la aplicación anfitriona y el motor de WebView**

No todos los WebView se comportan igual al ejecutar JS, renderizar CSS o gestionar la seguridad y las interfaces. La capa contenedora también puede inyectar o restringir API. Como consecuencia, una misma aplicación H5 puede comportarse de forma distinta según el contenedor.

> Un ejemplo típico son los interceptores de iOS. El contenedor puede interceptar las solicitudes de red, la navegación entre rutas y otras operaciones. Una implementación incorrecta o duplicada de esas interceptaciones puede causar problemas. En Huixiao, por ejemplo, encontramos tokens invalidados porque no se había podido establecer una cookie. En la aplicación para comercios de reparto tuvimos problemas con el funcionamiento sin conexión.
>
> En esa misma aplicación descubrimos también la inyección de un hook que cargaba por su cuenta la versión 1.9.1 de knb.js si no la encontraba. Esto hacía que en Android, de forma ocasional, la suscripción a appear tuviera éxito pero no se ejecutara el callback.

**3. OS & Hardware: fragmentación de sistemas operativos y dispositivos**

Las diferencias entre ROM de fabricantes, modelos, resoluciones y versiones del sistema pueden provocar cierres inesperados, errores de disposición o problemas de rendimiento en determinados dispositivos.

> En la versión iOS de la aplicación para comercios de reparto, un mismo usuario llegó a generar un gran número de llamadas repetidas a yoda. Al resolver otro problema al año siguiente descubrimos que podíamos investigarlos juntos. La causa resultó ser la falta de memoria disponible en dispositivos de gama baja. Tras una advertencia de memoria, el mecanismo para mantener activa la aplicación hacía que WebView invocara reload una y otra vez. Eso provocaba que el mismo usuario entrara repetidamente en la página en un periodo muy corto.

**4. User & Physical Context: diferencias en el entorno real del usuario**

Las distintas formas de uso y circunstancias de los usuarios, como una red deficiente, batería baja o poco espacio de almacenamiento, introducen muchas variables fuera de nuestro control. Pueden producir anomalías en casos límite. La falta de reproducibilidad suele dificultar mucho su investigación. Hace falta combinar registros de instrumentación y de acciones del usuario para encontrar pistas.

> En pagos de terceros encontramos fallos causados por el uso de dos instancias de WeChat. Algunos usuarios recurren a funciones del sistema o de terceros que permiten ejecutar dos instancias de una misma aplicación en un teléfono. Este mecanismo puede romper la suposición de instancia única o la cadena de comunicación entre procesos, IPC, y causar problemas inesperados.

***

#### He caído en muchas trampas. Comparto algunas lecciones y dos casos

Primero, hay que soltar el apego a la propia explicación. No todos los problemas difíciles necesitan una «explicación perfecta» inmediata. Si ya se ha producido un incidente, la primera prioridad es aliviar la presión de quienes te rodean. Hay que encontrar una solución provisional controlable que contenga el riesgo y permita desplazar pronto la atención de los demás. A la mayoría no le preocupa tanto la «causa raíz definitiva». Primero hay que estabilizar la situación. Después habrá margen para seguir buscando la verdad.

Segundo, la perseverancia y la disposición a afrontar los retos son necesarias para ganar profundidad técnica. Muchos problemas se resuelven de pronto después de una larga espera. Cuando se llega a un callejón sin salida, se puede dejar el problema en reposo, esperar una oportunidad o una intuición y completar lo que falte. Pero no hay que abandonarlo.

***

#### Caso uno: artefactos de compilación inestables de Webpack

El problema de inestabilidad de los artefactos de Webpack que mencioné al principio fue un proceso de casi tres años, en el que fuimos acercándonos a la verdad desde lo superficial hacia lo profundo.

1. Síntomas. A veces los artefactos generados por Webpack eran inutilizables y causaban pantallas en blanco ocasionales en producción. Cuando encontramos el problema por primera vez no pudimos identificar la causa raíz. Sin embargo, la investigación permitió mejorar el mecanismo de distribución de paquetes de la canalización, garantizando que el paquete validado en producción mediante una lista de usuarios autorizados fuera exactamente el mismo que se desplegaba después para todos.
2. Análisis de la configuración. Más adelante, Hongze realizó un análisis específico de la configuración de Webpack. Identificó anomalías de compilación causadas por la mezcla de ESM y CJS en dependencias de terceros y ajustó la configuración. Aun así, seguían apareciendo artefactos defectuosos.
3. Experimento colectivo y compromiso. El año pasado, Jianzuan dedicó una sesión del programa de transmisión de fundamentos técnicos a estos fallos. Reprodujo junto al equipo la inestabilidad de los artefactos. El experimento colectivo profundizó nuestro conocimiento de la compilación. Además, encontramos un ajuste más eficaz: si desactivábamos la compilación asíncrona de los paquetes, dejaban de aparecer artefactos defectuosos. El costo era una compilación más lenta.
4. Solución final. La semana pasada, Jianzuan propuso una nueva solución. Identificó una característica clave de los artefactos, el envoltorio n.n(). Comprobar que las características de minificación de CJS en el resultado cumplen lo esperado permite garantizar que los paquetes de producción sean correctos y cerrar por completo esta vía de riesgo para la calidad.

Llegados aquí, creo que podemos dar el problema por cerrado. Si queda tiempo y capacidad, el siguiente paso sería ayudar a Webpack a resolver de raíz la compilación asíncrona de módulos CJS y enviarles un PR.

***

#### Caso dos: refactorización de marketing del proyecto Alpha

Los problemas se pueden resolver, pero no todos admiten una explicación técnica completa. El proceso de afrontarlos es más importante.

Una refactorización de marketing del proyecto Alpha provocó una caída de la conversión de apertura de cuentas. Tardamos más de dos meses en resolverla y dejó al descubierto una serie de problemas. Al final no encontramos la causa técnica raíz. Tampoco quedaron las condiciones necesarias para reproducirla, por lo que ya nunca podrá haber una explicación técnica plenamente satisfactoria.

Sin embargo, aquel proceso nos hizo comprender la calidad con mucha más profundidad. Durante ese periodo completamos la observación en tiempo real de las métricas del negocio, la capacidad de hacer experimentos A/B y el trabajo habitual de calidad antes de producción. También reflexionamos a fondo sobre la estrategia de reversión y la toma de decisiones. El incidente impulsó directamente la refactorización integral de Alpha al año siguiente y estableció para el equipo una buena referencia de mantenibilidad.
