Backend y Frameworks

Tabla de Contenidos

Tabla de Contenidos

Tabla de Contenidos

Compatibilidad y Rendimiento

Asegurar que el código JavaScript se ejecute sin problemas en diferentes navegadores y optimizar el rendimiento son aspectos clave del desarrollo web. Esta sección aborda técnicas para manejar la compatibilidad entre navegadores, la optimización del rendimiento y las mejores prácticas para una ejecución eficiente de JavaScript.

Manejo de la Compatibilidad entre Navegadores

Diferentes navegadores interpretan JavaScript de manera ligeramente diferente. Los desarrolladores deben asegurarse de que su código funcione de manera consistente en navegadores modernos como Chrome, Firefox, Safari, Edge, e incluso en versiones más antiguas de Internet Explorer cuando sea necesario.

Detección de Características Usando if Declaraciones

Antes de usar una característica, verifique si el navegador la admite.

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition(position => {
    console.log("Latitude:", position.coords.latitude);
  });
} else {
  console.log("Geolocation is not supported in this browser.");
}

Usando try...catch para Recaídas

Para características que pueden generar errores en navegadores no compatibles:

try {
  let speech = new SpeechSynthesisUtterance("Hello");
  window.speechSynthesis.speak(speech);
} catch (error) {
  console.log("Speech API not supported.");
}

Usando Polyfills

Un polyfill es código JavaScript que proporciona funcionalidad moderna en navegadores más antiguos.

Ejemplo: Agregar soporte para fetch() para navegadores antiguos:

<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/3.6.2/fetch.min.js"></script>

Reduciendo el Tiempo de Ejecución de JavaScript

Minimizar JavaScript elimina caracteres innecesarios para reducir el tamaño del archivo.

Use Terser o UglifyJS para minimizar scripts:

Cargue scripts de manera asíncrona para evitar bloquear la carga de la página.

async: Carga en paralelo pero se ejecuta inmediatamente.

defer: Carga en paralelo y se ejecuta después de que la análisis de HTML esté completa.

<script src="script.js" async></script>
<script src="script.js" defer></script>

Reducir la Manipulación Innecesaria del DOM

Cambios frecuentes en el DOM pueden ralentizar el rendimiento.

Ineficiente:

for (let i = 0; i < 100; i++) {
  document.body.appendChild(document.createElement("p"));
}

Eficiente (usando DocumentFragment):

let fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  let p = document.createElement("p");
  fragment.appendChild(p);
}
document.body.appendChild(fragment);

Optimización de Bucles y Escuchadores de Eventos

Usar Bucles Eficientes

forEach() y map() son convenientes, pero los bucles for pueden ser más rápidos para conjuntos de datos grandes.

let arr = new Array(100000).fill(0);

console.time("forEach");
arr.forEach(num => num + 1);
console.timeEnd("forEach");

console.time("for-loop");
for (let i = 0; i < arr.length; i++) {
  arr[i] + 1;
}

console.timeEnd("for-loop");

Limitar y Debounce Eventos

Escuchadores de eventos costosos (por ejemplo, desplazamiento, cambio de tamaño) pueden degradar el rendimiento.

  • Debouncing asegura que la función se ejecute solo después de que el evento haya dejado de activarse.

  • Throttling asegura que la función se ejecute a intervalos fijos, incluso si el evento sigue activándose.

Ejemplo de Debounce

function debounce(func, delay) {
  let timer;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, arguments), delay);
  };
}
  
window.addEventListener("resize", debounce(() => {
  console.log("Resize event fired!");
}, 300));

Ejemplo de Throttle

function throttle(func, limit) {
  let lastCall = 0;
  return function () {
    let now = Date.now();
    if (now - lastCall >= limit) {
      lastCall = now;
      func.apply(this, arguments);
    }
  };
}
  
window.addEventListener("scroll", throttle(() => {
  console.log("Scroll event fired!");
}, 200));

Usar Trabajadores Web para Cálculos Pesados

Los Trabajadores Web permiten ejecutar JavaScript en segundo plano sin bloquear el hilo principal.

Creando un Trabajador Web

let worker = new Worker("worker.js");

worker.postMessage("Start");
  
worker.onmessage = event => {
  console.log("Worker Response:", event.data);
};

worker.js

self.onmessage = () => {
  let result = 0;
  for (let i = 0; i < 1e9; i++) {
    result += i;
  }
  postMessage(result);
};

Usar Estructuras de Datos Eficientes

Usar Mapas en Lugar de Objetos para Conjuntos de Datos Grandes

let obj = {};
let map = new Map();
  
map.set("key1", "value1");
console.log(map.get("key1"));

Usar Set para Valores Únicos

let uniqueNumbers = new Set([1, 2, 3, 3, 4]);
console.log(uniqueNumbers.size); // Outputs: 4

Conclusión

Optimizar JavaScript asegura un mejor rendimiento del navegador y compatibilidad. Esta sección cubrió técnicas para reducir el tiempo de ejecución, manejar fugas de memoria, mejorar el manejo de eventos y usar estructuras de datos eficientes. La próxima sección se enfocará en JavaScript en el Backend con Node.js, cubriendo el desarrollo del lado del servidor con JavaScript.