Introducción
Gran parte del objetivo de HTML5 es ofrecer compatibilidad con navegadores nativos para los componentes y las técnicas que logramos hasta ahora a través de las bibliotecas de JavaScript. Si están presentes, el uso de estas funciones puede ofrecer una experiencia mucho más rápida a los usuarios. En este instructivo, no resumiré la excelente investigación de rendimiento que viste en el sitio de Rendimiento excepcional de Yahoo ni en los documentos de velocidad de la página y el sitio Hagamos que la Web sea más rápida de Google. En cambio, me enfocaré en cómo usar HTML5 y CSS3 hoy en día puede hacer que tus apps web sean más responsivas.
Sugerencia 1: Usa el almacenamiento web en lugar de las cookies
Si bien las cookies se han usado para hacer un seguimiento de los datos de usuarios únicos durante años, tienen desventajas graves. El mayor defecto es que todos los datos de tus cookies se agregan a cada encabezado de solicitud HTTP. Esto puede tener un impacto medible en el tiempo de respuesta, especialmente durante las XHR. Por lo tanto, una práctica recomendada es reducir el tamaño de las cookies. En HTML5, podemos hacer mucho más: usar sessionStorage y localStorage en lugar de cookies.
Estos dos objetos de almacenamiento web se pueden usar para conservar los datos del usuario en el cliente durante la sesión o de forma indefinida. Tampoco se transfieren sus datos al servidor a través de cada solicitud HTTP. Tienen una API que te hará feliz deshacerte de las cookies. Estas son ambas APIs, que usan cookies como resguardo.
// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {
// easy object property API
localStorage.wishlist = '["Unicorn","Narwhal","Deathbear"]';
} else {
// without sessionStorage we'll have to use a far-future cookie
// with document.cookie's awkward API :(
var date = new Date();
date.setTime(date.getTime()+(365*24*60*60*1000));
var expires = date.toGMTString();
var cookiestr = 'wishlist=["Unicorn","Narwhal","Deathbear"];'+
' expires='+expires+'; path=/';
document.cookie = cookiestr;
}
Sugerencia 2: Usa transiciones de CSS en lugar de animaciones de JavaScript
Las transiciones de CSS te brindan una transición visual atractiva entre dos estados. La mayoría de las propiedades de estilo pueden realizar transiciones, como manipular la sombra de texto, la posición, el fondo o el color. Puedes usar transiciones a estados de selectores falsos, como :hover, o desde formularios HTML5, :invalid y :valid (ejemplo con estados de validación de formularios). Sin embargo, son mucho más potentes y se pueden activar cuando agregas cualquier clase a un elemento.
div.box {
left: 40px;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
div.box.totheleft { left: 0px; }
div.box.totheright { left: 80px; }
Si agregas el cambio de las clases de totheleft y totheright, puedes mover el cuadro. Compara esta cantidad de código con la de una biblioteca de animación de JavaScript. Claramente, la cantidad de bytes que se envían al navegador es mucho menor cuando se usa una animación basada en CSS. Además, con la aceleración a nivel de la GPU, estas transiciones visuales serán lo más fluidas posible.
Sugerencia 3: Usa bases de datos del cliente en lugar de ida y vuelta del servidor
Base de datos de SQL web y IndexedDB presentan bases de datos al cliente. En lugar del patrón común de publicar datos en el servidor a través de XMLHttpRequest o el envío de formularios, puedes aprovechar estas bases de datos del cliente. Reducir las solicitudes HTTP es un objetivo principal de todos los ingenieros de rendimiento, por lo que usarlas como un almacén de datos puede ahorrar muchos viajes a través de XHR o publicaciones de formularios al servidor. localStorage y sessionStorage se pueden usar en algunos casos, como capturar el progreso del envío de formularios, y se ha demostrado que son notablemente más rápidas que las APIs de bases de datos del cliente.
Por ejemplo, si tienes un componente de cuadrícula de datos o una carpeta Recibidos con cientos de mensajes, almacenar los datos de forma local en una base de datos te ahorrará viajes de ida y vuelta de HTTP cuando el usuario desee buscar, filtrar o ordenar. Se podría filtrar una lista de amigos o un autocompletado de entrada de texto en cada pulsación de tecla, lo que brindaría una experiencia del usuario mucho más responsiva.
Sugerencia 4: Las mejoras de JavaScript ofrecen ventajas de rendimiento considerables
Se agregaron muchos métodos adicionales al prototipo de Array en JavaScript 1.6. Ahora están disponibles en la mayoría de los navegadores, excepto en IE. Por ejemplo:
// Give me a new array of all values multiplied by 10.
[5, 6, 7, 8, 900].map(function(value) { return value * 10; });
// [50, 60, 70, 80, 9000]
// Create links to specs and drop them into #links.
['html5', 'css3', 'webgl'].forEach(function(value) {
var linksList = document.querySelector('#links');
var newLink = value.link('http://google.com/search?btnI=1&q=' + value + ' spec');
linksList.innerHTML += newLink;
});
// Return a new array of all mathematical constants under 2.
[3.14, 2.718, 1.618].filter(function(number) {
return number < 2;
});
// [1.618]
// You can also use these extras on other collections like nodeLists.
[].forEach.call(document.querySelectorAll('section[data-bucket]'), function(elem, i) {
localStorage['bucket' + i] = elem.getAttribute('data-bucket');
});
En la mayoría de los casos, el uso de estos métodos nativos genera velocidades significativamente más rápidas que el bucle for típico, como for (var i = 0, len = arr.length; i < len; i++).
El análisis JSON nativo (a través de JSON.parse()) reemplaza el archivo json2.js que solíamos incluir desde hace tiempo. El JSON nativo es mucho más rápido y seguro que usar una secuencia de comandos externa, y ya está disponible en IE8, Opera 10.50, Firefox 3.5, Safari 4.0.3 y Chrome.
String.trim nativo es otro buen ejemplo de que no solo es más rápido que los equivalentes de JS largos, sino que también es potencialmente más correcto. Ninguna de estas incorporaciones de JavaScript es técnicamente HTML5, pero se encuentran dentro del paraguas de las tecnologías que están disponibles recientemente.
Sugerencia 5: Usa el manifiesto de caché para los sitios activos, no solo para las apps sin conexión
Hace dos años, WordPress usó Google Gears para agregar una función llamada WordPress Turbo. En esencia, almacenaba en caché muchos de los recursos que se usaban en el panel de administración de forma local, lo que aceleraba el acceso a los archivos. Podemos replicar ese comportamiento con applicationCache de HTML5 y cache.manifest.
La caché de la app tiene una ligera ventaja sobre la configuración de encabezados Expires. Como creas un archivo declarativo que indica los recursos estáticos que se pueden almacenar en caché, los navegadores pueden optimizarlos en gran medida, incluso almacenarlos previamente antes de que los uses.
Considera la estructura básica de tu sitio como una plantilla. Tienes datos que pueden cambiar, pero el código HTML que los rodea suele ser bastante coherente. Con la caché de la app, puedes tratar tu HTML como una serie de plantillas puras, almacenar en caché el marcado a través de cache.manifest y, luego, entregar JSON a través de la red para actualizar el contenido. Este modelo es muy similar al que hace una app de noticias nativa para iPhone o Android.
Sugerencia 6: Habilita la aceleración de hardware para mejorar la experiencia visual
En los navegadores líderes, muchas operaciones visuales pueden aprovechar la aceleración a nivel de la GPU, lo que puede hacer que las operaciones visuales altamente dinámicas sean mucho más fluidas. Se anunció la aceleración de hardware para Firefox Minefield y IE9, y Safari agregó aceleración a nivel de hardware en la versión 5. (Llegó a Mobile Safari mucho antes). Chromium acaba de agregar transformaciones 3D y aceleración de hardware para Windows, y las otras dos plataformas estarán disponibles próximamente.
La aceleración de la GPU se activa solo en un conjunto bastante restringido de condiciones, pero las transformaciones 3D y la opacidad animada son las formas más comunes de activar el interruptor. Una forma algo hackeada, pero no invasiva, de activarlo es la siguiente:
.hwaccel { -webkit-transform: translateZ(0); }
Sin embargo, no hay garantías. :) Con la aceleración de hardware admitida y habilitada, la traducción animada, la rotación, el escalamiento y la opacidad serán mucho más fluidos con la composición de GPU. Tendrán el beneficio de administrarse directamente en la GPU y no requieren volver a dibujar el contenido de la capa. Sin embargo, cualquier propiedad que afecte el diseño de la página seguirá siendo relativamente lenta.
Sugerencia 7: Para operaciones con gran uso de CPU, los trabajadores web ofrecen lo siguiente:
Los trabajadores web tienen dos beneficios significativos: 1) son rápidos. 2) Mientras se ejecutan las tareas, el navegador sigue siendo responsivo. Consulta la presentación de diapositivas de HTML5 para ver a los trabajadores en acción. Estas son algunas situaciones posibles en las que podrías usar Web Workers:
- Formato de texto de un documento largo
- Resaltado de sintaxis
- Procesamiento de imágenes
- Síntesis de imágenes
- Procesa grandes arreglos
Sugerencia 8: Atributos y tipos de entrada de formularios HTML5
HTML5 presenta un nuevo conjunto de tipos de entrada, que actualiza nuestro conjunto de text, password y file para incluir search, tel, url, email, datetime, date, month, week, time, datetime-local, number, range y color. La compatibilidad de los navegadores con estos elementos varía, y Opera es el que implementa la mayoría en este momento. Con la detección de funciones, puedes determinar si el navegador tiene compatibilidad nativa (y ofrecerá una IU como un selector de fecha o de color) y, de lo contrario, puedes seguir usando los widgets de JS para realizar estas tareas comunes.
Además de los tipos, se agregaron algunas funciones útiles a nuestros campos de entrada normales. La entrada placeholder ofrece un texto predeterminado que se borra cuando haces clic en él y autofocus enfoca el signo de intercalación en la carga de la página para que puedas interactuar de inmediato con ese campo. La validación de entradas es otra característica que se está incorporando a HTML5. Si agregas el atributo required, el navegador no permitirá que se envíe el formulario hasta que se complete ese campo. Además, el atributo pattern te permite especificar una expresión regular personalizada para que se pruebe la entrada, con valores no válidos que bloquean el envío del formulario. Esta sintaxis declarativa es una gran actualización no solo en la legibilidad de la fuente, sino también en una reducción significativa de JavaScript necesaria. Una vez más, puedes usar la detección de funciones para publicar una solución de resguardo si no hay compatibilidad nativa para estas.
El uso de los widgets nativos aquí significa que no necesitas enviar el JavaScript y el CSS pesados necesarios para mostrar estos widgets, lo que acelera la carga de la página y, probablemente, mejora la capacidad de respuesta de los widgets. Para probar algunas de estas mejoras de entrada, consulta la presentación de diapositivas de HTML5.
Sugerencia 9: Usa efectos CSS3 en lugar de solicitar sprites de imágenes pesados
CSS3 ofrece muchas posibilidades de diseño nuevas que reemplazan nuestro uso de imágenes para representar el diseño visual con precisión. Reemplazar una imagen de 2,000 píxeles por 100 bytes de CSS es un gran logro, sin mencionar que quitaste otra solicitud HTTP. Estas son algunas de las propiedades con las que debes familiarizarte:
- Gradientes lineales y radiales
- Border-radius para esquinas redondeadas
- Sombra del cuadro para sombras paralelas y brillo
- RGBA para la opacidad alfa
- Transformaciones para la rotación
- Máscaras de CSS
Por ejemplo, puedes crear botones muy pulidos con degradados y replicar muchos otros efectos sin imágenes. La compatibilidad de los navegadores con la mayoría de estos es muy sólida, y puedes usar una biblioteca como Modernizr para detectar navegadores que no admiten las funciones para usar imágenes en un caso de resguardo.
Sugerencia 10: WebSockets para una publicación más rápida con menos ancho de banda que XHR
WebSockets se diseñó en respuesta a la creciente popularidad de Comet. En efecto, usar WebSockets ahora tiene ventajas, en lugar del modelo Comet sobre XHR.
WebSockets tiene un enmarcado muy ligero, por lo que el ancho de banda que consume suele ser más ligero que el de XHR. Algunos informes indican una reducción del 35% en los bytes enviados por cable. Además, con un volumen más alto, la diferencia de rendimiento en cuanto a la entrega de mensajes es más evidente. XHR se registró en esta prueba con un tiempo agregado un 3500% más largo que WebSockets. Por último, Ericsson Labs analizó el rendimiento de WebSockets y descubrió que los tiempos de ping a través de HTTP eran de 3 a 5 veces más grandes que a través de WebSockets debido a requisitos de procesamiento más sustanciales. Llegaron a la conclusión de que el protocolo WebSocket era claramente más adecuado para las aplicaciones en tiempo real.
Recursos adicionales
Para obtener recomendaciones de medición y rendimiento, debes usar las extensiones de Firefox Page Speed y YSlow. Además, Speed Tracer para Chrome y DynaTrace Ajax para IE proporcionan un nivel más detallado de registro de análisis.