Slow eventos de toque de Javascript en Android

Estoy tratando de escribir una simple aplicación de dibujo basado en html (código simplificado autónomo adjunto abajo). He probado esto en los siguientes dispositivos:

  • IPad 1 y 2 : Funciona muy bien
  • ASUS T101 corriendo Windows : Funciona muy bien
  • Samsung Galaxy Tab : Extremadamente lento y desigual – inutilizable.
  • Lenovo IdeaPad K1 : Extremadamente lento y desigual – inutilizable.
  • Asus Transformer Prime : El retraso notable compara con el iPad – cerca de usable.

La tableta de Asus está ejecutando ICS, las otras tabletas android están funcionando 3.1 y 3.2. He probado con el navegador de acciones Android. También probé el Android Chrome Beta, pero eso fue aún peor.

Aquí hay un video que demuestra el problema: http://www.youtube.com/watch?v=Wlh94FBNVEQ

Mis preguntas es ¿por qué las tabletas Android son tan lentas? ¿Estoy haciendo algo mal o es un problema de herencia con Android OS o navegador, o hay algo que puedo hacer al respecto en mi código?

Multi.html:

<html> <body> <style media="screen"> canvas { border: 1px solid #CCC; } </style> <canvas style="" id="draw" height="450" width="922"></canvas> <script class="jsbin" src="jquery.js"></script> <script src="multi.js"></script> </body> </html> 

Multi.js:

 var CanvasDrawr = function(options) { // grab canvas element var canvas = document.getElementById(options.id), ctxt = canvas.getContext("2d"); canvas.style.width = '100%' canvas.width = canvas.offsetWidth; canvas.style.width = ''; // set props from options, but the defaults are for the cool kids ctxt.lineWidth = options.size || Math.ceil(Math.random() * 35); ctxt.lineCap = options.lineCap || "round"; ctxt.pX = undefined; ctxt.pY = undefined; var lines = [,,]; var offset = $(canvas).offset(); var eventCount = 0; var self = { // Bind click events init: function() { // Set pX and pY from first click canvas.addEventListener('touchstart', self.preDraw, false); canvas.addEventListener('touchmove', self.draw, false); }, preDraw: function(event) { $.each(event.touches, function(i, touch) { var id = touch.identifier; lines[id] = { x : this.pageX - offset.left, y : this.pageY - offset.top, color : 'black' }; }); event.preventDefault(); }, draw: function(event) { var e = event, hmm = {}; eventCount += 1; $.each(event.touches, function(i, touch) { var id = touch.identifier, moveX = this.pageX - offset.left - lines[id].x, moveY = this.pageY - offset.top - lines[id].y; var ret = self.move(id, moveX, moveY); lines[id].x = ret.x; lines[id].y = ret.y; }); event.preventDefault(); }, move: function(i, changeX, changeY) { ctxt.strokeStyle = lines[i].color; ctxt.beginPath(); ctxt.moveTo(lines[i].x, lines[i].y); ctxt.lineTo(lines[i].x + changeX, lines[i].y + changeY); ctxt.stroke(); ctxt.closePath(); return { x: lines[i].x + changeX, y: lines[i].y + changeY }; }, }; return self.init(); }; $(function(){ var drawr = new CanvasDrawr({ id: "draw", size: 5 }); }); 

Mirando su código, usted debe hacer algo de optimización. Justo al revés, nunca utilice $ .each () de jQuery para hacer bucles. Además, cada vez que consulta la izquierda, la parte superior, la anchura o la altura de algo, está haciendo que el navegador deje de hacer lo que está haciendo, repintar toda la pantalla y buscar los valores más precisos. Almacene estos valores en variables javascript en su lugar. Utilice la función de cronograma de google chrome para encontrar y eliminar las pinturas y los reflujos no necesarios. Aquí hay algunos enlaces útiles:

Nicholas C. Zakas te da algunas sugerencias para evitar reflujos. http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html

Aquí está Zakas dando su presentación a los programadores de Google: http://www.youtube.com/watch?v=mHtdZgou0qU

Paul Irish Acelera un lento JavaScript delante de tus ojos: http://www.youtube.com/watch?v=Vp524yo0p44 Tenga en cuenta, en el momento de ese video, que la línea de tiempo era una característica beta de Chrome. Ahora es estándar en Chrome 20. Si no lo ves, actualiza Chrome.

Desafortunadamente … Incluso con todas estas optimizaciones … a partir de 2012 …

LA MAYORÍA DE LOS DISPOSITIVOS ANDROIDES SON STILL SLOW 🙁

Los eventos táctiles no se disparan tan rápido como lo hacen en los dispositivos de Apple, porque los dispositivos de Apple sólo tienen un mejor hardware que la mayoría de los dispositivos que ejecutan el sistema operativo de Android. Hay tabletas y teléfonos Android rápidos por ahí, pero por lo general cuestan tanto como los dispositivos de Apple, probablemente porque tienen especificaciones de hardware similares. Los dispositivos de Apple tienen chips especiales de viruta flotante y chips gráficos además de la CPU principal. Muchos dispositivos Android no contienen esos chips adicionales, sino que tienen chips virtuales de punto flotante.

Lo único que puede hacer para acomodar dispositivos Android más lentos es detectarlos y degradar graciosamente la experiencia del usuario. Por ejemplo, creé un carrusel de producto arrastrable. Para Androids, elimino la opción de arrastrar y añadir flechas de desplazamiento que mueven el carrusel a la izquierda oa la derecha un conjunto fijo de píxeles a la vez.

La única manera de saber realmente dónde y por qué su código es bajo rendimiento es perfilarlo.

Chrome Mobile te permite conectarte al inspector de WebKit desde tu escritorio , dándole acceso a las fantásticas herramientas de depuración a las que estás acostumbrado en las Herramientas para desarrolladores de Chrome.

Una vez que estés conectado a Chrome Mobile, perfila tu secuencia de comandos y ver qué funciones están mascando el tiempo de CPU. A continuación, podrá empezar a averiguar cómo optimizar esas funciones.

  • Android requestFocusFromTouch muestra menú con el primer elemento resaltado
  • Animación de RecyclerView en el clic de artículo
  • Diferencia entre onSingleTapConfirmed y onSingleTapUp
  • Android - Detectar doble acceso y tripletap en vista
  • Android - overdraw diseño permite toque a través de LinearLayout
  • (Disposición de Android) Solución para colocar el botón en la parte superior de la imagen de forma irregular o obtener la detección de toque (zona de contacto) de área particular de la imagen?
  • Android 4 Chrome éxito problema de prueba en eventos de toque después de transformar CSS
  • Cómo interceptar eventos de contacto desde ViewPager.OnPageChangeListener
  • LibGDX - Obtener deslizar hacia arriba o deslizar derecha, etc?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.