Too Cool for Internet Explorer

Vivimos en un mundo mal formado 2

Hora y Fecha: Diciembre 8, 2006 @ 9:53 pm Autor: Moisés Maciá
Categorías:
465 views

Ian Hickson realizó un pequeño experimento y lo publicó en la lista de distribución de la W3C, lo traduzco:

Hice un pequeño estudio recientemente comprobando únicamente los errores sintácticos de documentos HTML, y los resultados fueron que de 667.416 archivos testeados, 626.575 tenían errores sintácticos. Más del 93%.

Sólo errores sintácticos en el HTML, no comprobé el CSS, el contenido, los errores semánticos (por ejemplo IDs duplicados — 86.461 documentos del espacio muestral contenían IDs duplicados ), u otro tipo de errores.

Si incluimos estos, encontraremos que la mayoría de las paginas contienen algún tipo de error que dispara la alerta. Así que algún tipo de UI estaría continuamente diciéndonos esta pagina tiene errores. Esto no sería un buen UI para la mayoría de los usuarios, a los que simplemente no les importa.

HTML error chart

Ante lo que Tim-Berners Lee, el padre de la Web, concluía con que el movimiento para una Web bien formada con XHTML ha fallado:

Tengo algunas cosas claras con el paso de los años. Necesitamos evolucionar HTML de manera incremental. En intento de que todo el mundo cambiara a XML, incluyendo el entrecomillado del valor de los atributos, las barras para cerrar las etiquetas vacías y los espacios de nombre, todo a la vez no funcionó. La mayoría de gente que publicaba en HTML no movió un dedo, en gran medida porque los navegadores no se ajustaron al nuevo sistema. Algunas comunidades si que dieron el paso y están disfrutando de los frutos de los sistemas bien formados, pero no todos. Es importante mantener HTML de manera incremental, así como continuar la transición al mundo de los documentos bien formados, y enfatizar ese mundo.

Posiblemente sea por eso que ahora mismo hay 63 errores de validación en la pagina principal de Google. Nos guste o no, vivimos en un mundo mal formado. Los navegadores no son compiladores, y siempre han sido, tolerantes por diseño.

A tu navegador no le importa si tu HTML está bien formado. Tus usuarios/clientes ni siquiera saben lo que es HTML, así que tampoco les importa si esta bien formado o no. ¿Entonces, por qué te debería importar?

La mayoría de los problemas que presenta este artículo vienen de la primera gran guerra de los navegadores de Internet disputada entre Netscape y Microsoft a mediados de los 90. Echarle las culpas a Microsoft sería muy fácil pero realmente es tan culpable uno como otro porque ambos se dedicaron a inyectar en la web funcionalidades incompatibles entre sí. El hecho de que HTML por aquel entonces, ni era formal ni estaba ampliamete probado, no hizo más que empeorar la situación.

Los navegadores no son compiladores, pero quizá si deberían serlo ya que procesan un lenguaje formal y como tal está regido por una gramática y una semántica que definen su construcción y significado unívocamente. Actualmente un navegador se programa dos veces: una bien, respetando el lenguaje y otra mal para corregir ese 93% de errores. Esta situación hace que el renderizado de documentos no sea óptimo bajo casi ninguna circunstancia y los navegadores empleen dos métodos de renderizado: standard compliance y quirks mode. ¿Cuantos parches críticos recibe IE a lo largo del año para corregir hacks a través de código mal formado? Muchos.

Replanteemos la situación. Si yo escribo en C y olvido un punto y coma, el compilador me dirá que tengo un fallo; si olvido inicializar una variable entera o hago algo raro con un puntero me dirá “tu código, aunque puedo compilarlo, es posible que dé problemas” y sabré que efectivamente si porto el código a otra maquina u otro compilador aquello no va a funcionar.

A tu compilador no le importa que tu código devuelva 5.000 warnings. Tus usuarios/clientes ni siquiera saben lo que es un warning. ¿Entonces, por qué te debería importar? Si tu código devuelve 5.000 warnings no tienes perdón de $DEITY, deberías considerar aprender a programar en lugar de hacer Crtl+C Crtl+V desde Google, porque me juego el cuello a que semejante aberración es imposible de mantener.

¿A tus clientes/usuarios les importa estar bien posicionados en los buscadores? ¿Te importa a ti?
El código mal formado funciona más o menos bien en la mayoría de los navegadores porque las empresas han invertido mucho tiempo y dinero en el manejo de estas situaciones. Lo han hecho porque los usuarios así lo demandan. Pero no esperes que los parsers que utilizan los robots buscadores actuen de la misma manera que tu navegador favorito (de echo no lo hacen).

Si olvidas las comillas alrededor de una URL, posiblemente el robot no sepa que tiene que indexarla, o quizá sí. ¿Cómo prodríamos estar seguros? ¿Quieres correr el riesgo? Si tu código es válido no te tienes que preocupar de estas cosas.

Un documento HTML mal formado es prácticamene imposible de depurar, es una escopeta de feria que puede estallar en tu cara en cualquier momento: Javascript, CSS, AJAX, todas esas tecnologías esperan un documento bien formado para aplicarle cambios. Si tu árbol XML está cojo nada va a funcionar o como poco tendrás increíbles dolores de cabeza para saber qué demonios anda mal y cómo corregirlo para que funcione bien en todas las plataformas.

Un documento HTML mal formado o con una semántica pobre es infinitamente más complicado de modificar y mantener mediante scripts PHP, JSP, ASP o la tecnología que utilices. ¿Habéis intentado modificar mediante PHP un layout hecho con tablas?

Esto no va de ser más cool, más 2.0, de lucir camisetas con tags XHTML. Esto va de producir más, con mayor calidad, simplificar el mantenimiento e intercomunicación entre aplicaciones.

Jeff Atwood también habla del tema, aunque parece no tenerlo tan claro como yo :)



Paginado de datos 2

Hora y Fecha: @ 7:13 pm Autor: Moisés Maciá
Categorías:
886 views

Después del tsunami menéame de ayer (en un par de horas tuve el tráfico de casi un mes) vamos a retomar un poco la temática habitual hablando de varios trucos para paginar datos en MySQL.

¿Qué es el paginado?

El paginado de datos consiste en trocear una salida de datos muy larga en paquetes mas pequeños y digeribles para el usuario. Hay ejemplos de paginados en la inmensa mayoría de aplicaciones, especialmente en las de Internet. Por ejemplo:

Paginado de Google:

Paginado de Google

Paginado de Flickr:

Paginado en Flickr

Paginado de Digg:

Paginado en Digg

¿Por qué debo paginar?

  • Para el usuario es más sencillo ver 10 paquetes de 10 resultados que 100 de golpe.
  • Probablemente al usuario sólo le interesen los resultados más relevantes que son los que aparecen en la primera o segunda página.
  • Para la base de datos es más sencillo y rápido traer 10 resultados que 100.
  • Para el servidor HTTP es más sencillo y rápido servir 10 resultados que pesan 20Kb en lugar de 100 resultados que pesan 200Kb.

¿Cómo paginar datos?

Para paginar los datos necesitamos de antemano dos cosas: el tamaño de la pagina y el total de filas que tenemos de datos.

Contamos el total de filas:

  1.  
  2. SELECT COUNT(*) AS total FROM employees;
total
---------------
63

Mediante la instrucción SQL LIMIT n,m podemos trocear los datos de salida y mostrar la pagina que nos interese. LIMIT acepta dos parámetros: el primero es el offset de la pagina y el segundo la cantidad de filas que devuelve.

Devolvemos 10 resultados de la pagina 3:

  1.  
  2. SELECT id,name FROM employees LIMIT 3,10;
id      name
------------------------
13     Pepe
22     Manolo
34     Jose
...

Necesitamos el total de filas para calcular cuantos paquetes de datos (paginas) necesitamos. En este caso tenemos un total de 63 filas paginadas de 10 en 10. Veamos un script PHP muy simple que nos devuelve las paginas:

  1.  
  2. $pagging = 10;
  3. isset($_GET[‘page’]) ? $current = (int)$_GET[‘page’] : $current = 1;
  4.  
  5. $q = mysql_query("SELECT COUNT(*) FROM employees;");
  6. $row = mysql_fetch_assoc($q);
  7.  
  8. $total_pages = (int)ceil($row[‘total’]/$pagging);
  9.  
  10. //header pagging
  11. echo "Pagina $current de $total_pages ({$row['total']} resultados)nn";
  12.  
  13. //body pagging
  14. $q = msql_query("SELECT id,name FROM employees LIMIT {$current-1},$pagging;");
  15. while($row = mysql_fetch_assoc($q))
  16. {
  17.    echo vsprintf("%dt%sn", array($row[‘id’], $row[‘name’]));
  18. }
  19.  
  20. //footer pagging
  21. echo "«t";
  22. for($i=0;$i < $total_pages;$i++)
  23. {
  24.    if($i === ($current-1))
  25.       echo " [$i] ";
  26.    else
  27.       echo " $i ";
  28. }
  29. echo "t»";
Pagina  1 de 7 (63 resultados)

13     Pepe
22     Manolo
34     Jose
...

«   [1] 2 3 4 5 6 7   »

Consideraciones para MySQL

Para calcular el paginado debemos utilizar obligatoriamente dos consultas como mínimo, si las consultas son complejas podemos tener un problema de rendimiento importante pero existen maneras de atajar el camino. Si la base de datos que utilizamos es MySQL existe un hack para devolver el resultado paginado y el total de filas en un solo paso.

Seleccionamos la pagina que nos interesa:

  1.  
  2. SELECT SQL_CALC_FOUND_ROWS id,name FROM employees LIMIT 0,10;

Miramos cuantas filas tiene en total:

  1.  
  2. SELECT FOUND_ROWS();

Siguen siendo dos consultas pero a efectos prácticos rinde como “una y media”, en cualquier caso nunca será tan lento como hacerlo con las dos consultas anteriores.

SQL_CALC_FOUND_ROWS funciona a partir de la versión 4 de MySQL si no recuerdo mal.

Las instrucciones SQL_CALC_FOUND_ROWS y FOUND_ROWS() deben ir una detrás de otra, si hacemos consultas por en medio es muy probable que nos encontremos con resultados imprecisos.

Me consta que Oracle tiene una instrucción equivalente pero no sabría explicaros, no tengo suficiente experiencia con esa base de datos. PostgreSQL y SQLite si que sé seguro que no pueden hacer uso de este hack, al menos en sus versiones actuales.

Paginado deluxe en CakePHP

Los usuarios de CakePHP estamos de suerte, Andy Dawson escribió un helper que permite realizar paginados de cualquier tipo de datos con muy poco esfuerzo. Permite ordenar datos tabulados por columnas y el interfaz de control funciona completamente en AJAX (si el cliente lo permite o nosotros lo forzamos).

Encontrareis todo lo referente al paginado en Bakery.




Bad Behavior has blocked 208 access attempts in the last 7 days.