Медленные сенсорные события Javascript на Android - PullRequest
9 голосов
/ 29 марта 2012

Я пытаюсь написать простое приложение для рисования на основе html (отдельный упрощенный код прилагается ниже). Я проверил это на следующих устройствах:

  • iPad 1 и 2 : отлично работает
  • ASUS T101 под управлением Windows : отлично работает
  • Samsung Galaxy Tab : чрезвычайно медленный и неоднородный - невозможно использовать.
  • Lenovo IdeaPad K1 : чрезвычайно медленный и неоднородный - невозможно использовать.
  • Asus Transformer Prime : Заметное отставание по сравнению с iPad - близко к удобству использования.

Планшет Asus работает под управлением ICS, остальные планшеты Android работают под управлением 3.1 и 3.2. Я тестировал с помощью стандартного браузера Android. Я также попробовал Android Chrome Beta, но это было еще хуже.

Вот видео, демонстрирующее проблему: http://www.youtube.com/watch?v=Wlh94FBNVEQ

Мои вопросы: почему планшеты Android так медленные? Я делаю что-то не так или это наследственная проблема с Android OS или браузером, или я могу что-то сделать в моем коде?

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 });
});

Ответы [ 2 ]

8 голосов
/ 12 июля 2012

Глядя на свой код, вы должны провести некоторую оптимизацию. Сразу же, никогда не используйте jQuery $ .each () для создания циклов. Кроме того, каждый раз, когда вы опрашиваете левую, верхнюю, ширину или высоту чего-либо, вы заставляете браузер останавливать свою работу, перекрашивать весь экран и получать наиболее точные значения. Вместо этого сохраните эти значения в переменных javascript. Используйте функцию временной шкалы Google Chrome, чтобы найти и устранить ненужные краски и краски. Вот несколько полезных ссылок:

Николас С. Закас дает вам несколько советов о том, как избежать перевоспитания. http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html

Вот Закас, делающий свою презентацию для программистов Google: http://www.youtube.com/watch?v=mHtdZgou0qU

Пол Ирландский Ускоряет медленный JavaScript на ваших глазах: http://www.youtube.com/watch?v=Vp524yo0p44 Обратите внимание, что во время этого видео временная шкала была бета-функцией в Chrome. Теперь это стандарт в Chrome 20. Если вы его не видите, обновите Chrome.

К сожалению ... Даже с учетом всех этих оптимизаций ... по состоянию на 2012 год ...

НАИБОЛЕЕ АНДРОИДНЫЕ УСТРОЙСТВА ЕЩЕ МЕДЛЕННО: - (

События касания срабатывают не так быстро, как на устройствах Apple, потому что устройства Apple просто имеют лучшее оборудование, чем большинство устройств с ОС Android. Существуют быстрые планшеты и телефоны на базе Android, но они обычно стоят столько же, сколько устройства Apple - возможно, потому, что у них схожие аппаратные характеристики. Устройства Apple имеют специальные математические чипы с плавающей точкой и графические чипы в дополнение к основному процессору. Многие устройства Android не содержат этих дополнительных чипов, вместо этого они имеют виртуальные математические чипы с плавающей точкой.

Единственное, что вы можете сделать, чтобы приспособиться к более медленным Android-устройствам, - это обнаружить их и изящно ухудшить пользовательский опыт. Например, я создал перетаскиваемую карусель продукта. Для Android я исключаю параметр перетаскивания и добавляю интерактивные стрелки прокрутки, которые перемещают карусель влево или вправо на фиксированный набор пикселей за раз.

3 голосов
/ 29 марта 2012

Единственный способ действительно узнать, где и почему ваш код работает хуже, - это профилировать его.

Chrome Mobile позволяет подключаться к инспектору WebKit с рабочего стола , предоставляя вам доступ кфантастические инструменты отладки, к которым вы привыкли в Chrome Developer Tools.

После подключения к Chrome Mobile профилируйте свой сценарий и посмотрите, какие функции загружают процессорное время.Тогда вы сможете начать понимать, как оптимизировать эти функции.

...