Alpha's Manifesto

A black and white figure's thought-hive

Link del día: Performance HTML5, CSS3 y DOM, Parte 2: Performance HTML5

Hay varias formas de aproximarse a la performance de una aplicación que está construida bajo los nuevos estándares e implementaciones de HTML5, CSS3, y, por supuesto, JavaScript. Como ya lo habíamos mencionado en la parte 1 de este artículo, el tutorial de HTML5 Rocks llamado Improving the performance of your HTML5 App trata varios puntos que son importantes para lograr una buena performance y una aplicación sólida.

Repasémoslos rápidamente:

  • Delegar animaciones al browser siempre que sea posible
    • Transformaciones y trancisiones con instrucciones CSS
    • Renderización “incentivada” a ser a través del GPU con [code lang=”css”]-webkit-transform: translateZ(0);[/code]
    • Separación de threads de animación con [code lang=”javascript”]window.requestAnimationFrame[/code]
  • Profiling de JavaScript
    • Utilizar el DOM lo menos posible
    • Nombrar funciones anónimas para identificar dónde están los problemas más fácilmente
    • Refactorizar el código
    • Crear funciones definidas y autollamadas si hacer métodos más pequeños no se puede (de esa forma “nombramos” parte del código)
  • Utilización del DOM
    • Lo menos posible (nuevamente)
    • Cachear elementos cuando tenga sentido
    • Hacer lecturas, luego modificaciones, luego escrituras para evitar reflows
    • No usar el DOM dentro de loops
  • Inicialización tardía
    • Delegación de eventos en lugar de asociación de handlers

Y eso es, a muy grandes rasgos, este artículo. Realmente recomiendo que le den una leída a fondo si ustedes trabajan del lado de la web. Realmente no verán una página de la misma manera.

Soy un zorrinito performante.

Link del día: Cómo atacar un problema de performance

Hablando de la web y performance y todo eso, creo que nunca hemos visto un caso práctico de cómo debería atacarse un problema de performance. Es decir, si sospechamos que hay un problema de estos en un determinado lugar, ¿cuáles son los pasos a ejecutar? Creo que la experiencia juega mucho a favor, porque cada caso es distinto, pero siempre es mejor observar este tipo de situaciones en webs o aplicaciones que tienen una carga pesada diaria, con lo cual un problema de performance es mucho más pequeño y difícil de detectar, y las mejoras que se necesitan son mucho más finas y difíciles de lograr.

En el blog de Sam Saffron, nos cuenta cómo se trata uno de estos problemas en la famosa web Stack Overflow, llamada A day in the life of a slow page at Stack Overflow.

Como podemos ver, las aproximaciones al problema son varias, desde la tecnología utilizada, hasta el tipo de queries que se hacen a base de datos, optimizaciones en las mismas, y hay miles de cosas más que podrían estar involucradas (imágenes, textos, procesamiento de distintos elementos… en fin, es todo un mundo.

Soy un zorrinito performante.

Link del día: Optimización web vs. desarrollo prolijo

Hace tiempo ya estaba comentando con un colega sobre la enorme cantidad de medidas que pueden tomarse para mejorar la performance de una aplicación web. Existen miles de factores involucrados, entre los cuales hay muchas configuraciones y tweaks que pueden hacerse al servidor, pero muchos otros tienen que ver con el código en sí mismo. Sí señores, estamos hablando de HTML, CSS y JS.

El problema en este punto es que un HTML mínimo puede no ser el HTML que nuestro generador de contenidos genera. Puede que el CSS sea automatizado también, o que nuestro diseñador o desarrollador HTML no esté pensando en hacer las cosas de la forma “más mínima posible”, sino realmente trabajando en hacer que algo se vea bien y esté bien codificado. No está entre sus prioridades escribir

[css light=”true”]
background: url("image.jpg") repeat top left scroll;
[/css]

en lugar de

[css light=”true”]
background: url(image.jpg);
[/css]

Ambos son equivalentes, pero la segunda es más corta y por tanto más eficiente. Pero nuestro desarrollador debe realmente preocuparse porque el desarrollo sea correcto, que la visualización sea consistente y que sea acorde entre navegadores.

Ni hablar de JavaScript, en donde la cantidad de optimizaciones, minimizaciones y mejoras puede ser realmente importante. Alguno quiere trabajar sobre JavaScrpt minimizado? Sin duda: no.

La alternativa a la que llegamos era la de tener dos versiones de la aplicación. La de desarrollo con código normal y la de producción. Una vez que desde la de desarrollo se hicieran pruebas y quisiera hacerse un release, solo teníamos que correr una serie de herramientas que nos permitieran tener una versión minimizada y optimizada del código, bajo el riesgo de que algo se rompiera en el proceso.

Pero ahora Google acaba de publicar un módulo que han desarrollado para Apache 2.2, llamado mod_pagespeed, el cual hace optimizaciones y cache en el momento de los pedidos, para optimizar los sitios web sin tener que modificar los archivos reales. Por supuesto, es altamente configurable, y podemos ver la gran cantidad de mejoras que puede realizar en el poco tiempo que tiene.

Google nos cuenta que ya está trabajando con GoDaddy para que todos sus clientes puedan utilizarlo, y con Cotendo para que esté disponible en su CDN también. Si ustedes no tienen la suerte de estar entre ellos, pueden bajarlo por cuenta propia desde la página del proyecto de PageSpeed, e instalarlo en sus propios servidores.

Soy un zorrinito acelerado.

Doppler Reports (Español)

Hola a todos

Me enorgullece poder anunciar que desde hace un tiempo he tenido la oportunidad de trabajar junto con el equipo Doppler para un nuevo proyecto, algo que desde entonces se estaba formando llamado Doppler Reports (link). Este proyecto finalmente vio la luz y está activo públicamente desde el 27 de Julio. Permítanme contarles un poco más sobre eso.

Momento… ¿qué es Doppler?

Doppler Email MarketingPara aquellos que no lo conocen, Doppler es una herramienta de email-marketing. Es realmente compleja, pero explicándola en un vistazo rápido, es posible usarla para crear contenido de email online (basado en plantillas o editandolo manualmente), y enviarlo masivamente a una o más listas pre-cargadas. Sim embargo, hay mucho más para lo que puede utilizarse, y una de las grandes posibilidades que nos ofrece está en la capacidad de analizar la reacción del cliente a nuestras campañas de emails. Cuando uno tiene diez, quizá veinte, cincuenta o cien contactos, esto es algo que se puede hacer fácilmente con un listado de ellos. Uno verifica sus contactos, analiza quién abrió los emails enviados, quién hizo click en cuál link, y esa es toda la información que uno necesita.

¿Reportes?

Las cosas cambiaron mucho desde esa mañana del 2005. ¿Qué pasa cuando tienes mil contactos? ¿Y un millón? No, no estoy exagerando. Eso es parte de nuestro trabajo *diario*: mantener una herramienta que envía millones de emails. ¿Cómo obtenemos los resultados y los mostramos al usuario? La respuesta obvia es: Reportes.

Los reportes  te darán toda la información resumida que necesitas sin tener que revisar cada uno de los contactos (porque, por supuesto, el sistema lo hace por tí). A medida que la tecnología evoluciona y que el comportamiento del cliente evoluciona a medida que el marketing evoluciona, nuestras herramientas deben evolucionar también.

Aquí es donde el Equipo de Doppler vio la necesidad de una aplicación de reportes totalmente nueva, para poder satisfacer muchos pedidos que nuestros clientes tenían para la versión anterior de la misma. Pero esta herramienta debía estar pensada para millones de emails, miles de usuarios, información en tiempo real y al mismo tiempo, reportes informativos y elegantes.

Y entramos en la escena. Tuve la oportunidad de trabajar junto con Juan Fazzini para diseñar una arquitectura que escalaría a medida que Doppler siguiera creciendo con todas las futuras características que obtendrá. Entonces, en una tarde de viernes, un pizarrón en blanco, una notebook como grabadora para todo lo que decíamos (ya saben, la documentación es importante), comenzamos a idear y pensar sobre cómo Doppler Reports trabajaría.

¿Cómo está diseñada la arquitectura?

1. Arquitectura distribuida

Distributed architectureCada parte de Doppler funcionará como un módulo independiente, que puede tener varias instancias funcionando al mismo tiempo. Hay un módulo en especial que se encargará de interconectar a los demás entre ellos, pero estos módulos de interconexión pueden trabajar de forma independiente también.

Esto significa que ahora tenemos mayor tolerancia a errores catastróficos. Si un servidor deja de funcionar, las otras instancias de los módulos seguirán trabajando, manteniendo al sistema con funcionamiento normal. Los usuarios no se darán cuenta, apenas puede que noten una demora pequeña en la aplicación.

También significa que si tenemos mucha carga por uso intensivo, podemos crear nuevas instancias de un módulo y los módulos de interconexión automáticamente balancearán la carga.

2. Seguridad en cada llamada

Keys and lock

Tener estos módulos ahí afuera no es poca cosa para la seguridad. La seguridad tiene que ser tan estricta como es posible. Por eso, desarrollamos un protocolo de comunicación que le permitiría a cada módulo verificar si el que llama al mismo es una aplicación autorizada y si está bien devolver datos a la misma. Si todo funciona bien, la llamada se realiza y los datos se devuelven. Si algo no sale bien, como si se provee un token de autorización incorrecto, nunca se sabrá qué pasó. Sabemos que esto no es particularmente transparente para los programadores, pero es lo más seguro que podemos realizar para prevenir intentos de hacking.

El resultado de esta característica es que, incluso cuando los módulos estén disponibles en Internet (no todavía, pero quizás en algún momento lo estén), no cualquiera puede acceder a ellos. Incluso si saben en dónde están o cómo llamarlos, ellos no harían nada hasta que los clientes le provean un token de seguridad auténtico.

También significa que las claves de seguridad para acceder a este módulo se pueden generar y, en el futuro, podría resultar en una API para ciertos módulos de Doppler que cualquiera (o algunos usuarios) podrían utilizar. ¿Imaginas crear una aplicación para tu propia empresa que automáticamente trabaje con los datos que Doppler generó para tí?

3. Reportes en tiempo real

Más que una decisión arquitectural, esto fue un desafío. Ya se sabe que estamos manejando toneladas de datos. ¿Cómo cargarlos rápidamente? ¿Cómo obtener una buena performance? Para eso, decidimos que algunos objetos trabajarían internamente como proxies, de forma que sólo se obtendría la información que se ve.

Esto significa que ahora al entrar a la pantalla de Resumen de Métricas para una de tus campañas, podrías ver (cuidado… se viene un listado grande):

Quick clock

  • Nombre de la campaña
  • Asunto del email de la campaña
  • Tipo de campaña
  • Cantidad de listados de emails que recibieron la campaña
  • Cuántos suscriptores recibieron la campaña
  • Cuándo se envió la campaña
  • Aperturas por cada hora
  • Clicks por cada hora
  • Cuántos emails fueron abiertos (total)
  • Cuántos emails todavía no han sido abiertos
  • Cuántos emails resultaron en soft-bounce
  • Cuántos emails resultaron en hard-bounce
  • Última fecha de apertura
  • Clicks únicos
  • Aperturas únicas
  • Cada uno de los links
  • Para cada link, cuántos suscriptores hicieron click en ellos
  • Para cada país del mundo, cuántas aperturas ocurrieron en ese país

*toma aire* ¿Saben cuánto tiempo le toma a Doppler Reports obtener y mostrar toda esa información? Menos de 5 segundos. Pongo énfasis en ello: Menos. De. Cinco. Segundos. Ese es el tiempo que me toma leer las primeras tres líneas de la página. Quizá cuatro, quizá cinco. Pero antes de que haya terminado de hacerlo, la página está completamente cargada y funcionando. Y debo aclarar, mi conexión a internet no se destaca por su velocidad.

Por supuesto, también usamos caching. Esto agrega una capa más de interacción hasta los datos, pero nuestro sistema de caching nos asegura que tengamos los datos listos para el usuario en el momento que los pida. Los datos de una campaña no cambian mucho, a menos que se acabara de enviar, por lo que, para la gran mayoría de los casos, podrías ver los datos de tu campaña tan rápido como cualquier otra página web.

4. Diseño modular

Puzzle

Mencioné antes que Doppler ha comenzado a ser más y más complejo, y ahora está siendo diseñado de una forma modular. De esta forma, los módulos trabajan independientemente y a la vez, delegan responsabilidad en el módulo que sabe cómo resolver un cierto problema o cómo tratar cierto conjunto de datos. Tener un diseño modular es un aspecto terriblemente importante para cambios futuros. Le permite a nuestro equipo paralelizar el trabajo, y le permite a nuestro equipo (y a nuestra aplicación) crecer.

Esto tiene importantes consecuencias. Para el lado que el usuario logra ver, esto significa que muchas características estarán disponibles más rápidamente. Nuevas características, más mejoras, más robusto, más rápido, mejor. “Harder, faster, better, stronger.”, como Daft Punk recomienda construir el software.

Eso es increíble, ¿puedo usarlo?

Por supuesto. Estas nuevas características ya están disponibles para todos los usuarios que tengan una cuenta de Doppler. Si no tienes una, puedes crearte una de forma gratuita y probar el producto por tí mismo: http://www.FromDoppler.com/.

Antes de que se vayan…

…Quería decir que considero un logro personal haber podido formar parte de todo esto. Intentamos lograr algo radical y hoy tenemos un producto radical. Creo que el Equipo Doppler está muy orgulloso de lo que han logrado. Yo ciertamente lo estoy.

Ah, y este post ha llegado hasta el blog de GetCS. Visitenló, puede que les interese.

Doppler Reports

Hello to you all

I’m really glad to announce that since some time ago, I had the opportunity to work along with the Doppler team for a new project, something that since that time was evolving, called Doppler Reports. This project finally became active and working publicly on July 27th. Let me tell you a little more about it.

What is Doppler anyway?

Doppler Email MarketingFor those that are not aware of it, Doppler is a online email-marketing tool. It’s really complex, but explaining it just at a glance, you can use it to create email content online (template-based or editing it yourself online), and sending it massively to one or many of your pre-entered mailing lists. However, there is much more to it, and one of the big powers enclosed in such a tool is the ability to analyze the customer’s reaction to your mail campaigns. When you have ten, maybe twenty, fifty, or even a hundred customers, this is something you could easily do with lists. You check for your contacts, you see who opened the email you sent, you see who click on which link, and that’s all the information you need to go on.

Reports?

Things have changed a lot in the business since that morning in 2005. What happens when you’ve got a thousand contacts. A million? No, I’m not exagerating. That’s part of our everyday work, maintaining a tool that daily sends millions of emails. How do we get results and present them to the users? The obvious answer is: reports.

Summarizing reports will give you the information youneed without having to scan for each of your contacts (because, of course, the system does it for you). And as technologies evolve, and as customer behavior evolves, and as marketing evolves, our tools needs to evolve too.

That’s where the Doppler Team saw the necessity of creating a new brand report application, in order to fulfill a lot of requests that our customers had from the previous version of our reporting tool. But this one would have to be thought for millions of emails, thousands of users, real time information and at the same time elegant and data-rich reports.

Then we entered the scene. I had the chance to work closely along with Juan Fazzini to design an architecture that would scale as Doppler would get bigger with all future features that it will get. So, in a Friday afternoon, a big white board, a notebook as recorder to keep track of everything we said (you know, documentation is important), we started brainstorming and dreaming about what Doppler reports would work like.

How is the architecture designed?

1. Distributed architecture

Distributed architectureEvery part of Doppler will work as a separated module, that can have many instances working at the same time. There is a special module which will take care of connecting all of the others between them, but these interconnection modules may work independently as well.

This means that we now have more catastrophic-error tolerance. If one server fails down, the other instance of the module will keep on working, and users will notice nothing, but maybe some little delay on the application.

This also means that if we have too much load, because of intensive use, we can just create new module instances and the interconnection modules load balancing will automatically take care of the load.

2. Security on each call

Keys and lockHaving this modules out on the wild is no little thing for security. So, security had to be strong as possible, and we developed a communication protocol that would allow each module to check if the caller is in fact an authorized application and that it is ok to return data to it. If everything goes right, then the call is made and the results are returned. If something goes wrong, as like if you provided an incorrect token, you would never know what happened. This is not transparent at all for the end developer (and we know that), but it is as secure as it gets to prevent hackers.

This means that even when modules are out in the internet (not right now, but maybe someday), not anyone can access them. Even if they knew where they are and how to call it, it would just do nothing until clients provide an authorized token.

This also means that the keys that allow access to this module can be generated and in the future, the API for certain Doppler modules would be available for everyone (or just some users) to use. Do you imagine creating an application for your business that would automatically work with the data Doppler generated for you?

3. Real time reports

More than an architectural decision, this was a challenge. You already know that we are handling tones of data. How to load it quickly, how to achieve a high performance? For that, we decided to make some internal objects proxy-like, so that you would only get the information you request.

This means that you can now enter the dashboard screen summary report for one of your campaigns, and you would see (beware… long list coming):

  • Quick clockName of the campaign
  • Subject for the campaign
  • Campaign type
  • Amount of mailing lists that received that campaign
  • How many unique subscribers received
  • When was the campaign sent
  • Total openings by hour
  • Total clicks by hour
  • How many mails where opened (total)
  • How many mails haven’t been opened yet
  • How many mails have soft-bounced
  • How many mails have hard-bounced
  • Last open date
  • Unique clicks
  • Unique opens
  • Last click date
  • Each of the links
  • For each of the links, how many subscribers clicked on them
  • For each country in the world, how many openings happened in that country

*breathes for air* Do you know how much time takes to Doppler Reports gather and show all that information? Less than 5 seconds. Let me emphasize that: Less. Than. Five. Seconds. That’s what takes me to read the first three lines of the page. Maybe four, maybe five. But before I finished doing that, all the page is completely loaded and working. And I have to say, mine is not a premium connection.

Of course, we also use caching. This adds another layer of interaction until we get to the data, but our caching framework provides us with the ability of habing the data ready for the user right away. Campaign data does not change very often unless you have just sent it, so for most of the cases, you will be able to check your campaign data as quick as any webpage would load up.

4. Modular design

PuzzleI mentioned before that Doppler had started to become more complex, and is now being designed with a modular approach. In this way, modules work independently and at the same time, they rely responsibilities on the module that really knows how to solve a certain problem, or to treat certain data. Having a modular design is terribly important for future changes. It allows our team to parallelize work, it allows our team (and application) to grow.

This has great consequences. On the users side, new features will be available sooner. New features, new improvements. Harder, faster, better, stronger. (As Daft Punk suggests we build our software.)

That impresses me, may I use it?

Of course, this new features are available to all users that have a Doppler account. If you don’t have one, you can even create one free and try the product for yourself: http://www.FromDoppler.com/

Before you go…

…I just want to say that I consider a personal achievement having been part of all of this.  We tried to do something radical, and we have a radical product today. I think that all of the Doppler Team is very proud of what they have today, and I sure am too.

Oh, and this post has made its way into the GetCS blog. Make sure to check it out.

Link del día: Performance Web

A pedido de JF que está luchando con la performance de algunas aplicaciones web, hago un compilado de ciertos links que fui encontrando hace tiempo, y que de seguro serán útiles a más de una persona para mejorar la velocidad con la que funciona una web application. Especialmente ahora que es tenido en cuenta para su Page Ranking.

Comenzamos!

Eso es todo por hoy, pero seguramente tengo más por ahí guardado que hoy no logré encontrar. A apurar los websites!

UPDATE 21/05/2010:

Agrego los siguientes links que me mandó El Hombre Gris, para optimización de PNGs, parte I y parte II, de la misma idea que el de la optimización de JPEG que vimos antes.

Soy un zorrinito rápido.

Link of the day: Google Security

Well… sort of. It’s not anything new these days, but a while ago, Google published it’s own security testing tool for website security testing, called Skipfish. Of course, this is not the first tool that Google releases for this purposes, as many related are already out there (like ratproxy, the Browser Security Handbook, and so on…). However, the new thing today is skipfish.

Skipfish is an active website scanner that will test the web applications for XSS, SQL Injection, Shell injection, XML Injection (that one’s new for me), SSL, insecure cookies, correct MIME headers, server errors, invalid links… etc. The complete list is enormous, and one of the main things is that this tool is being developed on C for high performance. It claims to be able to run with 2000 requests per second on remote servers (of course, if the servers answers in time).

I haven’t had the chance yet to give it a try but I probably will these days. These are the kind of reports that you may see from it, see a skipfish screenshot.

This all came from Google’s Online Security Blog. It is worth a reading, updates are not too much common nor too much big, so you can keep easily up to date with your favorite RSS reader.

I’m a secure little skunk.

Link del día: consejitos de jQuery para pr0s

Ayer Xyborg compartió un link llamado jQuery and general Javascript Tips to improve your code. No sólo me encantaron los consejos que ahí aparecían, sino que me encontré con que dicho artículo tiene una secuela, llamada More jQuery and General Javascript Tips to improve your code.

Ambos artículos son muy detallados y concisos, con un montón de items interesantes que se pueden utilizar a modo de check-list para tunear finamente el código que hayamos hecho en jQuery. Algunos consejos probablemente no los vayamos a utilizar en el momento, pero sabiéndolos, en el futuro podremos mejorar un poco nuestras prácticas. Por ejemplo, quizá no usemos la consola o no usemos el almacenamiento de datos en los objetos, pero conociendo eso, a futuro podríamos hacer las cosas de forma más simple.

Otros consejos los podemos aplicar siempre: utilizar siempre IDs en lo posible para las búsquedas (o anteponer un ID en la búsqueda de clases), otros están apuntados a la performance, a la elegancia de código o a la reutilización del mismo, otros son snippets que podemos reutilizar para nuestras necesidades y otros son consejos para proyectos que pueden volverse demasiado grandes para verificar fácilmente.

Quien trabaje con jQuery no tiene excusa para no conocer lo bueno de estos consejos.

Soy un zorrrinito JavaScript.

Link del día: WPA Cracker

Si mal no recuerdo creo que fue Nano quién me compartió por Google Reader este artículo de Kabytes, en donde hablan de una aplicación web llamada WPA Cracker, una aplicación que tomando un archivo pcap de capturas de un wifi WPA, puede compararlo contra una enorme cantidad de palabras y combinaciones (gracias al cloud computing) y devolvernos el password en un pequeño tiempo.

El uso de esta aplicación es paga, no realmente mucho si es que tiene algún beneficio para nosotros la utilización de esa red, pero independientemente de eso, es una buena aproximación a la obtención de claves: no tiene por qué hacer todo el trabajo una sola máquina durante semanas, cuando varias máquinas alrededor del mundo pueden hacerlo en cuestión de horas o minutos.

Fuera de eso, la aplicación es interesante, también permite el crackeo por diccionario de archivos ZIP (sólo porque el público lo pidió), nuevamente también contra un diccionario enorme de palabras en inglés y en alemán.

Según cuenta el autor, es un esfuerzo mucho más grande pero mejor para resultar de esta forma porque utilizar rainbow tables (como las que tienen para bajar en Curch of Wifi) es un poco ineficiente, dado que para eso se necesita crear una serie de rainbow tables para cada ESSID de la red, con lo cual se vuelve impracticable la idea original del rainbow table: tener una solución pre-armada, por pesada que fuera.

El precio que se le pone al servicio es de 17 dólares si es que queremos utilizar el diccionario básico (136 millones de palabras) en modo half-cluster (es decir, la mitad de las máquinas disponibles trabajan), o 35 si queremos utilizar el clúster completo. Además, también se puede hacer una corrida contra un diccionario extendido (que no contiene al diccionario básico) con 284 millones de palabras. Realmente bastante como para que se haga en unos 20 minutos, verdad?

Cabe decir por último que este es otro de los trabajos de Moxie Marlinspike, un hacker que siempre interesado en la seguridad (y en la navegación [marina, no por internet], pero eso es otra cosa). Puede verse mucho más al respecto en su website, más personal que website, y más elegante que completo.

Soy un zorrinito cracker.

Link del día: Google Closure

Hace ya algunos días que Google publicó sus Closure Tools, una serie de herramientas para trabajar con JavaScript eficiente y lograr mejorar la performance, velocidad y tamaño del código. Entre ellos se encuentran Closure Compiler, una suerte de compilador para JavaScript, removiendo código innecesario, mejorando el código existente y minimizando lo que queda. También está la Closure Library, una librería JavaScript pero versión Google, y por último, los Closure Templates, una serie de soluciones “pre-hechas” para elementos reutilizables de HTML y UI.

Ahora, todo esto llama mi atención desde un artículo que encontré llamado Google Closure: How not to write JavaScript, que al principio parecía ser una crítica vacía de estas herramientas, pero luego se llena de fundamentos y (aquí es lo interesante) muchos datos que la gente de Google saltó al momento de crear estas herramientas. Esos datos son los que nos permitirían a nosotros aprender de esos errores y mejorar nuestras propias prácticas. Hay en todos lados para aprender.

Soy un zorrinito JavaScript.