> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Flujo de ejecución del motor

> Comprenda cómo funciona el motor de experimentación de Kameleoon, incluido un desglose detallado de las fases de carga, seguimiento y ejecución.

# Flujo de ejecución del motor

Conozca cómo el motor de experimentación carga, realiza el seguimiento y ejecuta los experimentos.

## Visión general del motor de experimentación

Kameleoon proporciona una solución de optimización en una única plataforma para la experimentación de aplicaciones web y full-stack. La plataforma admite dos soluciones principales:

* **Web Experimentation**: Realice pruebas A/B y otras formas de experimentación para sitios y aplicaciones web.
* **Feature Experimentation**: Habilite el feature flagging y la experimentación full-stack. Kameleoon también proporciona APIs y herramientas adicionales para eliminar el flickering en experimentos A/B, integrarse con sus herramientas existentes y automatizar tareas.

### Flujo del código: carga

```mermaid theme={null}
graph TD
    %% Main Flow Nodes
    EntryPoint(["Entry point"])
    JSFile(["Kameleoon.js"])
    
    LoadEngine(["Load the Kameleoon engine"])
    InitEngine(["Initialize the Kameleoon engine"])
    
    EventLoaded("Send the Kameleoon::Loaded event")
    CheckAbort(["Check abort conditions"])
    
    %% Branching Outcomes
    NoCond("No")
    YesCond("Yes")
    
    %% Yes Flow Nodes
    EventAborted("Send the Kameleoon::Aborted event")
    StopExecution("Stop the execution of Kameleoon<br>on the webpage")
    
    %% Side-Car/Optional Nodes
    DetailCmdQueue("Execute the Kameleoon CommandQueue code<br>with the level: IMMEDIATE argument")
    DetailFlicker("Optional: Remove the anti-flicker CSS rule.<br>Store the timestamp of the engine initialize completion step.")
    DetailDefer(["Optional: Defer all campaigns and configurations<br>(goals, segments, and so on) in a second call."])
    
    %% Continuation Placeholder
    NoDown("⬇")

    %% --- Connections ---
    
    %% Main Path
    EntryPoint --> JSFile
    JSFile --> LoadEngine
    LoadEngine --> InitEngine
    InitEngine --> EventLoaded
    EventLoaded --> CheckAbort
    
    %% Conditions
    CheckAbort --> NoCond
    CheckAbort --> YesCond
    
    %% Yes Path
    YesCond --> EventAborted
    EventAborted --> StopExecution
    
    %% No Path
    NoCond --> NoDown
    
    %% Side Actions
    LoadEngine --> DetailCmdQueue
    InitEngine --> DetailFlicker
    
    %% Connect the two Optional blocks
    DetailFlicker --> DetailDefer

    %% --- Styling ---
    classDef default fill:#F2F2FF,stroke:#8A8AC2,stroke-width:1px,color:#111;
    classDef whiteBox fill:#FFFFFF,stroke:#E2E2F2,stroke-width:1px,color:#111;
    classDef borderless fill:none,stroke:none,color:#111;
    
    class EventLoaded,EventAborted,StopExecution,DetailCmdQueue,DetailFlicker,NoCond,YesCond whiteBox;
    class NoDown borderless;
```

El motor de Kameleoon ejecuta la etiqueta `engine.js` (anteriormente `kameleoon.js`). Invoque esta etiqueta JavaScript a través del código fuente HTML de las páginas de su aplicación.

En el punto de entrada, el motor:

1. **Activación**: La etiqueta `engine.js` invoca una llamada a la Activation API a través de `Kameleoon.Analyst.load()`.

2. **Ejecución de la cola de comandos**: Tras la carga, el motor comprueba el [array kameleoonQueue](../../apis/activation-api-js/api-reference/command-queue#syntax) y ejecuta los comandos en el orden en que los haya añadido. Utilícelo para el código que deba ejecutarse antes de que Kameleoon instancie las funciones.

<Note>
  Kameleoon solo ejecuta las funciones añadidas a la cola con el parámetro `IMMEDIATE`.
</Note>

3. **Anti-flicker y variables globales**: El **flickering** se produce cuando la página original se muestra brevemente antes de que aparezca la variación. Este efecto puede provocar resultados inexactos. Kameleoon utiliza técnicas avanzadas para eliminar el flickering. Si configura el anti-flicker, el sistema carga el script de Kameleoon de forma asíncrona con [código anti-flicker](../implementation-and-deployment/standard-implementation#etiqueta-asíncrona-con-anti-flicker).

Una vez que Kameleoon termina de cargarse, la variable `window.KameleoonEndLoadTime` almacena la marca de tiempo de finalización.

<Note>
  Ajuste el timeout mediante la variable `kameleoonLoadingTimeout` en el snippet de instalación. Le recomendamos mantener el valor predeterminado de 1000 milisegundos (o 750 milisegundos para las implementaciones modernas). Esta variable determina el tiempo máximo durante el cual la etiqueta de instalación puede retrasar la visualización de la página mientras espera al archivo de aplicación.
</Note>

4. **Comprobación de motivos de bloqueo**: Antes de completar la inicialización, el motor comprueba los siguientes motivos de bloqueo:

   * **Storage**: Si el almacenamiento local o de sesión no está disponible, el motor finaliza y devuelve el evento `Kameleoon::Aborted` con el código `STORAGE`.
   * **Timeout**: Si `engine.js` tarda más de 750 ms en cargarse y ha configurado el proyecto para deshabilitar Kameleoon en la página o visita, el motor devuelve `TIMEOUT`.
   * **Prerender**: Kameleoon requiere que el documento esté listo (`document.visibilityState == "prerender"`). Si no lo está, el script finaliza y devuelve `PRERENDER`. Se recarga cuando cambia el estado de visibilidad.
   * **Custom script**: Si un script personalizado aborta la sesión, el motor devuelve `SCRIPT`.
   * **Parameter**: Si la URL contiene `KameleoonDisabled == true`, el motor devuelve `PARAMETER` y finaliza.
   * **Disabled**: Si deshabilita el proyecto en el panel, el motor devuelve `DISABLED`. Consulte [este artículo](/user-manual/project-management/manage-your-projects) para más detalles.

<Note>
  Solo un technical account manager de Kameleoon puede configurar scripts personalizados de cancelación.
</Note>

5. **Diferimientos**: El motor pospone el código y las campañas para una segunda llamada si es necesario. En este caso, el motor obtiene la configuración y las campañas en modo SYNC desde `https://SITECODE.kameleoon.com/engine-configuration.js` (anteriormente denominado `kameleoon-configuration.js`) y `https://SITECODE.kameleoon.com/engine-campaigns.js` (anteriormente denominado `kameleoon-actions.js`), respectivamente.

<Note>
  Solo un technical account manager de Kameleoon puede configurar la opción de aplazar todas las campañas. Puede aplazar experimentos específicos utilizando la etiqueta "DELAYED".
</Note>

Si no existen motivos de bloqueo, el motor avanza a la fase de seguimiento de datos del visitante.

### Flujo del código: seguimiento

```mermaid theme={null}
graph TD
    %% --- MAIN SPINE ---
    ParseBrowser(["Parse the browser and OS"])
    UnifySession("If the Unify session data across subdomains option is enabled:")
    RetrieveData["Send a message to the Kameleoon iframe to retrieve the data from the main domain's local storage.<br>Otherwise, retrieve it from the current local storage."]
    InitConsent(["Initialize consent management"])
    
    %% MERGED NODE: InitVisitor + its details
    InitVisitor["Initialize the Visitor object<br>---<br>1. Obtain all previous visits from local storage.<br>Optional: If the Real-Time Sync of visits option is enabled, an additional call retrieves visits stored on Kameleoon Data servers.<br><br>2. Generate a visitorCode ID if no existing one is found in the KameleoonVisitorCode cookie or local storage."]
    
    %% MERGED NODE: SendEvents + its detail
    SendEvents["Send events<br>---<br>Optional: Initialize the product recommendation history."]
    
    ExecGlobalScript(["Execute the project global custom script"])
    ExecQueue(["Execute the remaining code in the Kameleoon CommandQueue"])
    EventStarted(["Send the Kameleoon::Started event"])
    
    %% MERGED NODE: WaitDOM
    WaitDOM["Wait for the DOM to be ready.<br>---<br>Optional: If the Enable support for dynamic websites option is enabled, Kameleoon listens for URL changes to reload its engine."]
    
    InitCampaigns(["Initialize campaigns and actions"])
    FlowContinues("⬇")

    %% --- MAIN FLOW CONNECTIONS ---
    ParseBrowser --> UnifySession
    UnifySession --> RetrieveData
    RetrieveData --> InitConsent
    InitConsent --> InitVisitor
    InitVisitor --> SendEvents
    SendEvents --> ExecGlobalScript
    ExecGlobalScript --> ExecQueue
    ExecQueue --> EventStarted
    EventStarted --> WaitDOM
    WaitDOM --> InitCampaigns
    InitCampaigns --> FlowContinues

    %% --- BRANCHES (Now with plenty of room to fan out) ---
    
    %% Event Branches
    PageEvent("Page event<br>---<br>Page URL and title")
    StaticDataEvent("StaticData event<br>---<br>Data about the device, OS, window size, visit number, time since previous visit, timezone, and language")
    ActivityEvent("Activity event<br>---<br>Data about clicks and activity")

    SendEvents --> PageEvent
    SendEvents --> StaticDataEvent
    SendEvents --> ActivityEvent

    %% Campaign Branches
    Adblocker("Check Adblocker<br>---<br>Check if the visitor is using an adblocker, and send an Adblocker event if they are.")
    RunMutObs("Run MutationObserver<br>---<br>Run the optimization MutationObserver to fill all classes of elements and IDs present on the page for querySelector optimization.")
    GeoOpt("Optional: Geolocation / IP<br>---<br>IP: IP request to get the user IP address (https://data.kameleoon.io/ip).<br>Geolocation: Request to get user geolocation (Country, Region, City).")
    LiveUpdateOpt("Optional: Live Update<br>---<br>Load configuration from https://SITECODE.kameleoon.com/live-experiments/config.js.")

    InitCampaigns --> Adblocker
    InitCampaigns --> RunMutObs
    InitCampaigns --> GeoOpt
    InitCampaigns --> LiveUpdateOpt

    %% --- STYLING ---
    classDef default fill:#F2F2FF,stroke:#8A8AC2,stroke-width:1px,color:#111;
    classDef whiteBox fill:#FFFFFF,stroke:#E2E2F2,stroke-width:1px,color:#111;
    classDef detailBox fill:#FFFFFF,stroke:#8A8AC2,stroke-width:2px,color:#111;
    classDef borderless fill:none,stroke:none,color:#111;

    class UnifySession,RetrieveData,PageEvent,StaticDataEvent,ActivityEvent,Adblocker,RunMutObs,GeoOpt,LiveUpdateOpt whiteBox;
    
    %% Detail boxes get a slightly thicker border to denote they contain sub-steps
    class InitVisitor,SendEvents,WaitDOM detailBox;
    class FlowContinues borderless;
```

Tras la inicialización, Kameleoon recupera los datos del visitante:

1. Kameleoon recopila datos técnicos como el navegador y el sistema operativo del visitante.
2. Si habilita [unify session data across subdomains](../technical-concepts/unify-session-data-storage-across-subdomains), Kameleoon recupera datos anteriores utilizando un iFrame en el dominio principal de local storage.
3. Si habilita `real-time sync of visits` o la opción [`cross-device`](../../cross-device-experimentation), el motor obtiene el historial de uso desde los servidores de Kameleoon.

<Note>
  La sincronización en tiempo real está activa por defecto para Kameleoon Feature Experimentation o para Safari, con el fin de gestionar los [impactos de ITP](../technical-concepts/itp-management).
</Note>

4. El motor inicializa un visitante. Si no existe ningún código en la cookie `kameleoonVisitorCode` ni en el local storage, el motor asigna un nuevo código de visitante y analiza todas las visitas.
5. El motor analiza y almacena datos como la URL de la página, el dispositivo, el sistema operativo, la geolocalización y los objetivos.

<Note>
  Si utiliza el complemento de recomendación de productos, Kameleoon instancia aquí el motor de recomendaciones.
</Note>

6. El script personalizado global ejecuta cualquier JavaScript insertado antes de inicializar los experimentos.
7. El script global del experimento se ejecuta después del script global personalizado. Este script se ejecuta independientemente de la segmentación y se detiene cuando el experimento se pausa. Consulte [esta guía](/user-manual/experimentation/web-experimentation/graphic-based-experiments/getting-started-with-the-graphic-editor#Experiment-specific_custom_script) para más detalles.
8. El motor ejecuta los comandos pendientes de la `CommandQueue` que no utilizan el parámetro `IMMEDIATE`.
9. El evento `Kameleoon::Started` se desencadena cuando la inicialización se completa y el motor almacena los datos.
10. Si habilita la [gestión de SPA](/user-manual/experimentation/web-experimentation/advanced-experiment-types/set-up-experiment-single-page-app), Kameleoon monitoriza los cambios de URL. Cuando la URL cambia, el motor se recarga para garantizar que las campañas funcionen correctamente en la nueva vista.
11. Antes de inicializar las campañas, Kameleoon:
    * Comprueba si hay un bloqueador de anuncios.
    * Ejecuta `mutationObserver` para optimizar las operaciones de `querySelector`.
    * Obtiene los datos de geolocalización desde `https://eu-data.kameleoon.io/ip` si el segmento lo requiere.
12. Para cargar la configuración de la campaña, Kameleoon obtiene datos de `https://SITECODE.kameleoon.com/live-experiments/config.js` y los almacena en caché durante 2 minutos.

<Note>
  La funcionalidad Live Update Experiments actualiza los experimentos etiquetados con `LIVE-UPDATE` para permitir cambios de configuración en tiempo real sin retrasos por el almacenamiento en caché del navegador.
</Note>

### Flujo del código: ejecución

```mermaid theme={null}
graph TD
    %% Main Start Node
    StartNode(["Run all Experiments / Personalizations"])

    %% --- LEFT BRANCH: Holdout Control ---
    %% Check Node
    CheckHoldout(["Check if visitor is in an 'Holdout Control group'"])
    
    %% Outcomes
    OutcomeNo[No]
    OutcomeYes[Yes]

    %% No Flow Nodes
    HoldoutInclusionEvent(["Send holdout inclusion event"])
    IfTargetingTrue(["If targeting is 'true' for the visitor"])
    OptionalDelayedTag(["(Optional) If the campaign has a 'DELAYED' tag"])
    DownloadVariationData["<b>Download variation data</b><br>---<br>https://SITECODE.kameleoon.com/{personalizations/experiments}/$campaign_id/variations/$variation_id.js"]
    SendExpPersEvent(["Send Experiment / Personalization event"])
    
    %% Yes Flow Nodes
    HoldoutExclusionEvent(["Send holdout exclusion event"])

    %% Left Branch Connections
    StartNode --> CheckHoldout
    CheckHoldout --> OutcomeNo
    CheckHoldout --> OutcomeYes
    OutcomeNo --> HoldoutInclusionEvent
    HoldoutInclusionEvent --> IfTargetingTrue
    IfTargetingTrue --> OptionalDelayedTag
    OptionalDelayedTag --> DownloadVariationData
    DownloadVariationData --> SendExpPersEvent
    OutcomeYes --> HoldoutExclusionEvent

    %% --- RIGHT BRANCH: Targeting and Goals ---
    %% Split Point Node
    RunTargetingSegments(["Run all Targeting Segments"])
    
    %% Splitting Nodes
    %% Flow 1: Targeting Event
    IfSegmentConditions(["If the segment conditions are met for the visitor"])
    SendTargetingEvent(["Send Targeting event"])
    
    %% Flow 2: Goal Flow
    OptionalAIOpportunity(["(Optional) If the AI Opportunity Detection add-on is enabled"])
    DownloadOpportunitySegment["<b>Download opportunity segment and execute them</b><br>---<br>https://SITECODE.kameleoon.com/audiences/segments.js"]
    RunAllGoals(["Run all goals"])
    IfGoalConverted(["If the goal is converted for the visitor"])
    SendGoalEvent(["Send Goal event"])

    %% Right Branch Connections
    StartNode --> RunTargetingSegments
    
    %% Flow 1 Connections
    RunTargetingSegments --> IfSegmentConditions
    IfSegmentConditions --> SendTargetingEvent
    
    %% Flow 2 Connections
    RunTargetingSegments --> OptionalAIOpportunity
    OptionalAIOpportunity --> DownloadOpportunitySegment
    DownloadOpportunitySegment --> RunAllGoals
    RunAllGoals --> IfGoalConverted
    IfGoalConverted --> SendGoalEvent

    %% --- STYLING ---
    classDef mainStep fill:#F2F2FF,stroke:#8A8AC2,stroke-width:1px,rx:10,ry:10,color:#111;
    classDef whiteBox fill:#FFFFFF,stroke:#E2E2F2,stroke-width:1px,color:#111;
    classDef conditionalPill fill:#D0D0FF,stroke:#8A8AC2,stroke-width:1.5px,rx:10,ry:10,color:#111;
    classDef outcome fill:#ffffff,stroke:#8A8AC2,stroke-width:1px,rx:5,ry:5,color:#111;

    class StartNode,CheckHoldout,HoldoutInclusionEvent,HoldoutExclusionEvent,SendExpPersEvent,RunTargetingSegments,SendTargetingEvent,RunAllGoals,SendGoalEvent mainStep;
    class DownloadVariationData,DownloadOpportunitySegment whiteBox;
    class IfTargetingTrue,OptionalDelayedTag,IfSegmentConditions,OptionalAIOpportunity,IfGoalConverted conditionalPill;
    class OutcomeNo,OutcomeYes outcome;
```

Cuando se ejecuta el bucle de experimentación, el motor:

1. Si el visitante forma parte de un grupo "holdout", el motor envía un evento de inclusión en el holdout.
2. El motor desencadena un evento de exposición que contiene un `nonce`, un `experimentID` y un `variationId`. Por ejemplo: `eventType=experiment&nonce=5800F1BDD0667747&id=250830&variationId=978588`.
3. Si el visitante no está en un grupo holdout, el motor envía un "evento de exclusión del holdout".

<Note>
  Los experimentos holdout le permiten gestionar y bloquear otros experimentos:

  * El motor comprueba primero los experimentos holdout.
  * Si un usuario está en un grupo holdout, el motor lo asigna a un grupo y envía un evento para los informes.
  * Si el usuario está en el grupo de referencia, el motor bloquea todos los demás experimentos.
  * Si el usuario está en el grupo de variación, el motor permite que continúen los demás experimentos.

  Más información en la [guía de gestión de holdouts](/user-manual/experiment-analytics/analyze-results/advanced-analysis/create-and-manage-holdouts).
</Note>

A continuación, el motor inicia la recopilación de datos. Si una personalización se desencadena pero no se muestra, el motor devuelve uno de los siguientes motivos de bloqueo:

* **PERSONALIZATION\_CAPPING**: La personalización ha alcanzado su límite global de visitantes.
* **SCHEDULE**: La personalización está desactivada según su programación.
* **SCENARIO**: Algunas condiciones del escenario no se cumplen.
* **PRIORITY**: Existe una personalización de mayor prioridad.
* **VISITOR\_CAPPING**: El visitante ha alcanzado un límite que impide su visualización.

Si asocia una etiqueta `DELAYED` a un experimento, el motor lo desencadena después de la primera carga de página. El motor descarga los datos de la variación desde `https://SITECODE.kameleoon.com/(personalizations)/$campaign_id/variations/$variation_id.js`.

<Note>
  Aplazar un experimento es útil para popups o modificaciones por debajo del pliegue, donde el flickering es mínimo.
</Note>

Para el complemento AI Opportunity Detection, Kameleoon descarga las definiciones de segmentos desde `https://SITECODE.kameleoon.com/audiences/segments.js` para detectar oportunidades.

<Note>
  Kameleoon comprueba los segmentos creados o modificados en los últimos 90 días, excluyendo los que comienzan por `[DEV]`, `[TEST]` o `[QA]`.
</Note>

Analice esta información en la página de resultados para hacer seguimiento de las tasas de conversión y el potencial crecimiento de ingresos.
