Libra es un ERP basado en Oracle desarrollado por la empresa EDISA.
El módulo de movilidad es un desarrollo HTML5 que permite consultar información del ERP y ejecutar determinados procesos desde dispositivos móviles.
Presentamos el módulo y explicamos algunas de las técnicas de optimización aplicadas para mejorar la experiencia de usuario.
4. @marcosesperon
Libra
Libra es un ERP
desarrollado por EDISA
con tecnologías Oracle.
ERP son las siglas de
Enterprise Resource
Planning (planificación
de recursos
empresariales).
Sistema integrado que
combina los procesos
bajo un mismo
esquema que beneficia
a la organización.
5. @marcosesperon
Libra
• Optimización de los procesos
empresariales.
• Acceso a toda la información con
integridad de datos.
• Compartir información entre todos
los componentes de la organización.
• Reducir operaciones innecesarias.
• Análisis global de la información.
Características de un ERP
12. @marcosesperon
Libra Movilidad
El módulo se ejecutará en cualquier dispositivo con navegador
web: equipos de sobremesa, smartphones, tablets, PDAs,
televisiones…
Plataformas disponibles al comenzar el proyecto (2011)
22. @marcosesperon
Mantener conexiones abiertas
HTTP Response
HTTP/1.1 200 OK
Content-Type: application/javascript
Connection: close
KeepAlive On
KeepAliveTimeout 15
MaxKeepAliveRequest 1000
* Fundamental para redes 3G.
Respuesta
Apache
23. @marcosesperon
Evitar peticiones a recursos externos
• Imágenes
• Frameworks y plugins de javascript
• Fuentes
* Si es necesario, usar preferentemente CDN’s (Content Distribution Networks).
Almacenar los recursos en nuestro servidor
24. @marcosesperon
Comprimir las peticiones con GZIP
Minimizar los bytes descargados
GET / HTTP/1.1
Accept-Encoding: gzip, deflate
Petición
HTTP/1.1 200 OK
Content-Encoding: gzip
Respuesta
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/javascript
Apache: mod_deflate
$HTTP_ACCEPT_ENCODING;
ob_start("ob_gzhandler");
PHP: ob_gzhandler
25. @marcosesperon
Ofrecer contenido cacheable
Minimizar los bytes descargados
$_SERVER['HTTP_IF_MODIFIED_SINCE']
...
$mtime = filemtime($_SERVER['SCRIPT_FILENAME']);
$gmdate_mod = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
if ($if_modified_since == $gmdate_mod) {
header("HTTP/1.0 304 Not Modified");
exit;
}
header("Last-Modified: $gmdate_mod");
header('Content-type: text/css');
header('Expires: ' . date('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
26. @marcosesperon
CSS y JS empaquetado
Minimizar los bytes descargados
<!doctype html>
<html>
<head>
<title>EDISA</title>
<link rel="stylesheet" href=”css.php?p=menu" />
</head>
<body>
…
...
<script src=”js.php?p=menu"></script>
</body>
</html>
Una única llamada por CSS y JS que devuelve lo necesario para cada módulo.
En ocasiones solamente se utiliza el 10% del código CSS
27. @marcosesperon
Cachear los recursos en el cliente
APP
CACHE
SERVIDORHTTP
Minimizar los bytes descargados
CACHE MANIFEST
# v.130704-1
CACHE:
img/logo.png
img/menu/bg.png
css/fonts/fontawesome-webfont.eot
css/fonts/fontawesome-webfont.svg
css/fonts/fontawesome-webfont.ttf
css/fonts/fontawesome-webfont.woff
js/jquery.js
FALLBACK:
/ utils/offline.html
NETWORK:
*
offline.manifest
28. @marcosesperon
Estandarizar el código
Minimizar los bytes descargados
<img src="botoncerrar.png" alt="Cerrar" />
<img src="botonCerrar.png" alt="Cerrar" />
<img src=”BotonCerrar.png" alt="Cerrar" />
botoncerrar.png
* Si nuestro servidor es Windows,
29. @marcosesperon
Las cookies son kilos de más
Minimizar los bytes descargados
Puede que sean texto plano de pocos bytes, pero cada vez que se hace una
petición el navegador envía la información de las cookies que coincida con el
dominio solicitante.
SERVIDOR HTTP
• Eliminar cookies que no sean necesarias
• Reducir el tamaño de las cookies al mínimo
posible
30. @marcosesperon
Controlar los elementos del DOM
Generar un etiquetado eficiente
DOC
HTML
BODY
ELEM
ELEM ELEM
ELEM
ELEM ELEM
Es recomendable no superar los 1.000 elementos en el DOM
document.getElementsByTagName('*').length
31. @marcosesperon
Declarar el CSS en el head
Generar un etiquetado eficiente
<!doctype html>
<html>
<head>
<title>EDISA</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
...
</body>
<html>
El pintado de la página se bloquea hasta que se procesa el CSS.
Evitar los estilos en línea en el HTML.
32. @marcosesperon
Declarar el JS al final del body
Generar un etiquetado eficiente
<!doctype html>
<html>
<head>
<title>EDISA</title>
</head>
<body>
…
<script src="app.js"></script>
</body>
</html>
En el HEAD bloquea la petición hasta que procesa el JS.
Evitar los scripts en línea en el HTML.
33. @marcosesperon
Usar sprites para las imágenes
menu-libra.png
menu-libra-1.png
menu-libra-2.png
menu-libra-3.png
menu-libra-4.png
…
16 imágenes
16 conexiones
143 KB
1 imagen
1 conexión
30 KB
Optimizar los recursos utilizados
35. @marcosesperon
Reemplazar imágenes por CSS3
Optimizar los recursos utilizados
linear-gradient(to bottom, #feccb1 0%,#f17432 41%,#ea5507 65%,#fb955e 100%)
36. @marcosesperon
DataURI’s para imágenes de poco peso
Optimizar los recursos utilizados
data:image/
png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbW
FnZVJlYWR5ccllPAAAA1RJREFUeNq8V0tIVGEU/
u6d0ZlrDxxdWPSgpNC0B5YLh7CCDIKoNkatetHLjYFthIIKSmdhEq20jSaRGkptqk1ElCCKlkqZUKmp1Fg6M2rN6z7+zj93HK3V3
MG5Fw73cf57/u8/5zvnP7/AGEM8lyAIi19TLrgaBxgTcnUdhu5XntpOj/LiQXHZ5oPikX8mr24cau8YZDMqY9NBxppf9bGL1Q
+GuM6obRHGrzQIYs5e5xZ0jyno
+DKHgq35IIg5zkMn1hg1lgiAVO6Pga4e1NfcxuScjEBYhbTcgc5nLQEeESPGrAkAELjrCp2FKF2Rh9k5PxyShdypxTyfbA/
w4EJWAE1VI3GU1cQmTxgAzwiN/hSsqWTBCllDwldiHhBF9HS9R2tDPVSbA2EQEEE0DwAjnuU6C/
Dk82WUPRSQFhwBEywmAqBIh+getOg0DmkpYDDRA5wDKqIJRxYUVYmUQ1MBvHnRGwu7QtkgmEpCikHRwV2Uh/
orT0dzs4AirigLSa9qChJ1QWIAeB3gP0cnVRSTPcA58Lzlpc47gQNQ6CaYy4GSYyWxEGg8BGZ6QK//
C5VfUTWzQyBGXD8fAlWRza0DIrGvpa5Vjzp5QTW7Dsi0Fx8+fRxqmF5IQkE/
paJmCoCUc1UNffmb12NHBmC71gycf4yCnbuxaW0mSNf/f1+4lE2p5eyNupq7ba
+Zlz50UTPqL1vJmMvBvo4OMg994zoac4ePTUZTarfapCtH9hej8zsgtV+FlDFL5PMi
+OEROieAo6Sz2qUKPjYZIZDs9lTMqCJmPAHkPq1C6DfVAD+Q138LU9SO+kgH3VtSMppSTn588yiUdiS0eC1NX4FI0/
FMHPPIVJ4FQwszRMJQWMavKQ8CgoT+A+WwTtIK3MC77HJoIRk/
p7y0RRvjtREPaF73RNPwp76T2duK0LvHhe59tZFiaKV8TJUDIB287vEmxDbqOHv8ODegZXTbeMnV8DY9c3X6qg35sNp0r
imhINyjH+Gb/
uGrqzxTTJ9GSP7EY9sIAJ5aGRxEafnNiqx12cdFiyXWkEyOD7e23bteG53cw9uEpQaAaJFJJ8kicfBjWlTNa6KXhFgB3/
wpORkAEC0y9miqzTOOx5yfC4N85UaO538FGACcGdhVhFsFYQAAAABJRU5ErkJggg==
37. @marcosesperon
Obtener el JS bajo demanda
Optimizar los recursos utilizados
if(typeof calculadora == 'undefined') {
load('calculadora.js').thenRun(function () {
var c = new app.calculadora();
});
} else {
var c = new app.calculadora();
};
https://github.com/chriso/load.js
38. @marcosesperon
Optimizar nuestro Javascript
Reducir interacciones con el DOM
for(i = 0; i < array.length; i++) {
document.getElementById('test').innerHTML += array[i];
};
v_arts = document.querySelectorAll('.articulo');
Cachear elementos del DOM
var f = $('.filas');
var f = document.querySelectorAll('.filas');
Usar métodos nativos
No quedarse en jQuery