Todo desarrollador de iOS ha esperado varios minutos después de cambiar una línea de código y pulsar Compilar.
Si compilas docenas de veces al día, reducir un minuto por compilación te devuelve más de 30 minutos diarios, sin exagerar.
La respuesta clave: la causa estructural principal de la lentitud de Xcode es que un cambio pequeño provoca una recompilación demasiado amplia; la modularización reduce directamente ese alcance.
Este artículo desglosa las causas por capas, explica dónde resulta eficaz la modularización y muestra cómo medir numéricamente la mejora.
Este es el resumen clave.
- El alcance de recompilación de una compilación incremental queda limitado al módulo. Sin módulos, toda la app es una sola unidad.
- No ajustes nada sin medir. Build With Timing Summary de Xcode es la herramienta básica.
- También hay que revisar causas locales como los cuellos de botella de inferencia de tipos y la configuración de dSYM.
¿Por qué se ralentizan las compilaciones de Xcode?
Las causas pueden dividirse en tres capas.
Primero, el alcance de recompilación.
Cuando cambia un archivo Swift, Swift recompila los archivos afectados dentro de su módulo. En una app sin modularizar, todo el destino es un único módulo.
En un destino único con cientos de miles de líneas, incluso un cambio menor provoca una recompilación amplia. Si modificas un tipo usado en muchos lugares, el resultado se acerca a una compilación limpia.
Segundo, los cuellos de botella del comprobador de tipos.
El compilador de Swift dedica mucho tiempo a inferir tipos. Una sola expresión compleja puede tardar varios segundos. Las cadenas largas, los ternarios complejos y los body enormes de SwiftUI son culpables habituales.
Tercero, la configuración de compilación.
Si una compilación de depuración genera dSYM (DWARF with dSYM File) o tiene activado incorrectamente Whole Module Optimization, cada compilación añade un coste innecesario.
¿Cómo mejora la modularización la velocidad de compilación?
La modularización mejora la primera capa: el alcance de recompilación.
Los límites de módulo son cortafuegos para la recompilación. Si solo cambia la implementación interna de un módulo, no es necesario recompilar lo que queda fuera.
La estructura por capas del artículo anterior resulta útil aquí.
- Si modificas el interior de la función de búsqueda (FeatureSearch), la recompilación se limita a FeatureSearch y aproximadamente al destino de la app.
- En cambio, si cambias la interfaz pública de un módulo inferior del que todos dependen (CoreNetwork), las capas superiores se recompilan en cadena.
De ahí se derivan directamente estos principios de diseño de módulos orientados a la velocidad de compilación.
- Coloca el código que cambia con frecuencia aguas arriba del grafo (Feature) y el código estable aguas abajo (Core·Domain).
- Mantén mínima la interfaz pública de los módulos aguas abajo (si no es pública, no afecta al exterior).
- No crees un módulo Common sobredimensionado del que todos dependan.
También hay un efecto de paralelismo. Xcode compila simultáneamente los módulos sin dependencias, así que un grafo más ancho y menos profundo acelera también las compilaciones limpias.
¿Cómo se mide el tiempo de compilación?
La optimización basada en intuición suele fallar. Tres herramientas son suficientes.
Build With Timing Summary. Ejecuta Product → Perform Action → Build With Timing Summary en Xcode para ver el tiempo de cada fase al final del registro. Empieza identificando aquí el destino y la fase que forman el cuello de botella.
Flags de advertencia del comprobador de tipos. El compilador indica directamente las funciones y expresiones lentas. Añádelos a Other Swift Flags.
-Xfrontend -warn-long-function-bodies=100
-Xfrontend -warn-long-expression-type-checking=100
// 100ms Mostrar advertencias para funciones y expresiones que superen el límite
Línea de tiempo de compilación. Abre la línea de tiempo en el área Assistant del registro para ver la ejecución paralela por destino. Los tramos largos en serie indican que el grafo de dependencias bloquea el paralelismo.
Qué más debes comprobar además de la modularización
Al medir, a menudo se descubre que el problema es una sola línea de configuración, no la modularización. Esta es la lista para compilaciones de depuración.
| Elemento | Configuración recomendada (Debug) |
|---|---|
| Debug Information Format | DWARF (desactivar la generación de dSYM) |
| Compilation Mode | Incremental |
| Optimization Level | -Onone |
| Build Active Architecture Only | Yes |
Desde Xcode 16, Explicitly Built Modules mejoró el paralelismo durante la preparación de módulos. Usar el Xcode más reciente también puede mejorar por sí mismo la velocidad de compilación.
Así se plantea en una entrevista
P. Explica tu enfoque para reducir los tiempos de compilación en una app de iOS a gran escala.
Primero mide los cuellos de botella con Build With Timing Summary y revisa la configuración (generación de dSYM en depuración y modo de compilación). Estructuralmente, lo esencial es usar modularización para limitar la recompilación al módulo, colocar el código que cambia a menudo aguas arriba y minimizar la superficie pública de los módulos aguas abajo.
P. Si la compilación sigue siendo lenta después de dividir los módulos, ¿qué sospecharías?
Comprueba si un módulo inferior compartido cambia con frecuencia y si su interfaz pública se modifica a menudo. Busca cuellos de botella de comprobación de tipos con flags de advertencia, divide las expresiones complejas y revisa la línea de tiempo para detectar un grafo serializado que bloquee la compilación paralela.
La velocidad de compilación es la recompensa más tangible de la modularización, pero cuando los módulos llegan a decenas, la gestión del proyecto se convierte en trabajo.
El último artículo de la serie trata Tuist, una herramienta que reduce ese coste de gestión. También resume cómo librarse de los conflictos de pbxproj y usar caché binaria.

![Imagen de portada de [Modularización #5] Por qué las compilaciones de Xcode son lentas y cómo solucionarlo](/assets/images/posts/6c275447-9dc0-4fd6-9d55-72f98e6a50b4/1.jpg)