El hilo principal es un solo carril

Tocar un botón de compra y que no pase nada durante un segundo no es un bug aislado: es el techo del modelo. En un navegador o WebView, el motor de JS y el render comparten un solo hilo principal: ejecución de scripts, layout, pintado y respuesta a input compiten por el mismo carril. En cuanto hay una tarea larga (cálculo pesado, parseo de JSON grande, hidratación de framework, etiquetas de terceros), el pintado y el input se bloquean. web.dev define el TBT sin rodeos: una tarea de más de 50 ms es "tarea larga" y bloquea el hilo principal; el Web Almanac 2025 midió una TBT móvil mediana de 1.916 ms y 7.555 ms en el percentil 90. El mismo script que corre fluido en una laptop puede congelar un teléfono de gama media durante más de un segundo.

WebView: un hilo hace de todo

En el navegador y en WebView, el motor de JS y el render viven en el mismo hilo principal. Una tarea larga —cálculo pesado, parseo de JSON gigante, hidratación de framework, etiquetas de terceros— bloquea a la vez el pintado y el input. El toque del usuario ya se disparó, pero el navegador debe esperar a que la tarea termine para responder. Este es el techo estructural del H5 en móvil: tu propia lógica y "hacer que la pantalla se mueva" pelean por el mismo hilo.

Mini-programa: lógica y render van por separado

El modelo de doble hilo de WeChat los separa: la capa lógica corre en un motor JS aislado (JavaScriptCore en iOS, V8/X5 en Android) sin DOM; la capa de render es un WebView que solo pinta WXML/WXSS. No comparten memoria: se comunican solo por el puente Native vía setData —los datos se serializan, se diffean y se aplican a la vista. Así, un cálculo pesado en la capa lógica no congela el pintado de la capa de render; como el trabajo de esta última es ligero, sigue respondiendo al toque del usuario.

(Con honestidad: el setData tiene su costo —serialización + diff + transferencia entre hilos. Un setData grande o muy frecuente trae su propio jank. La ganancia real es "el cálculo ya no bloquea el pintado", pero hay que mantener el setData ligero. Skyline de WeChat es un motor de render más nuevo que se acerca aún más a nativo).

De dónde viene la fluidez

  • Separación de responsabilidades. Cálculo pesado y pintado aislados, sin esperas cruzadas.
  • Hilo de render ligero. Solo hace diff y pinta, no corre lógica de negocio.
  • Mediación Native. El puente batcha y reenvía; el render no espera tu loop.
  • Predecible en móvil. El jank que persigue al H5 en gama media se reduce estructuralmente.

Cara a cara

DimensiónWebView / H5Mini-Programa
Modelo de hilosHilo principal único (JS+layout+pintado+input)Doble: motor lógico + render WebView
Impacto de tarea largaBloquea pintado e input (toque congelado)Cálculo aislado; render sigue pintando
TBT móvil (mediana)1.916 ms; 7.555 ms en p90Hilo de render fuera de la ruta JS crítica
¿DOM en capa lógica?Sí (puede bloquear directo)No, solo vía setData
Costo a vigilarJS sin límiteTamaño/frecuencia de setData
Mejor paraContenido web abiertoUI transaccional dentro del host

Qué significa para tu flujo

Para una UI de trading, un chat o un formulario, la respuesta es el producto. Mover el núcleo transaccional a un mini-programa elimina por estructura el techo de "un hilo hace de todo" que el H5 golpea en gama media. El H5 es correcto para la web abierta; el núcleo dentro del host no debería compartir su hilo principal con su propia lógica pesada.

Dónde encaja Cross Mini App

Cross Mini App es el runtime y el catálogo abierto del modelo de doble hilo. Construyes una vez y corres en cualquier host con lógica y render separados por un puente gobernado, así el cálculo pesado nunca le roba el frame a un toque. El H5 sigue siendo la puerta; el mini-programa es la habitación donde el botón siempre responde.

Fuentes