Cómo cambiar la URL sin recargar la página: optimización y rendimiento

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: Por qué cambiar la URL sin recargar es un superpoder

\n\n

Imagine: abre un servicio web moderno — digamos, un cliente de correo o un editor de documentos en línea. Cambia entre carpetas, abre correos, modifica configuraciones — y la página no se recarga. Mientras tanto, la barra de direcciones del navegador cambia, los botones «Atrás» y «Adelante» funcionan, y los marcadores guardan el estado deseado. ¿Cómo funciona esto? Magia de la modificación de URL sin recargar la página.

\n\n

Esto no es solo un «adorno» — es la base de las aplicaciones de una sola página (SPA) de alto rendimiento. Antiguamente, los desarrolladores usaban hashes (#), pero era feo e incómodo. Hoy tenemos la History API — una herramienta poderosa que permite cambiar la URL al instante, sin parpadeos, sin pérdida de estado, sin solicitudes HTTP innecesarias.

\n\n

En este artículo, analizaremos cómo funcionan pushState y replaceState, cómo afectan el rendimiento y cómo evitar errores comunes al optimizar. ¡Allá vamos!

\n\n

Fundamentos: History API y sus métodos

\n\n

La especificación HTML5 nos regaló la interfaz window.history. Los dos métodos principales para cambiar la URL sin recargar son pushState y replaceState.

\n\n

pushState — añade una nueva entrada al historial

\n\n

pushState crea una nueva entrada en el historial del navegador. El usuario puede presionar «Atrás» y volver a la URL anterior.

\n\n
// Sintaxis\nhistory.pushState(state, title, url);\n\n// Ejemplo\nhistory.pushState({ page: 1 }, 'Inicio', '/home');\n
\n\n

Parámetros:

\n
    \n
  • state — objeto de datos asociado con esta entrada. Puede almacenar cualquier dato serializable (por ejemplo, estado de un filtro, ID de un elemento).
  • \n
  • title — título de la página (la mayoría de los navegadores lo ignoran, pero es mejor pasar una cadena vacía o un texto significativo).
  • \n
  • url — la nueva URL. Debe ser relativa o absoluta, pero dentro del mismo origin (protocolo + dominio + puerto).
  • \n
\n\n

replaceState — reemplaza la entrada actual

\n\n

replaceState modifica la entrada actual en el historial sin crear una nueva. El usuario no podrá volver «atrás» a la URL anterior — será reemplazada.

\n\n
// Sintaxis\nhistory.replaceState(state, title, url);\n\n// Ejemplo — actualizar la URL al cambiar un filtro\nfunction applyFilter(filterName) {\n  history.replaceState({ filter: filterName }, '', `?filter=${filterName}`);\n  updateUI(filterName);\n}\n
\n\n

popstate — escuchar cambios en el historial

\n\n

Cuando el usuario presiona «Atrás» o «Adelante», el navegador genera el evento popstate. Importante: pushState y replaceState no disparan este evento — debe manejarse por separado.

\n\n
window.addEventListener('popstate', function(event) {\n  if (event.state) {\n    // Restaurar el estado según los datos de event.state\n    restorePageState(event.state);\n  } else {\n    // Si el state está vacío — quizás el usuario salió de los límites de nuestra aplicación\n    loadDefaultState();\n  }\n});\n
\n\n

Optimización del rendimiento: qué es importante saber

\n\n

La modificación de URL es rápida. Pero hay matices que pueden convertir un superpoder en una fuente de errores.

\n\n

1. No llame a pushState con demasiada frecuencia

\n\n

Cada llamada a pushState añade una entrada al historial. Si lo llama con cada movimiento del ratón o cada carácter en una búsqueda — el historial se inflará y el usuario tendrá que presionar «Atrás» 100 veces para salir del filtro. Use replaceState para estados intermedios y pushState para acciones lógicamente completas (por ejemplo, abrir una nueva página).

\n\n

2. Sincronice

Blogs

Book Recommendations