viernes, 23 de marzo de 2012

¿Qué es un polyfill?

Un "polyfill", también conocido como un "polyfiller", es una pieza de código o plugin que te permite trabajar con una tecnología que esperas que el navegador te proporcione de forma nativa.

Y me preguntarás: ¿esto no es un "shim"? Y estarás en lo cierto. Un "shim" es una pieza que intercepta una API de manera transparente, cambiando los parámetros, gestionando la operación directamente o redirigiéndola a otro sitio. Los "shims" se usan típicamente cuando una API cambia. Con un "shim" se puede conseguir, por ejemplo, que código nuevo pueda funcionar con una API antigua u obsoleta.

Por tanto, podemos decir que un "polyfill" es un "shim" pero centrado en proporcionar a navegadores legacy la compatibilidad con funcionalidades HTML5 y CSS3.

A continuación os presento un ejemplo de polyfill para ilustrar el concepto.

requestAnimationFrame

requestAnimationFrame es una nueva característica de los navegadores que permite indicarle al navegador que deseas realizar una animación. Básicamente lo que le dices con esta función al navegador es: "antes de pintar el siguiente frame en pantalla, aplica esta lógica del juego o procesa esta animación". El método recibe como argumento el callback que se tiene que invocar antes del repintado. Como te puedes imaginar, esta función viene genial para programar juegos en entorno web.

Las ventajas de utilizar requestAnimationFrame son varias:
  • Si queremos utilizar setInterval o setTimeout, para realizar una animación a una velocidad constante hay que estar recalculando contantemente la diferencia de tiempo transcurrido entre el último frame y el momento actual, porque el parámetro de tiempo que se pasa a estas funciones no se aplica estrictamente. Con requestAnimationFrame nos olvidamos de esto y conseguimos una tasa de refresco constante.
  • Gestionar tabs inactivas. Esta es una de las grandísimas ventajas que proporciona. Al permitir al navegador elegir el mejor intervalo entre frames, los usuarios podrían estar jugando a un juego muy intensivo en CPU y que al abrir otra pestaña o al minimizar la ventana el juego se pause, liberando recursos para otras tareas. El jsfiddle a continuación lo ilustra correctamente.

El uso de requestAnimationFrame sería en teoría tan sencillo como:



Los problemas de requestAnimationFrame son (al menos) estos dos:
  1. Navegadores antiguos. No existe por lo que hay que tirar de un setInterval o setTimeout.
  2. Navegadores actuales. La API no está estable por lo que es necesario añadir el dichoso prefijo de los navegadores.
Así que necesitamos un polyfill. En este caso, es tan sencillo como lo que ves en el siguiente gist. Nos abstraemos de las implementaciones de los navegadores y tenemos un fallback a setTimeout:



Si quieres una versión más precisa o inteligente de este polyfill, aquí tienes otra versión de Erik Möller, ingeniero de Opera: http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating. Básicamente, escoge el delay más adecuado entre 4ms y 16ms para intentar conseguir una tasa de refresco lo más parecida a 60fps y prepara también el método contrario cancelAnimationFrame. Aquí tienes un gist ligeramente optimizado sobre la versión del artículo: https://gist.github.com/2174491

¡Quiero más polyfills!

Pues estás de suerte, el equipo de Modernizr mantiene un pequeño índice de polyfills en:
https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills

Y, por si te animas, Addy Osmani (está en el equipo de Google desde hace un par de días) ha escrito esta guía sobre como escribir polyfills:
http://addyosmani.com/blog/writing-polyfills/



ACTUALIZACIÓN (25-mar-2012):
Basándome en un ejemplo de 140byt.es aquí te presento otro gist con un polyfill de requestAnimationFrame ultracompacto:




No hay comentarios:

Publicar un comentario