[{"data":1,"prerenderedAt":796},["ShallowReactive",2],{"navigation":3,"\u002Fes\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals":177},[4,62],{"title":5,"path":6,"stem":7,"children":8},"About","\u002Fen","en\u002F1.index",[9,10,56],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13,"children":14},"Blog","\u002Fen\u002Farticles","en\u002F2.articles",[15],{"title":16,"path":17,"stem":18,"children":19,"page":33},"2026","\u002Fen\u002Farticles\u002F2026","en\u002Farticles\u002F2026",[20,34,47],{"title":21,"path":22,"stem":23,"children":24,"page":33},"April","\u002Fen\u002Farticles\u002F2026\u002Fapril","en\u002Farticles\u002F2026\u002Fapril",[25,29],{"title":26,"path":27,"stem":28},"Improving My App's Vibes with DESIGN.md","\u002Fen\u002Farticles\u002F2026\u002Fapril\u002Fexploring-llm-ui","en\u002Farticles\u002F2026\u002Fapril\u002Fexploring-llm-ui",{"title":30,"path":31,"stem":32},"How I Made My Fork Bilingual and Published It Right","\u002Fen\u002Farticles\u002F2026\u002Fapril\u002Fhow-i-made-my-fork-bilingual-and-published-it-right","en\u002Farticles\u002F2026\u002Fapril\u002Fhow-i-made-my-fork-bilingual-and-published-it-right",false,{"title":35,"path":36,"stem":37,"children":38,"page":33},"July","\u002Fen\u002Farticles\u002F2026\u002Fjuly","en\u002Farticles\u002F2026\u002Fjuly",[39,43],{"title":40,"path":41,"stem":42},"From Idea to MS Teams: Deploying an Agent","\u002Fen\u002Farticles\u002F2026\u002Fjuly\u002Ffrom-idea-to-ms-teams-agent","en\u002Farticles\u002F2026\u002Fjuly\u002Ffrom-idea-to-ms-teams-agent",{"title":44,"path":45,"stem":46},"Legally Spying on Your Competition is Possible","\u002Fen\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals","en\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals",{"title":48,"path":49,"stem":50,"children":51,"page":33},"May","\u002Fen\u002Farticles\u002F2026\u002Fmay","en\u002Farticles\u002F2026\u002Fmay",[52],{"title":53,"path":54,"stem":55},"Building an Agent's Personality Around the Customer Journey","\u002Fen\u002Farticles\u002F2026\u002Fmay\u002Fbuilding-agents-with-personality","en\u002Farticles\u002F2026\u002Fmay\u002Fbuilding-agents-with-personality",{"title":57,"path":58,"stem":59,"children":60},"Index","\u002Fen\u002Farticles_index","en\u002F4.articles_index",[61],{"title":57,"path":58,"stem":59},{"title":63,"path":64,"stem":65,"children":66},"Acerca De","\u002Fes","es\u002F1.index",[67,68,153,171],{"title":63,"path":64,"stem":65},{"title":11,"path":69,"stem":70,"children":71},"\u002Fes\u002Farticles","es\u002F2.articles",[72,95,117],{"title":73,"path":74,"stem":75,"children":76,"page":33},"2024","\u002Fes\u002Farticles\u002F2024","es\u002Farticles\u002F2024",[77,86],{"title":78,"path":79,"stem":80,"children":81,"page":33},"Diciembre","\u002Fes\u002Farticles\u002F2024\u002Fdiciembre","es\u002Farticles\u002F2024\u002Fdiciembre",[82],{"title":83,"path":84,"stem":85},"Diciembre es un mes más","\u002Fes\u002Farticles\u002F2024\u002Fdiciembre\u002Fhaikus","es\u002Farticles\u002F2024\u002Fdiciembre\u002Fhaikus",{"title":87,"path":88,"stem":89,"children":90,"page":33},"Octubre","\u002Fes\u002Farticles\u002F2024\u002Foctubre","es\u002Farticles\u002F2024\u002Foctubre",[91],{"title":92,"path":93,"stem":94},"Viaje de regreso","\u002Fes\u002Farticles\u002F2024\u002Foctubre\u002Fhaikus","es\u002Farticles\u002F2024\u002Foctubre\u002Fhaikus",{"title":96,"path":97,"stem":98,"children":99,"page":33},"2025","\u002Fes\u002Farticles\u002F2025","es\u002Farticles\u002F2025",[100,109],{"title":101,"path":102,"stem":103,"children":104,"page":33},"Agosto","\u002Fes\u002Farticles\u002F2025\u002Fagosto","es\u002Farticles\u002F2025\u002Fagosto",[105],{"title":106,"path":107,"stem":108},"Hola Mundo","\u002Fes\u002Farticles\u002F2025\u002Fagosto\u002Fholamundo","es\u002Farticles\u002F2025\u002Fagosto\u002Fholamundo",{"title":87,"path":110,"stem":111,"children":112,"page":33},"\u002Fes\u002Farticles\u002F2025\u002Foctubre","es\u002Farticles\u002F2025\u002Foctubre",[113],{"title":114,"path":115,"stem":116},"El Antipatrón de la Red Veloz","\u002Fes\u002Farticles\u002F2025\u002Foctubre\u002Flatencia","es\u002Farticles\u002F2025\u002Foctubre\u002Flatencia",{"title":16,"path":118,"stem":119,"children":120,"page":33},"\u002Fes\u002Farticles\u002F2026","es\u002Farticles\u002F2026",[121,133,145],{"title":21,"path":122,"stem":123,"children":124,"page":33},"\u002Fes\u002Farticles\u002F2026\u002Fapril","es\u002Farticles\u002F2026\u002Fapril",[125,129],{"title":126,"path":127,"stem":128},"Mejorando las VIBES de mi aplicación con DESIGN.md","\u002Fes\u002Farticles\u002F2026\u002Fapril\u002Fexploring-llm-ui","es\u002Farticles\u002F2026\u002Fapril\u002Fexploring-llm-ui",{"title":130,"path":131,"stem":132},"Cómo volví mi fork multilenguaje y lo publiqué bien","\u002Fes\u002Farticles\u002F2026\u002Fapril\u002Fhow-i-made-my-fork-bilingual-and-published-it-right","es\u002Farticles\u002F2026\u002Fapril\u002Fhow-i-made-my-fork-bilingual-and-published-it-right",{"title":35,"path":134,"stem":135,"children":136,"page":33},"\u002Fes\u002Farticles\u002F2026\u002Fjuly","es\u002Farticles\u002F2026\u002Fjuly",[137,141],{"title":138,"path":139,"stem":140},"De Idea a Ms Teams: Desplegando un Agente","\u002Fes\u002Farticles\u002F2026\u002Fjuly\u002Ffrom-idea-to-ms-teams-agent","es\u002Farticles\u002F2026\u002Fjuly\u002Ffrom-idea-to-ms-teams-agent",{"title":142,"path":143,"stem":144},"Espiar a Tu Competencia de Manera Legal es Posible","\u002Fes\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals","es\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals",{"title":48,"path":146,"stem":147,"children":148,"page":33},"\u002Fes\u002Farticles\u002F2026\u002Fmay","es\u002Farticles\u002F2026\u002Fmay",[149],{"title":150,"path":151,"stem":152},"Construyendo la personalidad de un agente en base a la travesía del cliente","\u002Fes\u002Farticles\u002F2026\u002Fmay\u002Fbuilding-agents-with-personality","es\u002Farticles\u002F2026\u002Fmay\u002Fbuilding-agents-with-personality",{"title":154,"path":155,"stem":156,"children":157},"Galería","\u002Fes\u002Fgallery","es\u002F3.gallery",[158],{"title":96,"path":159,"stem":160,"children":161,"page":33},"\u002Fes\u002Fgallery\u002F2025","es\u002Fgallery\u002F2025",[162],{"title":163,"path":164,"stem":165,"children":166,"page":33},"Septiembre","\u002Fes\u002Fgallery\u002F2025\u002Fseptiembre","es\u002Fgallery\u002F2025\u002Fseptiembre",[167],{"title":168,"path":169,"stem":170},"Cielo de Oyón","\u002Fes\u002Fgallery\u002F2025\u002Fseptiembre\u002Fholamundo","es\u002Fgallery\u002F2025\u002Fseptiembre\u002Fholamundo",{"title":172,"path":173,"stem":174,"children":175},"Lista","\u002Fes\u002Farticles_index","es\u002F4.articles_index",[176],{"title":172,"path":173,"stem":174},{"id":178,"title":142,"author":179,"badges":183,"body":184,"canonical":183,"cover":781,"date":782,"description":783,"extension":784,"layout":785,"meta":786,"navigation":638,"path":143,"seo":792,"stem":144,"__hash__":795},"content\u002Fes\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals.md",{"name":180,"url":181,"avatarUrl":182},"Ever Burga","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Feverburga\u002F","https:\u002F\u002Fwww.linkedin.com\u002F",null,{"type":185,"value":186,"toc":765},"minimark",[187,191,208,211,214,217,220,230,239,244,249,252,255,258,261,269,272,276,279,290,293,296,300,303,306,310,320,323,327,336,339,342,345,348,352,355,359,362,375,384,389,457,468,518,533,537,540,548,551,554,558,696,701,705,740,751,754,758,761],[188,189,142],"h1",{"id":190},"espiar-a-tu-competencia-de-manera-legal-es-posible",[192,193,196],"div",{"className":194},[195],"hero-breakout",[192,197,200],{"className":198},[199],"hero-breakout-inner",[201,202,203],"p",{},[204,205],"img",{"alt":206,"src":207},"Diagrama del flujo de rastreo de la competencia con datos abiertos","\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals-hero.svg",[201,209,210],{},"¿Cómo se obtiene datos de usuario de páginas que te interesa monitorear?",[201,212,213],{},"Usando datos públicos de Google!",[201,215,216],{},"No es necesario un scraper o suscripciones costosas a wappalyzer.",[201,218,219],{},"Solo necesitas ",[221,222,223,227],"ul",{},[224,225,226],"li",{},"La base de datos en bq y api de crux.",[224,228,229],{},"La base de datos de http archive en bq.",[201,231,232],{},[233,234,238],"a",{"href":235,"rel":236},"https:\u002F\u002Ftheuxreport.kekeros.com",[237],"nofollow","theuxreport",[240,241,243],"h2",{"id":242},"decisiones-de-arquitectura","Decisiones de Arquitectura",[245,246,248],"h3",{"id":247},"primero-veamos-la-naturaleza-de-las-fuentes-de-datos","Primero veamos la naturaleza de las fuentes de datos",[201,250,251],{},"Las BD de crux y http archive se actualizan mensualmente. Crux tiene un retraso de 2 meses, mientras que http archive de solo 1 mes. Esta diferencia tiene impacto para el análisis de datos. Por eso conviene etiquetar el mes de provenance de cada dato que ingrese a nuestro data lake. ",[201,253,254],{},"Por otro lado, para el usuario final que solo quiere ver reportes, la diferencia de 1 mes no importa mucho. Incluso se podría interpretar como un retraso de procesamiento o algun desfase insignificante entre los gráficos históricos. ",[201,256,257],{},"Ahora, si nos enfocamos en el volumen de datos, cada base de datos utiliza como identificador un campo llamado origin, que podemos interpretar como el dominio web del que se sirve el contenido y las aplicaciones. ",[201,259,260],{},"Cada origin tiene decenas de columnas en total. Pero al fin de al cabo, un tamaño fijo de datos. Esto significa que el volumen de datos crece, dados los parámetros",[221,262,263,266],{},[224,264,265],{},"N: número de origins a analizar",[224,267,268],{},"T: cantidad de unidades temporales a analizar,",[201,270,271],{},"... con complejidad O(NT). Para mi lista inicial de dominios peruanos registré 20mil dominios y mi objetivo es mantener una ventana de 24 semanas en el reporte. Dudo que en el futuro supere los 100mil dominios, así que tenemos un volumen modesto de datos que se puede procesar en un solo nodo, o mi computadora.",[245,273,275],{"id":274},"requisitos-y-restricciones","Requisitos y restricciones",[201,277,278],{},"Entre otros requisitos más específicos,",[221,280,281,284,287],{},[224,282,283],{},"Quiero almacenar los datos históricos y enrichment en un formato de bajo costo de almacenamiento pero con alta garantía de integridad de datos.",[224,285,286],{},"Mi página de reportes debe tener alta disponibilidad y presentar una experiencia de usuario fluida.",[224,288,289],{},"Quiero mantener costos de mantenimiento mínimos.",[201,291,292],{},"AWS S3 + Athena, GCP BigQuery Iceberg Catalog... hay muchas soluciones en el mercado. Esta vez decidí usar Cloudfare R2 Data Catalog, con una generosa cuota de 10GB de almacenamiento gratis y alto número de lecturas y escrituras. ",[201,294,295],{},"En cuanto a la página, Astro es mi opción preferida en estos casos. Y la CDN será CloudFare para mantener sencillez de administración.",[240,297,299],{"id":298},"transformación-de-datos","Transformación De Datos",[201,301,302],{},"Las etapas de extracción, filtro y enrichment son sencillas. ",[201,304,305],{},"Sin embargo, http archive no entrega categorías tecnológicas normalizadas. Como usa el motor de firmas de wappalyzer, simplemente entrega categorías de lo que sea que detecte. Puedes tener React.js y Next.js a la vez, incluso cuando sabemos que Next.js es un meta-framework de React y no existe sin este.",[245,307,309],{"id":308},"etapa-1-remapeo-a-macrocategorías","Etapa 1: Remapeo a Macrocategorías",[201,311,312,316],{},[204,313],{"alt":314,"src":315},"Diagrama del remapeo de categorías crudas a macrocategorías normalizadas","\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals-remapping.svg",[317,318,319],"em",{},"Remapeo de categorías crudas a macrocategorías normalizadas.",[201,321,322],{},"Origin_Technologies de R2 con una lista de categorías por tecnología. Después de agruparlas tenemos menos complejidad con la que trabajar. Pero es en esta etapa en la que hacemos el trabajo sucio.",[245,324,326],{"id":325},"etapa-2-limpiando-empates","Etapa 2: Limpiando empates.",[201,328,329,333],{},[204,330],{"alt":331,"src":332},"Diagrama del proceso LinearUntie para colapsar tecnologías atadas a una misma macrocategoría","\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals-linear-untie.svg",[317,334,335],{},"LinearUntie: colapsando tecnologías atadas a una misma macrocategoría.",[201,337,338],{},"Un origen puede tener varias tecnologías para la misma categoría. Esto es una consecuencia de lo que te conté antes. Puedes tener Next.js y Next App Router clasificados dentro de la misma categoría de Web Frameworks.",[201,340,341],{},"Para colapsar estos empates uso un ordenamiento lineal de las tecnologías de acuerdo a categoría. Si encuentro Nest.js y Express a la vez, Nest.js es la opción que agrupa ambos conceptos.",[201,343,344],{},"Una mejora directa a este modelo es realizar ordenamientos no solo por categoría, sino por categoría + framework. Pero esto requiere una tarea de relacionamiento costosa y de todas maneras hay excepciones que parten de la naturaleza con la que http archive genera los datos. ",[201,346,347],{},"Las excepciones menores o tecnologías mal categorizadas las voy agregando manualmente a una estructura en disco. Es un trabajo inevitable",[240,349,351],{"id":350},"ranking","Ranking",[201,353,354],{},"Una vez que ya tienes los conjuntos de datos normalizados el ranking se vuelve una tarea de estadística, y la página de reportes un proceso de diseño y UI.",[240,356,358],{"id":357},"the-ux-report","The UX Report",[201,360,361],{},"Si te interesa validar los resultados que ves en la web o alguna publicación, estos son los pasos.",[245,363,365,366,370,371,374],{"id":364},"cómo-reproducir-tu-severity-y-tu-score-con-la-api-pública-de-crux","Cómo reproducir tu ",[367,368,369],"strong",{},"severity"," y tu ",[367,372,373],{},"score"," con la API pública de CrUX",[201,376,377,378,383],{},"Lo que se muestra en la sección Core Web Vitals sale directo de la ",[233,379,382],{"href":380,"rel":381},"https:\u002F\u002Fdeveloper.chrome.com\u002Fdocs\u002Fcrux\u002Fapi",[237],"Chrome UX Report API"," de Google y que se usan en su ranking de SEO.",[385,386,388],"h4",{"id":387},"_1-pide-un-histograma-a-través-de-la-crux-api","1. Pide un histograma a través de la CrUX API",[390,391,396],"pre",{"className":392,"code":393,"language":394,"meta":395,"style":395},"language-bash shiki shiki-themes github-light github-dark","curl --request POST \\\n  'https:\u002F\u002Fchromeuxreport.googleapis.com\u002Fv1\u002Frecords:queryRecord?key=TU_API_KEY' \\\n  --header 'Accept: application\u002Fjson' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --data '{\"origin\":\"https:\u002F\u002Ftu-dominio.pe\"}'\n","bash","",[397,398,399,419,427,438,448],"code",{"__ignoreMap":395},[400,401,404,408,412,416],"span",{"class":402,"line":403},"line",1,[400,405,407],{"class":406},"sScJk","curl",[400,409,411],{"class":410},"sj4cs"," --request",[400,413,415],{"class":414},"sZZnC"," POST",[400,417,418],{"class":410}," \\\n",[400,420,422,425],{"class":402,"line":421},2,[400,423,424],{"class":414},"  'https:\u002F\u002Fchromeuxreport.googleapis.com\u002Fv1\u002Frecords:queryRecord?key=TU_API_KEY'",[400,426,418],{"class":410},[400,428,430,433,436],{"class":402,"line":429},3,[400,431,432],{"class":410},"  --header",[400,434,435],{"class":414}," 'Accept: application\u002Fjson'",[400,437,418],{"class":410},[400,439,441,443,446],{"class":402,"line":440},4,[400,442,432],{"class":410},[400,444,445],{"class":414}," 'Content-Type: application\u002Fjson'",[400,447,418],{"class":410},[400,449,451,454],{"class":402,"line":450},5,[400,452,453],{"class":410},"  --data",[400,455,456],{"class":414}," '{\"origin\":\"https:\u002F\u002Ftu-dominio.pe\"}'\n",[201,458,459,460,463,464,467],{},"La respuesta trae, por cada métrica, un ",[367,461,462],{},"histogram"," de 3 bins: bueno \u002F necesita mejora \u002F malo — cada uno con una ",[367,465,466],{},"density"," (fracción real de visitas de usuarios reales en ese rango, no un promedio sintético):",[390,469,473],{"className":470,"code":471,"language":472,"meta":395,"style":395},"language-json shiki shiki-themes github-light github-dark","\"largest_contentful_paint\": {\n  \"histogram\": [\n    { \"start\": 0,    \"end\": 2500, \"density\": 0.82 },\n    { \"start\": 2500, \"end\": 4000, \"density\": 0.11 },\n    { \"start\": 4000,               \"density\": 0.07 }\n  ],\n  \"percentiles\": { \"p75\": 2380 }\n}\n","json",[397,474,475,480,485,490,495,500,506,512],{"__ignoreMap":395},[400,476,477],{"class":402,"line":403},[400,478,479],{},"\"largest_contentful_paint\": {\n",[400,481,482],{"class":402,"line":421},[400,483,484],{},"  \"histogram\": [\n",[400,486,487],{"class":402,"line":429},[400,488,489],{},"    { \"start\": 0,    \"end\": 2500, \"density\": 0.82 },\n",[400,491,492],{"class":402,"line":440},[400,493,494],{},"    { \"start\": 2500, \"end\": 4000, \"density\": 0.11 },\n",[400,496,497],{"class":402,"line":450},[400,498,499],{},"    { \"start\": 4000,               \"density\": 0.07 }\n",[400,501,503],{"class":402,"line":502},6,[400,504,505],{},"  ],\n",[400,507,509],{"class":402,"line":508},7,[400,510,511],{},"  \"percentiles\": { \"p75\": 2380 }\n",[400,513,515],{"class":402,"line":514},8,[400,516,517],{},"}\n",[201,519,520,521,524,525,528,529,532],{},"Las tres métricas que importan son ",[367,522,523],{},"largest_contentful_paint"," (LCP), ",[367,526,527],{},"cumulative_layout_shift"," (CLS) e ",[367,530,531],{},"interaction_to_next_paint"," (INP). Los core web vitals oficiales de Google.",[385,534,536],{"id":535},"_2-calcula-el-severity-de-cada-métrica","2. Calcula el severity de cada métrica",[201,538,539],{},"Por cada métrica, el severity es un promedio ponderado por la densidad real de cada banda:",[390,541,546],{"className":542,"code":544,"language":545},[543],"language-text","severity_métrica = poor × 1.0 + needs_improvement × 0.5 + good × 0.0\n","text",[397,547,544],{"__ignoreMap":395},[201,549,550],{},"Con el ejemplo de arriba: 0.07 × 1.0 + 0.11 × 0.5 + 0.82 × 0.0 = 0.125.",[201,552,553],{},"¿Por qué ponderado y no \"banda dominante\"? Porque un origen con 51% good \u002F 49% needs-improvement y otro con 99% good \u002F 1% needs-improvement son historias reales muy distintas",[385,555,557],{"id":556},"_3-promedia-las-tres-métricas","3. Promedia las tres métricas",[390,559,563],{"className":560,"code":561,"language":562,"meta":395,"style":395},"language-python shiki shiki-themes github-light github-dark","def metric_severity(good: float, ni: float, poor: float) -> float:\n    return poor * 1.0 + ni * 0.5 + good * 0.0\n\nseverity = (\n    metric_severity(*lcp_densities)\n    + metric_severity(*cls_densities)\n    + metric_severity(*inp_densities)\n) \u002F 3\n","python",[397,564,565,599,634,640,651,661,674,685],{"__ignoreMap":395},[400,566,567,571,574,578,581,584,586,589,591,594,596],{"class":402,"line":403},[400,568,570],{"class":569},"szBVR","def",[400,572,573],{"class":406}," metric_severity",[400,575,577],{"class":576},"sVt8B","(good: ",[400,579,580],{"class":410},"float",[400,582,583],{"class":576},", ni: ",[400,585,580],{"class":410},[400,587,588],{"class":576},", poor: ",[400,590,580],{"class":410},[400,592,593],{"class":576},") -> ",[400,595,580],{"class":410},[400,597,598],{"class":576},":\n",[400,600,601,604,607,610,613,616,619,621,624,626,629,631],{"class":402,"line":421},[400,602,603],{"class":569},"    return",[400,605,606],{"class":576}," poor ",[400,608,609],{"class":569},"*",[400,611,612],{"class":410}," 1.0",[400,614,615],{"class":569}," +",[400,617,618],{"class":576}," ni ",[400,620,609],{"class":569},[400,622,623],{"class":410}," 0.5",[400,625,615],{"class":569},[400,627,628],{"class":576}," good ",[400,630,609],{"class":569},[400,632,633],{"class":410}," 0.0\n",[400,635,636],{"class":402,"line":429},[400,637,639],{"emptyLinePlaceholder":638},true,"\n",[400,641,642,645,648],{"class":402,"line":440},[400,643,644],{"class":576},"severity ",[400,646,647],{"class":569},"=",[400,649,650],{"class":576}," (\n",[400,652,653,656,658],{"class":402,"line":450},[400,654,655],{"class":576},"    metric_severity(",[400,657,609],{"class":569},[400,659,660],{"class":576},"lcp_densities)\n",[400,662,663,666,669,671],{"class":402,"line":502},[400,664,665],{"class":569},"    +",[400,667,668],{"class":576}," metric_severity(",[400,670,609],{"class":569},[400,672,673],{"class":576},"cls_densities)\n",[400,675,676,678,680,682],{"class":402,"line":508},[400,677,665],{"class":569},[400,679,668],{"class":576},[400,681,609],{"class":569},[400,683,684],{"class":576},"inp_densities)\n",[400,686,687,690,693],{"class":402,"line":514},[400,688,689],{"class":576},") ",[400,691,692],{"class":569},"\u002F",[400,694,695],{"class":410}," 3\n",[201,697,698,700],{},[367,699,369],{}," queda entre 0 (perfecto) y 1 (el peor caso posible). Si a tu origen le falta alguna de las tres métricas en esta ventana (CrUX exige un mínimo de tráfico por métrica para publicarla) lo que hago es completar el dato con el promedio del cohorte de esa ventana de datos. En ese caso sí tendrías problemas para reproducir tu score completo, pero puedes usar un valor placeholder de 50% para llegar a un aproximado.",[385,702,704],{"id":703},"_4-tu-score","4. Tu score",[390,706,708],{"className":560,"code":707,"language":562,"meta":395,"style":395},"score = round((1 - severity) * 100)\n",[397,709,710],{"__ignoreMap":395},[400,711,712,715,717,720,723,726,729,732,734,737],{"class":402,"line":403},[400,713,714],{"class":576},"score ",[400,716,647],{"class":569},[400,718,719],{"class":410}," round",[400,721,722],{"class":576},"((",[400,724,725],{"class":410},"1",[400,727,728],{"class":569}," -",[400,730,731],{"class":576}," severity) ",[400,733,609],{"class":569},[400,735,736],{"class":410}," 100",[400,738,739],{"class":576},")\n",[201,741,742,743,746,747,750],{},"Con ",[367,744,745],{},"severity = 0.125",", el score es ",[367,748,749],{},"87\u002F100",". Este número es 100% reproducible por cualquiera con solo la API pública de Google.",[201,752,753],{},"Espero que te haya gustado el artículo. Recuerda que cada mes actualizo el reporte de páginas. Te veo en mis métricas de analytics pronto!",[240,755,757],{"id":756},"colaboración","Colaboración",[201,759,760],{},"Tengo planeado liberar de manera open source el proyecto cuando entre en una etapa estable. Si quieres apoyar con alguna lista de URLs que consideras necesarias o una métrica que te gustaría tener escríbeme a mis redes con gusto.",[762,763,764],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":395,"searchDepth":421,"depth":421,"links":766},[767,771,775,776,780],{"id":242,"depth":421,"text":243,"children":768},[769,770],{"id":247,"depth":429,"text":248},{"id":274,"depth":429,"text":275},{"id":298,"depth":421,"text":299,"children":772},[773,774],{"id":308,"depth":429,"text":309},{"id":325,"depth":429,"text":326},{"id":350,"depth":421,"text":351},{"id":357,"depth":421,"text":358,"children":777},[778],{"id":364,"depth":429,"text":779},"Cómo reproducir tu severity y tu score con la API pública de CrUX",{"id":756,"depth":421,"text":757},"\u002Farticles\u002F2026\u002Fjuly\u002Fspying-on-your-rivals-cover.svg","2026-07-20T10:00:00.000Z","Rastrea a tu competencia con datos abiertos es una tarea... no tan difícil.","md","article",{"head":787},{"meta":788},[789],{"name":790,"content":791},"keywords","crux, http archive, bigquery, análisis competitivo, tecnologías web, wappalyzer, cloudflare r2, data lake, seo, analítica web",{"title":793,"description":794},"Rastreando a Los Usuarios de Tu Competencia","Rastrear a tu competencia con datos públicos es sencillo.","DkNrom9ryCwwNayT6tT2LTiH9ZD-eFic0vvGfg1IkP0",1785323411284]