Módulo 2: Funnels And Conversion
Encontrar el drop-off más grande
Descripción
El drop-off de un paso es la cantidad de usuarios que se pierden respecto al paso anterior (dropOff = usuarios_paso_N-1 - usuarios_paso_N), y el drop-off rate es esa pérdida expresada como proporción del paso anterior (dropOffRate = dropOff / usuarios_paso_N-1, que es exactamente 1 - conversionRate). Esta lección junta todo lo que construiste en las lecciones 3 y 4 —tasa por paso, conversión global— en una sola función, funnelAnalysis(), que además identifica el paso con mayor dropOffRate: el que, en proporción, más gente deja pasar por sus agujeros. Ese paso es la palanca de mayor impacto potencial del funnel.
Conexión con el módulo. Esta lección responde, de forma explícita y automatizada, la pregunta que quedó abierta desde la presentación del módulo y que la lección 3 empezó a contestar a mano: ¿cuál es el paso con la peor proporción de fuga? Aquí no lo calculas leyendo una tabla — lo calcula el código, con una regla clara (dropOffRate más alto), y el resultado es la base directa del proyecto final del módulo.
Una analogía cotidiana: el agujero más grande de la coladera, no el nivel con más agua encima
Volviendo a la coladera de niveles: si quieres arreglar la coladera para que llegue más agua al fondo, no tiene sentido enfocarte en el nivel que tiene más agua encima (ese nivel va a perder más agua en litros casi por definición, solo por tener más para empezar). Lo que quieres encontrar es el nivel cuyo agujero es proporcionalmente el más grande — el que deja pasar la menor fracción del agua que le llega. Ese es el nivel que, si lo arreglas, va a mejorar más el resultado final, sin importar cuánta agua tenía encima al empezar. dropOffRate es exactamente la medida de "qué tan grande es el agujero de este nivel, en proporción a lo que le llegó" — no "cuánta agua se perdió aquí en litros".
Ejemplo trabajado: funnelAnalysis() completo sobre el checkout de Mercado
// L5: funnelAnalysis completo -- conversionRate y dropOff por paso, conversion global,
// y el paso con mayor dropOffRate (la mayor palanca).
function funnelAnalysis(steps) {
const withRates = steps.map((step, i) => {
if (i === 0) {
return { name: step.name, users: step.users, conversionRate: null, dropOff: 0, dropOffRate: null };
}
const prevUsers = steps[i - 1].users;
const conversionRate = step.users / prevUsers;
const dropOff = prevUsers - step.users;
const dropOffRate = dropOff / prevUsers;
return { name: step.name, users: step.users, conversionRate, dropOff, dropOffRate };
});
const overallConversion = steps[steps.length - 1].users / steps[0].users;
const worstStep = withRates.slice(1).reduce((worst, s) => (s.dropOffRate > worst.dropOffRate ? s : worst));
return { steps: withRates, overallConversion, worstStep: worstStep.name, worstDropOffRate: worstStep.dropOffRate };
}
const funnel = [
{ name: 'visit', users: 10000 },
{ name: 'view_product', users: 6000 },
{ name: 'add_to_cart', users: 2400 },
{ name: 'checkout', users: 1200 },
{ name: 'purchase', users: 900 },
];
const result = funnelAnalysis(funnel);
console.log('=== funnelAnalysis() sobre el checkout de Mercado ===\n');
result.steps.forEach((s) => {
const conv = s.conversionRate === null ? '—' : (s.conversionRate * 100).toFixed(1) + '%';
const drop = s.dropOffRate === null ? '—' : (s.dropOffRate * 100).toFixed(1) + '%';
console.log(
' ' + s.name.padEnd(14) +
String(s.users).padStart(6) + ' users' +
' conversionRate: ' + conv.padStart(6) +
' dropOff: ' + String(s.dropOff).padStart(5) +
' dropOffRate: ' + drop.padStart(6)
);
});
console.log('\n Conversion global (visit -> purchase): ' + (result.overallConversion * 100).toFixed(1) + '%');
console.log(' Paso con mayor fuga: ' + result.worstStep + ' (dropOffRate: ' + (result.worstDropOffRate * 100).toFixed(1) + '%)');
Qué esperar. Al correr el archivo con Node, la salida es exactamente esta:
=== funnelAnalysis() sobre el checkout de Mercado ===
visit 10000 users conversionRate: — dropOff: 0 dropOffRate: —
view_product 6000 users conversionRate: 60.0% dropOff: 4000 dropOffRate: 40.0%
add_to_cart 2400 users conversionRate: 40.0% dropOff: 3600 dropOffRate: 60.0%
checkout 1200 users conversionRate: 50.0% dropOff: 1200 dropOffRate: 50.0%
purchase 900 users conversionRate: 75.0% dropOff: 300 dropOffRate: 25.0%
Conversion global (visit -> purchase): 9.0%
Paso con mayor fuga: add_to_cart (dropOffRate: 60.0%)
funnelAnalysis() confirma, con una regla explícita en código (s.dropOffRate > worst.dropOffRate), lo que la lección 3 encontró a mano: el paso con mayor fuga es add_to_cart, con un dropOffRate de 60%. Míralo con las cuatro columnas juntas, lado a lado, y nota el patrón completo:
view_productpierde 4,000 usuarios en números absolutos (la caída más grande de la tabla), pero sudropOffRatees de solo 40% — es el segundo mejor paso del funnel, proporcionalmente.add_to_cartpierde 3,600 usuarios en números absolutos (menos queview_product), pero sudropOffRatees del 60% — el peor de los cuatro. Es, literalmente, el agujero proporcionalmente más grande de la coladera.checkoutpierde solo 1,200 usuarios, con undropOffRatede 50% — segundo peor.purchasees, con diferencia, el paso más sano: pierde solo 300 usuarios, undropOffRatede apenas 25%.
Si un equipo de Mercado tuviera que elegir un solo paso del checkout para invertir el próximo trimestre de ingeniería y diseño, esta tabla dice, sin ambigüedad, cuál: add_to_cart. No es el paso con más tráfico (ese es visit), ni el paso con la caída absoluta más grande (ese es view_product) — es el paso donde, proporcionalmente, se pierde la mayor fracción de la gente que llegó. Esa es exactamente la palanca de mayor impacto potencial, y el proyecto de la lección 8 va a cuantificar cuánto vale, en compras adicionales, arreglar ese paso específico.
dropOffRate es simplemente 1 - conversionRate: por qué la función calcula ambos
Fíjate que dropOffRate de add_to_cart es 60% y su conversionRate es 40% — suman exactamente 100%, porque son la misma información vista desde dos ángulos: la fracción que sí siguió (conversionRate) y la fracción que no siguió (dropOffRate). ¿Por qué entonces funnelAnalysis() calcula ambos números en vez de solo uno? Porque cada uno responde mejor una pregunta distinta: conversionRate es el que usas para calcular la conversión global (lección 4, multiplicando supervivencias), y dropOffRate es el que usas para priorizar entre pasos (esta lección, buscando el máximo). Tener los dos, calculados explícitamente y con nombre propio en el objeto que devuelve la función, evita el error de tener que restar 1 - x mentalmente cada vez que quieres comparar pasos — un paso extra de aritmética mental es, en la práctica, un lugar más donde alguien se equivoca bajo presión en una reunión.
Errores comunes
Mirar solo la conversión global y no el paso fugado. Qué pasa: un equipo reporta "nuestra conversión de checkout es del 9%" trimestre tras trimestre, la usa como el único número de seguimiento, y nunca desagrega dónde, dentro del funnel, se concentra esa pérdida — así que cuando llega el momento de decidir en qué invertir, no hay ninguna base de datos para decidir, solo intuición. Por qué pasa: la conversión global es un solo número, fácil de poner en un slide y de comparar mes a mes; desagregarla por paso exige una tabla completa, que se siente como "más trabajo" para una reunión que solo quiere ver si el número sube o baja. Cómo detectarlo: si el reporte de conversión de un producto tiene un solo número (la conversión global) y ningún desglose por paso, el equipo puede saber que algo empeoró, pero no dónde actuar — es un guardrail, no una herramienta de diagnóstico. Cómo corregirlo: la conversión global (lección 4) y el desglose por paso con dropOffRate (esta lección) no son alternativas, son complementarias — la primera te dice si el funnel completo mejora o empeora; la segunda te dice en qué paso específico actuar para moverlo. Reporta ambas siempre juntas.
Elegir el peor paso mirando dropOff (el número absoluto) en vez de dropOffRate (la proporción). Qué pasa: alguien lee la tabla de funnelAnalysis(), ve que view_product tiene el dropOff más alto (4,000, más que los 3,600 de add_to_cart), y concluye que ese es el paso a priorizar — invirtiendo el orden correcto de prioridad que ya viste en esta misma lección. Por qué pasa: dropOff está expresado en la misma unidad que users (personas), que es más fácil de imaginar intuitivamente ("perdimos 4,000 personas") que un porcentaje abstracto; el cerebro prefiere números concretos sobre proporciones. Cómo detectarlo: si la justificación de "por qué priorizamos este paso" cita un número de usuarios perdidos en vez de un porcentaje de fuga, revisa si se está comparando dropOff en vez de dropOffRate. Cómo corregirlo: la regla dura de funnelAnalysis() es clara y no admite ambigüedad: el peor paso se decide con dropOffRate (s.dropOffRate > worst.dropOffRate), nunca con dropOff. El único caso en el que dropOff (el número absoluto) importa más es al calcular el impacto en usuarios reales de arreglar un paso — pero eso es el modelo de la lección 8, un paso distinto y posterior a decidir cuál paso priorizar.
Ejercicios
Ejercicio 1 — Encuentra el peor paso a mano. Un funnel tiene estos datos: signup: 4000, verify_email: 3600, set_password: 1800, first_login: 1500. Calcula el dropOffRate de cada paso (excepto signup) y di cuál es el peor.
Ver solución
verify_email: dropOff = 4000 - 3600 = 400, dropOffRate = 400/4000 = 10%. set_password: dropOff = 3600 - 1800 = 1800, dropOffRate = 1800/3600 = 50%. first_login: dropOff = 1800 - 1500 = 300, dropOffRate = 300/1800 ≈ 16.7%. El peor paso es set_password, con un dropOffRate del 50% — la mitad de la gente que verificó su email nunca llega a poner una contraseña. Fíjate que, en números absolutos, set_password también tiene el dropOff más alto (1,800) en este ejemplo — pero eso es coincidencia de estos datos específicos, no una regla general; en el funnel de Mercado, el peor paso por tasa (add_to_cart, 3,600 de caída) tampoco tenía la caída absoluta más grande (esa era de view_product, con 4,000).
Ejercicio 2 — Diseña un funnel donde el peor paso por dropOff y por dropOffRate sean el mismo. Inventa cuatro números de usuarios para un funnel de tres pasos donde el paso con el dropOff (número absoluto) más alto también tenga el dropOffRate (proporción) más alto — es decir, un caso donde ambos criterios coinciden en vez de contradecirse como en el funnel de Mercado.
Ver solución
Un ejemplo válido: [{name:'a', users: 1000}, {name:'b', users: 800}, {name:'c', users: 200}]. Paso b: dropOff = 200, dropOffRate = 200/1000 = 20%. Paso c: dropOff = 600, dropOffRate = 600/800 = 75%. Aquí c gana en las dos métricas: tiene el dropOff más alto (600 contra 200) y el dropOffRate más alto (75% contra 20%). Esto puede pasar cuando el paso con peor tasa también ocurre en un punto del funnel con volumen todavía considerable de usuarios (no muy al fondo del embudo, donde los números absolutos ya son chicos por naturaleza). El caso de Mercado, donde los dos criterios discrepan, es más instructivo para el módulo, pero ambos casos son posibles en datos reales — por eso funnelAnalysis() nunca asume cuál va a coincidir, y siempre usa dropOffRate como criterio de decisión.
Ejercicio 3 — Ubica el error en una decisión de producto. Un product manager dice: "Vamos a invertir el sprint en optimizar view_product, porque ahí es donde perdemos más usuarios en total (4,000, según el dashboard)". Usando los datos del funnel de Mercado de esta lección, explica por qué esa decisión, tal como está justificada, no sigue la regla de funnelAnalysis().
Ver solución
La decisión usa dropOff (4,000, el número absoluto más alto) como criterio, cuando funnelAnalysis() usa dropOffRate para decidir el peor paso. Con el dropOffRate como criterio, view_product tiene 40% de fuga — el segundo mejor de los cuatro pasos, no el peor. El paso que realmente tiene la mayor palanca proporcional es add_to_cart, con 60% de fuga. Esto no significa que invertir en view_product sea necesariamente una mala idea en algún sentido más amplio del negocio (podría haber otras razones válidas, como el volumen de tráfico que pasa por ahí) — pero la justificación específica que dio el PM ("es donde perdemos más usuarios") describe dropOff, no dropOffRate, y por lo tanto no es la razón correcta para priorizar ese paso sobre add_to_cart según la lógica de esta lección.
Resumen y siguiente paso
funnelAnalysis() junta la tasa de conversión (lección 3), la conversión global (lección 4) y una nueva pieza —dropOff y dropOffRate por paso— en una sola función que además identifica automáticamente el paso con mayor fuga proporcional. En el checkout de Mercado, ese paso es add_to_cart, con un dropOffRate del 60%: el agujero más grande de la coladera, no el nivel con más agua encima.
Antes de avanzar deberías poder: calcular dropOff y dropOffRate de un paso a mano; y explicar, con el ejemplo de Mercado, por qué el paso con mayor dropOff absoluto no es necesariamente el paso con mayor dropOffRate.
Hasta ahora, cada tasa que calculaste fue local — un paso contra el inmediatamente anterior (micro-conversión). La lección 6 introduce su contraparte: la macro-conversión, la tasa de un tramo más amplio del funnel (por ejemplo, de view_product a purchase, saltándose pasos intermedios), y cuándo cada una es la pregunta correcta para hacer.
Recursos
- Amplitude, "What Is Funnel Drop-Off: Complete Guide to Identification & Prevention" — amplitude.com/explore/analytics/funnel-drop-off. Guía específica sobre cómo identificar el paso con mayor fuga en un funnel real. En inglés.
- Amplitude, "Identify conversion drivers in your funnel analyses" — amplitude.com/docs/analytics/charts/funnel-analysis/funnel-analysis-identify-conversion-drivers. Documentación sobre cómo priorizar qué paso de un funnel atacar primero. En inglés.
- Mixpanel, "Funnels: Measure conversions through a series of events" — docs.mixpanel.com/docs/reports/funnels. Referencia sobre cómo una herramienta real calcula y visualiza el drop-off por paso. En inglés.