Experiencia de Tecnoblog con los comentarios de Discourse

¡Hola!

Estoy realmente emocionado por esta nueva función. Llevo tiempo esperando una solución como esta, y la respuesta inicial de nuestros lectores en Tecnoblog ha sido excelente: les encanta tener la comunidad integrada.

Sin embargo, tras algunas pruebas en condiciones reales, he detectado algunos obstáculos técnicos que debemos superar para que esto se sienta como un sistema de comentarios realmente nativo y, lo que es más importante, para que sea sostenible en sitios con mucho tráfico.

Esto es lo que he encontrado hasta ahora:

1. Rendimiento y carga del servidor

La carga de nuestro servidor aumentó significativamente después de integrar la aplicación completa. Según Cloudflare, el volumen de solicitudes se multiplicó por 10. Algunas ideas sobre cómo optimizar esto:

  • Carga diferida (Lazy Loading): Implementar la carga diferida para el JS ayuda mucho (ya estoy usando una solución alternativa para esto).
            <script type="text/javascript">
                DiscourseEmbed = {
                    discourseUrl: '<?php echo esc_url($discourse_url); ?>',
                    
                    <?php if ($use_topic_id): ?>
                        // Modo ID: Tema guardado en la base de datos, inmune a cambios de URL
                        topicId: <?php echo intval($topic_id); ?>,
                    <?php else: ?>
                        // Modo URL: Fallback cuando falla la creación vía API
                        discourseEmbedUrl: '<?php echo esc_url($permalink); ?>',
                    <?php endif; ?>
                    fullApp: true,
                    embedHeight: '800px',
                };

                (function() {
                    var container = document.getElementById('discourse-comments');

                    // Verifica si el navegador soporta IntersectionObserver
                    if ('IntersectionObserver' in window) {
                        var observer = new IntersectionObserver(function(entries, observer) {
                            entries.forEach(function(entry) {
                                if (entry.isIntersecting) {
                                    // Cuando el div entra en la pantalla, carga el script
                                    loadDiscourse();
                                    observer.unobserve(entry.target);
                                }
                            });
                        }, { rootMargin: "1500px" }); // Carga 1500px antes de llegar al div

                        observer.observe(container);
                    } else {
                        // Fallback para navegadores antiguos
                        loadDiscourse();
                    }

                    function loadDiscourse() {
                        var d = document.createElement('script'); 
                        d.type = 'text/javascript'; 
                        d.async = true;
                        d.src = window.DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
                        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
                    }
                })();
            </script>

Aquí puedes ver cómo disminuye el número de solicitudes después de implementar la carga diferida (y algunas partes del sitio web aún estaban en caché, por lo que este no es el resultado final):

  • Reducción de la carga útil: ¿Podemos reducir los recursos que se cargan dentro de la integración? Por ejemplo: noté consultas para URLs de Chat y verificaciones de créditos de IA; ¿son necesarias para la vista integrada?

  • Frecuencia de solicitudes: Las solicitudes POST en tiempo real son un poco agresivas. Quizás podamos reducir la frecuencia de sondeo para la versión integrada.

  • Caché: Mejorar la gestión de la caché para los temas integrados y manejar los picos de tráfico.

2. Caos en las analíticas

Actualmente, la integración está ejecutando scripts de Google Analytics/GTM. Esto está duplicando nuestras visitas a la página (un registro para la entrada y otro para el iframe), lo que altera nuestros datos. Sería ideal que el sistema pudiera detectar que está dentro de un iframe y desactivar automáticamente cualquier script de seguimiento (incluidas las analíticas de Discourse).

3. El problema de la altura del iFrame

Este es probablemente el mayor obstáculo para la experiencia de usuario. Si una entrada no tiene comentarios, aparece un extraño espacio vacío. Si tiene un hilo largo, el iframe se corta después de los primeros 2 o 3 comentarios, obligando a un “desplazamiento dentro de otro desplazamiento”, lo cual es bastante malo, especialmente en móviles.

Para competir realmente con algo como Disqus, necesitamos que la altura sea dinámica (según el número de comentarios) y también tener un botón “Leer más” que expanda el hilo después de cierto número de respuestas.

4. Conflictos de plugins

Dado que la integración carga todos los plugins activos, estamos viendo algunos comportamientos extraños. Por ejemplo, “Google One Tap” aparece dentro de la entrada del blog. Cuando un usuario inicia sesión, el iframe se actualiza y lo lleva a la página de inicio de la comunidad en lugar del hilo de comentarios. Poder deshabilitar manualmente plugins específicos para la vista integrada sería un gran alivio.

5. Fricción en el inicio de sesión

El flujo actual es un poco un asesino de conversiones: el usuario hace clic en iniciar sesión → se abre una nueva pestaña → se realiza el inicio de sesión → el usuario queda en la página de inicio de la comunidad. De vuelta en la entrada del blog, el iframe sigue pareciendo que no ha iniciado sesión hasta que el usuario actualiza manualmente toda la página. Es un bucle confuso que hace que la gente se rinda y se vaya antes de comentar.

Desde que activamos la nueva integración, nuestros registros diarios se han más que duplicado, lo cual es genial. Sin embargo, nuestras métricas de engagement no han cambiado en absoluto. De hecho, nuestro DAU/MAU disminuyó: tenemos más usuarios conectados, pero no están interactuando. Métricas como “Usuarios activos diarios”, “Nuevos contribuyentes” y “Publicaciones” no han visto ningún aumento.

Esto demuestra que la gente quiere unirse a la conversación, pero se pierde en el bucle de inicio de sesión y abandona la entrada antes de poder comentar realmente.

6. Interfaz de usuario en móvil

En móvil, la ventana de respuesta ocupa toda la pantalla, por lo que pierdes todo el contexto de la conversación a la que estás respondiendo. Se siente un poco claustrofóbico; cualquier cosa que podamos hacer para mantenerla más compacta sería una gran victoria.


Realmente quiero que esto sea el sistema predeterminado para Tecnoblog (y también en otro sitio que poseemos). ¡Avísame si quieres profundizar en alguno de estos puntos!

14 Me gusta

Esto se corregirá en

11 Me gusta

¡Gracias por los comentarios detallados, @Thiago_Mobilon!

Me pondré con la lista y trataré de cubrir todo al final.

Acabo de hacer una comprobación aquí y parece que tienes una configuración incorrecta del CSS en tu sitio de Discourse. Tienes dos encabezados cache-control duplicados, y uno de ellos es no-cache.

curl -v https://tecnoblog.net/comunidade/stylesheets/common_cd45efa28175431b0b8ff143783178d55206920b.css?__ws=tecnoblog.net -s 2>&1 | grep cache-control
< cache-control: max-age=31556952, public, immutable
< cache-control: no-store, no-cache, must-revalidate, private
9 Me gusta

¿Estás usando la integración nativa de Google Analytics de Discourse?

8 Me gusta

Manejo de esto en

9 Me gusta

Manejado en

11 Me gusta

Creo que Cloudflare debe haber añadido ese encabezado porque omití la caché para el directorio /comunidade/. Si no lo elimino, aplicará sus reglas de caché al CSS y JS de Discourse, lo cual podría crear conflictos más adelante.

En cualquier caso, cuando mencioné el problema de la caché, lo hice con el objetivo principal de reducir la carga del servidor. Los archivos CSS son estáticos, ¿correcto? Si es así, el hecho de que no estén en caché, aunque no sea deseable, no afectaría directamente la carga del servidor.

5 Me gusta

Estoy utilizando la integración de Discourse con Google Tag Manager.

4 Me gusta

Afectan al rendimiento del usuario final, ya que se realizan 59 solicitudes para descargar 1,43 MB de CSS (comprimidos a 340 KB) en cada artículo.

Y también son servidos por el servidor Ruby, ya que esperamos que los sitios no invaliden la caché, lo que significa que, en condiciones normales, esta ruta se usa muy raramente.

Si no me equivoco, servirlos con la caché invalidada significa que incluso acceden a la base de datos.

4 Me gusta

Esta es una gran idea, estoy agregando soporte nativo para ello

11 Me gusta

Este es un problema más general relacionado con la redacción al vuelo, y se beneficiará de las mejoras de Creating/Editing a post on mobile: let's discuss the 2026 Discourse experience.

8 Me gusta

Tenemos un caché increíble para usuarios anónimos que acceden a páginas de temas, y también cubre este nuevo modo, así que deberías poder escalar bien para manejar picos siempre que haya suficientes trabajadores de Pitchfork y trabajadores de E/S de Redis.

5 Me gusta

El sondeo reduce automáticamente la frecuencia en pestañas en segundo plano o durante eventos de alta carga, y lo mismo debería aplicarse aquí.

5 Me gusta

Optó por etiquetar a aquellos en

8 Me gusta

Estoy teniendo dificultades para que la altura dinámica funcione correctamente. A pesar de actualizar Discourse y refrescar mi fragmento con las últimas configuraciones, el problema persiste.

        <h4 class="comments-main-title component-title">Comentarios</h4>
        <div id='discourse-comments'></div>

        <meta name='discourse-username' content='<?php echo esc_attr($discourse_author); ?>'>

        <script type="text/javascript">
            DiscourseEmbed = {
                discourseUrl: '<?php echo esc_url($discourse_url); ?>',
                
                <?php if ($use_topic_id): ?>
                    // Modo ID: Tema guardado en la base de datos, inmune a cambios de URL
                    topicId: <?php echo intval($topic_id); ?>,
                <?php else: ?>
                    // Modo URL: Fallback cuando la creación vía API falla
                    discourseEmbedUrl: '<?php echo esc_url($permalink); ?>',
                <?php endif; ?>
                fullApp: true,
                lazyLoad: true, // desactiva la carga diferida del iframe
                lazyLoadMargin: '1500', // píxeles antes del viewport para comenzar la carga
                dynamicHeight: true,
                embedMinHeight: '400',
                embedMaxHeight: '3000',
					  embedHeight: '800px',
                // className: 'NOMBRE_CLASE',
            };

            (function() {
            var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
            d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
            })();
        </script>
4 Me gusta

¿Podríamos usar <iframe loading="lazy"> aquí? De esa manera, no necesitaríamos JS personalizado ni observadores de intersección.

4 Me gusta

¡Ah, ya tiene amplio soporte en los navegadores? ¡TIL! Lo cambiaré lo antes posible.

8 Me gusta

Gracias por las pruebas, hemos encontrado el problema

5 Me gusta

¡Excelente! La altura dinámica ahora funciona como se esperaba. Sin embargo, esto ha introducido un pequeño problema: cuando hago clic para responder, el campo de entrada para la respuesta intenta ajustarse a la altura del iframe. En este caso, se ha vuelto erróneamente de 7385px de altura.

El post contenía 31 comentarios, y el iframe incrustado tenía 9757px de alto (había configurado embedMaxHeight en 15000px).

Actualización: He notado que el formulario de comentarios expande la altura del iframe a su máximo, por lo que cuando hago clic en «descartar», el diseño termina con un gran espacio en blanco debajo de los comentarios.

Screenshot 2026-04-16 at 16.03.37

5 Me gusta

Creo que necesitarás un max-height con un valor más razonable allí, como 1000 a 1500px.

Así que esta función cubrirá tu problema inicial de

y escala hasta cierto punto, pero dado el comportamiento de desplazamiento infinito nativo de Discourse, no quieres que la altura aumente tanto.

Esta función no eliminará el “desplazamiento dentro de desplazamiento” en un futuro cercano.

En cuanto al compositor móvil, estoy investigando qué podemos hacer aquí.

6 Me gusta