Optimización de Rendimiento: Guía Completa

Introducción a la Optimización de Rendimiento

El rendimiento de una aplicación web se puede dividir en dos áreas principales:

  1. Mejorar la velocidad de carga
  2. Mejorar la velocidad de renderizado

A continuación, exploraremos técnicas para optimizar cada una de estas áreas.

Optimización de Carga

Para acelerar la carga de páginas, debemos enfocarnos en el tamaño de los recursos, el número de solicitudes y la red.

  1. Reducción del tamaño de recursos
  • Compresión de código y activos
  1. Reducción del número de solicitudes
  • Fusión de recursos
  • Combinación de múltiples archivos JavaScript
  • Combinación de múltiples archivos CSS
  • Consolidación de pequeños iconos en una única imagen (spritesheet)
  • Renderizado en el Servidor (SSR): Carga y renderizado simultáneo de página y datos
  • La arquitectura frontend-back end tradicional carga primero la página, luego los datos y finalmente renderiza. Tecnologías como JSP y PHP implementaban SSR. Frameworks modernos como Vue y React también ofrecen SSR.
  • Utilización de caché
  • Adición de hashes a recursos estáticos para activar el mecanismo de caché HTTP y recibir respuestas 304 cuando el recurso no cambia
  1. Uso de redes más rápidas
  • Redes de Distribución de Contenidos (CDN)
  • Utilización de CDN para bibliotecas y recursos externos

Optimización de Renderizado

  • Colocar CSS en el y JavaScript al final del
  • Ejecutar JavaScript lo antes posible usando el evento DOMContentLoaded
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // El DOM ha sido completamente cargado
        // Las imágenes y otros recursos pueden no estar listos aún
        inicializarAplicacion();
    });
</script>

  • Carga diferida de imágenes
  • Implementar carga diferida para imágenes que apaercen en pantalla
![Imagen con carga diferida](placeholder.jpg)

<script>
    document.addEventListener('DOMContentLoaded', function() {
        const imagenes = document.querySelectorAll('.lazy-image');
        
        const cargarImagenVisible = () => {
            imagenes.forEach(img => {
                const rect = img.getBoundingClientRect();
                if (rect.top < window.innerHeight && rect.bottom > 0) {
                    img.src = img.dataset.src;
                    img.classList.remove('lazy-image');
                }
            });
        };
        
        cargarImagenVisible();
        window.addEventListener('scroll', cargarImagenVisible);
    });
</script>

  • Caché de consultas DOM
// Sin caché de consultas DOM
const items = document.querySelectorAll('.item');
for (let i = 0; i < items.length; i++) {
    // Cada iteración requiere una consulta DOM
    items[i].classList.add('active');
}

// Con caché de consultas DOM
const items = document.querySelectorAll('.item');
const itemCount = items.length;
for (let i = 0; i < itemCount; i++) {
    // Solo se realiza una consulta inicial
    items[i].classList.add('active');
}

  • Operaciones por lotes en DOM
const contenedor = document.getElementById('lista');

// Crear un fragmento de documento
const fragmento = document.createDocumentFragment();

// Generar elementos y añadirlos al fragmento
for (let i = 0; i < 20; i++) {
    const elemento = document.createElement('div');
    elemento.textContent = `Elemento ${i + 1}`;
    fragmento.appendChild(elemento);
}

// Insertar todos los elementos de una sola vez
contenedor.appendChild(fragmento);

  • Control de eventos con throttling y debouncing
  • Debouncing
  • Definición: Ejecutar la función después de que el evento no se haya disparado durante un período determinado
  • Enfoque en el resultado final
  • Aplicaciones:
  • Búsqueda en tiempo real: Evitar búsquedas mientras el usuario sigue escribiendo
  • Manejo de redimensionamiento de ventana: Ejceutar solo después de que el usuario termine de redimensionar
  • Prevención de envíos múltiples: Evitar que se envíe un formulario múltiples veces

Implementación:

function debounce(funcionRetraso, tiempoEspera = 300) {
    let temporizador = null;
    
    return function(...argumentos) {
        const contexto = this;
        
        // Limpiar el temporizador existente
        if (temporizador) {
            clearTimeout(temporizador);
        }
        
        // Establecer un nuevo temporizador
        temporizador = setTimeout(() => {
            funcionRetraso.apply(contexto, argumentos);
            temporizador = null;
        }, tiempoEspera);
    };
}

// Ejemplo de uso
const campoBusqueda = document.getElementById('campo-busqueda');

const realizarBusqueda = (evento) => {
    console.log('Realizando búsqueda:', campoBusqueda.value);
};

campoBusqueda.addEventListener('input', debounce(realizarBusqueda, 500));

  • Throttling
  • Definición: Limitar la ejecución de una función a una vez cada ciertos intervalos de tiempo
  • Enfoque en el proceso continuo
  • Aplicaciones:
  • Eventos de scroll: Limitar la frecuencia de actualizaciones durante el desplazamiento
  • Animaciones suaves: Garantizar un número constante de actualizaciones por segundo
  • Actualizaciones en tiempo real: Proporcionar retroalimentación sin sobrecargar el procesador

Implementación:

function throttle(funcionLimitada, intervaloTiempo) {
    let ultimaEjecucion = 0;
    
    return function(...argumentos) {
        const contexto = this;
        const ahora = Date.now();
        
        if (ahora - ultimaEjecucion >= intervaloTiempo) {
            funcionLimitada.apply(contexto, argumentos);
            ultimaEjecucion = ahora;
        }
    };
}

// Ejemplo de uso
const elemento = document.getElementById 'elemento-desplazable';

const manejarScroll = (evento) => {
    console.log('Posición actual:', window.scrollY);
};

window.addEventListener('scroll', throttle(manejarScroll, 200));

Etiquetas: optimización-de-rendimiento web-performance desarrollo-web frontend cdn

Publicado el 6-17 16:58