Al usar el plugin de traducción inmersiva LLM para traducir algunos sitios web, noté lag del ratón: algunas sugerencias de LLM

Además, el lag solo se puede reproducir en algunos sitios web. Dejé que el LLM leyera el código del plugin; más tarde pediré a un experto que vea si hay ideas para optimizar.

Desde el nivel de arquitectura e implementación del desarrollo del plugin, para los cuellos de botella de rendimiento causados por la traducción con LLM, se puede optimizar en profundidad desde los siguientes ejes principales:

  1. Introducir una arquitectura de procesamiento asíncrono (Web Workers)
    Actualmente, una gran cantidad de coincidencias con expresiones regulares, análisis de HTML y comparación de textos traducidos del plugin quizá se ejecuten en el Content Script (hilo principal).
  • Plan de optimización: migrar a un Web Worker la lógica que no implique operaciones directas sobre el DOM (como el análisis del protocolo de streaming del LLM, el preprocesamiento de texto y los algoritmos de comparación multilingüe).
  • Efecto: liberar el hilo principal y garantizar que el navegador, mientras procesa los datos de traducción, pueda seguir respondiendo al desplazamiento y a los clics del usuario a 60fps.
  1. Implementar “procesamiento por lotes de renderizado” y “segmentación temporal” (Scheduling)
    En la salida en streaming (Streaming), lo peor es actualizar el DOM por cada carácter recibido.
  • Plan de optimización:
    • Actualización con búfer (Buffering): establecer un búfer de 100ms-200ms; combinar varios fragmentos devueltos por el LLM y luego iniciar una única actualización del DOM mediante requestAnimationFrame.
    • Segmentación temporal (Time Slicing): si hay que insertar de golpe una gran cantidad de nodos de traducción, usar una idea similar a React Fiber, descomponer la tarea en múltiples tareas pequeñas e insertar una a una cuando el navegador esté libre (requestIdleCallback).
  • Efecto: convertir los reflow (Reflow) originalmente intensivos en actualizaciones rítmicas, reduciendo en gran medida la carga instantánea de CPU.
  1. “Renderizado perezoso” basado en el viewport (Intersection Observer)
    Si la página es muy larga, la traducción completa hará que miles de nodos del DOM se actualicen simultáneamente en segundo plano, aunque esos nodos no estén en pantalla.
  • Plan de optimización: utilizar la API IntersectionObserver.
    • Solo cuando el nodo del texto original entre en el viewport (o esté a punto de entrar) se dispara la solicitud de traducción y se monta el DOM de traducción.
    • Para los nodos de traducción que queden muy lejos del viewport, se puede considerar destruirlos u ocultarlos temporalmente para reducir la presión del cálculo de layout del navegador.
  • Efecto: reducir el volumen de cómputo de “escala de toda la página” a “escala de pantalla”.
  1. Optimizar la estrategia de montaje del DOM (Containment)
    Al insertar nodos de traducción, si se rompe el layout original, se provocará el reflow de toda la página.
  • Plan de optimización:
    • CSS Containment: añadir contain: layout; o contain:
      content; al contenedor traducido. Esto le indica al navegador que los cambios internos de este nodo no afectarán al layout externo.
    • Placeholder fijo: antes de iniciar la traducción, estimar una altura de placeholder según la longitud del texto original, para evitar que el streaming del texto traducido cause “oscilaciones” repetidas en la página.
  • Efecto: limitar el alcance del reflow y evitar que “se mueva todo por tirar de un solo hilo”.
  1. Reducir los disparos excesivos de MutationObserver
    Como el propio plugin modifica el DOM, esto vuelve a disparar su propio listener de MutationObserver.
  • Plan de optimización:
    • Al insertar nodos de traducción, usar un flag global (Flag) para bloquear temporalmente la escucha, o bien filtrar en el listener los nodos generados por el propio plugin mediante node.isTrusted
      o atributos específicos.
    • Aumentar dinámicamente el umbral de mutationChangeDelay: cuando se detecte que el usuario está desplazándose a alta velocidad, incrementar automáticamente el retraso o pausar el escaneo.
  1. “Actualizaciones incrementales” en la salida en streaming en lugar de “reemplazos completos”
  • Plan de optimización: si el nodo de traducción es un contenedor, en las actualizaciones en streaming se deben añadir solo nodos de texto, en lugar de hacer cada vez innerHTML = …
    y reconstruir la estructura interna.
  • Efecto: reducir la presión del recolector de basura (GC) y el coste de análisis del árbol del DOM.

Resumen
La ruta de optimización más efectiva es: Web Worker para procesar datos →
requestAnimationFrame para renderizado con búfer → IntersectionObserver
para limitar el alcance → CSS contain para aislar el layout. De este modo se puede desacoplar perfectamente la “carga pesada” del LLM de la “fluidez” del navegador.


Al activar la traducción LLM, la CPU salta instantáneamente de 5 a una carga de 50.