Contenido

Rendimiento extremo de Javascript

10 nov

+ 10

En uno de esos momento de querer pulir scripts en Javascript me pegó la neura de probar diferente formas de hacer lo mismo sacando el cronómetro y midiendo tiempos para ver que era más eficiente y que lo era menos.

Al final, por esas cosas del destino, me tuve que ir al final terminé olvidándome de lo que quería hacer. Hasta ahora que me he encontrado con esta presentación de Thomas Fuchs (author de Script.aculo.us). En ella (la recomiendo) hace exáctamente lo que yo quería hacer, medir los tiempos de ciertas tareas cotidianas y compararlas con alternativas que nos ofrece el mismo resultado.

Algunos de los resultados muestran cosas realmente interesantes:

Rendimiento

Objetos literales frente a clásicos

// Más lento
function literals(){
 var a = [], o = {};
}
// Más rápido
function classic(){
 var a new Array, o = new Object:
}

En la presentación se ven los resultados sobre los diferentes navegadores y podemos ver como de usar uno u otro en Google Chrome podemos multiplicar por 2 el tiempo de proceso.

Loops

Los loops tambien muestran unos resultados curiosos:

var test = '';
for (var i = 0; i<10000; i++)
 test = test + str;

var test = '', i = 10000;
while(i--) test = test + str;

Entre los dos anteriores, no se muestran diferencias en los resultados devueltos.

// Más lenta
function normalLoop(){
 var i = 60, j = 0;
 while(i--) j++;
}

// Más rápida
function unrolledLoop(){
 var j = 0;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
}

Tambien vemos que muy caro hacer un loop, en Firefox multiplicamos por 2 el tiempo y en Google Chrome lo multiplicamos por 5.

Cachear variables globales

// Más rádida
function cache(){
 var w = window, i = 10000;
 while(i--) w.test = 'test';
}

// Más lenta
function nocache(){
 var i = 10000;
 while(i--) window.test = 'test';
}

El cachear variables globables nos ayudará en la mayoría de casos.

Acceder a atributos de un objeto frente a with()

// Más lento
function conwith(){
 var obj = { prop: 'test', str: '' };
 with(obj){
 var i = 10000;
 while(i--) str += prop;
 return str;
 }
}

// Más rápido
function sinwith(){
 var obj = { prop: 'test', str: '' }, i = 10000;
 while(i--) obj.str += obj.prop;
 return obj.str;
}

En los resultados nos muestra que usar with() para acceder a un objeto nos puede penalizar el tiempo de proceso de nuestro Javascript. En el caso de Google Chrome reducimos el tiempo a un 7% del empleado con with().

Pasar a bits frente a parseInt()

// Más lenta
parseInt(12.50);

// Más rápida
~~(1 * "12.5");

Javascript 1.5 integra una serie de operadores a nivel de bit, entre ellos nos encontramos ~(Alt Gr + 4) que representa el NOT a nivel de bit y que en este caso nos ayuda a convertir a entero una cadena como podemos ver en el ejemplo (haciendo un doble NOT para obtener un valor positivo).

Curiosidades del lenguaje

Diferencia entre && y ||

var n = 1;
if (true && (n=2)) ...;
console.log(n);
// --> n = 2
if (true || (n=3)) ...;
console.log(n);
// --> n = 2

Como es lógico, el uso de && evalua las dos condiciones frente a || que si ya se cumple la primera, nos evitamos comprobar la segunda.

(...).toString()

(function(){ return 2 * 3; }).toString();

// IE, Safari y Google Chrome
function(){ return 2 * 3; }

// Firefox
function(){ return 6; }

En este ejemplo vemos como la ejecución de esta función anónima nos muestra un resultado algo extraño en Firefox.

Más info

  1. Extreme Javascript Perfomance (Thomas Fuchs)
  2. JsRocks

Frase de V 2009 1×01

9 nov

+ 5

Existe un Arma poderosa ahí fuera….Devoción.

Erica Evans(V 2009 1×01)

Google Closure, Google nos ayuda a optimizar nuestro Javascript

9 nov

+ 5

Google nos ofrece sus herramientas para optimizar Javascript mediante una serie de componentes que podremos usar desde nuestras aplicaciones. Con ellas podremos conseguir aplicaciones muy ricas en Javascript y rápidas como gMail, Google Docs o Google Maps.

Closure Compiler

Se trata de un optimizador de código que hará nuestras aplicaciones más ligeras y compactas, haciendo que el código redundante, al igual que los espacios en blanco, comentarios y demás desaparezcan de nuestro código.

Ya tenemos un ejemplo de como usarlo en nuestras aplicaciones PHP

$script = file_get_contents('http://www.domain.com/scripts/script.js');
$ch = curl_init('http://closure-compiler.appspot.com/compile');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'output_info=compiled_code&output_format=text&compilation_level=SIMPLE_OPTIMIZATIONS&js_code=' . urlencode($script));
$output = curl_exec($ch);
curl_close($ch);

Basta con cambiar la URL del fichero .js por nuestro fichero Javascript.

[Closure Compile]

Closure Inspector

Extensión para Firebug que nos permite detectar errores del código fuente compactado. Ideal para depurar esas aplicaciones que tenemos en real y que por motivos de optimización hemos compactado.

inspector_originalsource
(Ver Imagen)

[Closure Inspector]

Closure Library

Se trata de una librería Javascript, al igual que jQuery, MooTools, Prototype,… con un conjunto de funciones compatibles entre los diferentes navegadores.

[Closure Library]

Closure Templates

Packs basados en HTML/Javascript que nos permite generar componentes web fácilmente.

[Closure Templates]

Wp-Answers, crea una comunidad de preguntas y respuestas con WordPress

7 nov

+ 77

Hace unos meses empecé a montar este plugin que permite crear comunidades basadas en preguntas y respuestas, al estilo StackOverFlow y/o Yahoo! Answers. La idea es generar, sin modificar para nada el núcleo de WordPress, un sistema basado en votaciones de comentarios y ordenarlos por este número de votaciones.

De esta forma, podremos disponer de un sistema que nos permita lanzar preguntas y que mediante las contestaciones de los usuarios y sus votos, podamos obtener una respuesta lo más acertada posible.

Wp-Answers

El plugin se encarga de añadir un formulario a cada comentario permitiendo que los usuarios puedan votar positiva o negativamente dicho comentario. Posteriormente y dependiendo del número de comentarios de este comentario y los demás, lo ordenará de forma que el comentario con más votos quede primero, el segundo mejor votado segundo y así sucesivamente.

wp-answers
(Ver Imagen)

Nuestro theme

El plugin, está pensado para no depender de ningún theme y que pueda funcionar en cualquiera, por ello todo el estilo CSS y el Javascript (para realizar las llamadas con Ajax) se puede añadir fácilmente adaptándolo a cada WordPress.

Dándole estilos

El formulario, por defecto no tiene estilos aunque puede personalizarse como más nos guste incluyendo los estilos a nuestro style.css de nuestro theme. Os dejo un ejemplo del que he usado para las pruebas:

.wp_answers_votes {
 float:right;
 background-color:#F1F1F1;
 margin-bottom:10px;
 padding:10px
 text-align:center;
 -moz-border-radius:6px;
 -webkit-border-radius:6px;
 border-radius:6px;
}
.wp_answers_total_votes{
 font-size:2em;
}

Opciones

Disponemos de una serie de opciones, muy sencillas que nos permiten configurar el nivel de Karma que aporta o resta la votación de comentarios. Además de poder indicar si necesitamos que el usuario este registrado en el blog o no.

wp-answers-options
(Ver Imagen)

Widget

He creado un pequeño Widget que nos permitirá mostrar un top N usuarios, ordenados por karma acumulado en nuestro sidebar, simplemente tendremos que indicar las opciones del Widget y añadirlo al sidebar que deseemos.

wp-answers-widget
(Ver Imagen)

Descargar

Aquí teneis el enlace, también podeis verlo en funcionamiento con el theme P2 (de WordPress)

Actualización

Por sugerencia de Cristian Eslava añado la opción de seleccionar una categoría a la que asociar este sistema de mostrar los comentarios. De esta forma, es posible asociarlo a una parte de tu WordPress y no a todo.

Another World JS

5 nov

+ 4

Impresionante versión del famoso juego Another World implementado completamente en Javascript. Impresionante el uso de <canvas /> e impresionante el consumo de CPU :D

MooTools nos pide que actualicemos nuestras librerías

5 nov

+ 1

La gente de MooTools publica en su blog una entrada para recomendarnos que actualicemos las versiones 1.1.2 y la versión 1.2.4.

El motivo, la desaparición de el método document.getBoxObjectFor en Mozilla Firefox 3.6.

La última versión de Gecko, elimina este método y afectará directamente a la versión 1.1.2 de MooTools ya que se usa en dos casos concretos:

  • Event.relatedTarget: Identifica el target de cualquier evento. Esta propiedad se usa en muchos sitios del framework.
  • Evento MooseWheel:  Firefox identifica el evento usando “DOMMouseScroll” en lugar “mousewheel”

Por este motivo nos informan de que tenemos la actualización de las dos versiones disponibles para descargar y reemplazar las que usamos actualmente.

MooTools 1.1.2 / MooTools 1.2.4

Excerpt2Content, muestra todo el contenido a tus usuarios

4 nov

+ 12

Muchos son los mails que he recibido pidiendome una solución al problema de que el theme de su WordPress muestra solo una pequeña porción del contenido. Esto es debido a que el theme que están usando está haciendo uso de la función the_excerpt() en lugar de the_content().

La diferencia es que la primera nos muestra únicamente el extracto del artículo, sino lo hemos redactado este cogerá las primeras 55 palabras (por defecto) del artículo, eliminando tags HTML como <img />, <strong />,… haciendo que el contenido tenga un aspecto de “extracto” del original. Generalmente este contenido está seguido de unos puntos suspensivos indicando que el artículo no está completo ([...]). Lo que hace que el usuario tenga que acceder a leer el artículo directamente para ver el contenido completo.

Por otro lado, the_content() nos muestra el contenido completo y nos permite cortarlo donde queramos mediante el uso de 2 tags:

  • <!--more-->: Añade un texto de “Leer Más” (que puedes cambiar) al final de la página principal y que te lleva al artículo completo.
  • <!--nextpage-->: Te permite generar una paginación y cada tag generará una página nueva.

anieto2k_excerpt
(Ver Imagen)

Muchos themes traen the_excerpt() por defecto, ya que la teoría dice (y la práctica lo demuestra) que al mostrar parte del contenido, el usuario genera un mayor número de páginas vistas (una de la página principal y una por cada noticia que quiere ver completa) pero en muchos casos quieres mostrar imágenes o simplemente no quieres que el usuario tenga que acceder a ver un post completo para leer toda la noticia, en estos casos tenemos varias soluciones.

1) Reemplazar the_excerpt() por the_content()

La primera solución sería la de buscar en el theme que estamos usando la palabra the_excerpt() y reemplazarla por the_content() haciendo que siempre se muestre el contenido.

2) Añadir filtro a the_excerpt()

Otra solución más sencilla y fácil de deshacer sería la de añadir un pequeño (muy pequeño) filtro a la llamada the_excerpt() para hacer que nos devuelva el contenido completo.

function excerpt2content(){
 return get_the_content();
}
// Añadimos excerpt2content al filtro
add_filter('get_the_excerpt', 'excerpt2content');

Este código, puede ir alojado en el fichero functions.php del theme y si queremos volver al estado inicial, simplemente tendremos que eliminar estas 4 líneas para volver a la normalidad :D

El consumo de memoria de Firefox 3.6 Beta 1

4 nov

+ 16

En lifehacker hacen una comparativa de los diferentes navegadores web sobre Windows 7 y aunque los resultados no sorprenden a nadie (Google Chrome 4.0 vence sobre Firefox 3.6 beta 1 e Internet Explorer 8.0 termina la lista por detrás de Opera 10.01) nos deja una fantástica gráfica que alegrará a más de uno.

memory_use
(Ver Imagen)

Se trata del consumo de memoria de los navegadores consumida en el arranque y trás la carga completa de 9 pestañas. Como podemos ver Firefox 3.6 beta 1 se alza campeón de esta prueba sorprendiendonos con un consumo inferior al de la versión estable actual (3.5.4).

Una gran noticia para los que usamos Firefox y conocemos los problemas de consumo de memoria con los que lidiamos día a día.

Opera Mobile 10 beta para desarrolladores

3 nov

+ 2

Opera Mobile está evolucionando y es que no solo su hermano mayor lo iba a hacer. La versión móvil, por fin se pasa a Presto 2.4 para renderizar las páginas web y no lo hace solo ya que además incorpora una gran cantidad de mejoras y nuevas funcionalidades para la Internet de hoy.

Opera_Mobile_10_beta
(Ver Imagen)

Como podemos ver el cambio a nivel de interfaz de usuario es destacable y el nuevo aspecto ofrece la capacidad de interactuar mediante el dedo con todas las opciones del navegador. Además esta versión dispondrá de Speed Dial portado a la versión móvil.

Al igual que su hermano mayor, esta versión dispone de Opera Turbo, lo que nos permitirá comprimir las páginas hasta un 70% en caso de disponer de una conexión lenta.

Datos para desarrolladores

Los desarrolladores web, tenemos que tener presente algunas formas de detectar el navegador para condicionar las funcionalidades y/o apariencia.

Agente de usuario

El agente de usuario que arroja esta versión nos permitirá reconocer la versión móvil desde nuestro Javascript.

Opera/9.80 (S60; SymbOS; Opera Mobi/275; U; en-GB) Presto/2.4.13 Version/10.00

Desarrollando para el móvil

Al igual que la versión móvil de Webkit disponemos de una serie de tags HTML y expresiones CSS para condicionar el aspecto para dispositivos móviles.

Meta tag viewport

Tenemos un tag HTML que nos permite especificar el tamaño de la página.

<meta name="viewport" content="width=device-width" />

Media Query

Gracias a la implementación de CSS3 nos es posible condicionar parte del CSS a unos dispositivos u otros, dependiendo del tamaño de la pantalla o del tipo de la misma.

@media screen and (max-width: 480px) {
  background-color: red;
  font-size: 1.5em;
}

Dragonfly

Esta nueva versión nos sorprende con una versión beta de Dragonfly para esta dispositivos móviles. No ofrece las mismas posibilidades que la versión de escritorio, pero nos permitirá seleccionar elementos y debugear nuestras aplicaciones desde el dispositivo móvil.

dragonfly-highlight2
(Ver Imagen)

Nuevos estándares

Entre los nuevos estándares disponibles, que son prácticamente los mismos que la versión de escritorio, cabe destacar la capacidad word-wrap que nos permitirá que el texto se ajuste a la pantalla automáticamente.

word-wrap_demo_mobile
(Ver Imagen)

div p.wrap { word-wrap: break-word; }

Opera siempre ha estado a la última y esta vez no va a ser diferente, con esta versión los dispositivos móviles podrán disfrutar de Internet rica y rápida en su propia mano.

Ordenar artículos por orden de comentarios más recientes

2 nov

+ 1

En Stackoverflow descubro un sistema sencillo para ordenar nuestros posts por orden de comentarios más recientes. Esto nos permitirá mostrar los últimos artículos en los que hay actividad.

<?php

$query = 'select wp_posts.*, max(comment_date) as comment_date
 from $wpdb->posts wp_posts
 right join $wpdb->comments
 on id = comment_post_id
 group by ID
 order by comment_date desc
 limit 10';

$results = $wpdb->get_results($query) or die('!');
foreach ($results as $result):

?>
[Aquí el template del post]
<?php endforeach ?>

Una interesante forma de mostrar de una forma dinámica por parte de la interacción de los usuarios los posts que han sido comentados recientemente.