在Android上缓慢的Javascript触摸事件

one*_*elf 10 javascript mobile android touch

我正在尝试编写一个简单的基于html的绘图应用程序(附带的独立简化代码).我在以下设备上测试了这个:

  • iPad 1和2:效果很好
  • 华硕T101运行Windows:效果很好
  • 三星Galaxy Tab:非常缓慢和零散 - 无法使用.
  • 联想IdeaPad K1:非常缓慢和零散 - 无法使用.
  • 华硕Transformer Prime:与iPad相比显着滞后 - 接近可用.

华硕平板电脑正在运行ICS,其他安卓平板电脑正在运行3.1和3.2.我使用现有的Android浏览器测试过.我也尝试过Android Chrome测试版,但情况更糟.

这是一个演示此问题的视频:http://www.youtube.com/watch?v = Wlh94FBNVEQ

我的问题是为什么Android平板电脑这么慢?我做错了什么或者它是Android操作系统或浏览器的继承问题,还是我可以在我的代码中做些什么呢?

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>
Run Code Online (Sandbox Code Playgroud)

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 });
});
Run Code Online (Sandbox Code Playgroud)

mrb*_*000 8

查看代码,您应该进行一些优化.蝙蝠,永远不要使用jQuery的$ .each()来做循环.此外,每当您轮询某事物的左侧,顶部,宽度或高度时,您将导致浏览器停止正在进行的操作,重新绘制整个屏幕并获取最准确的值.将这些值存储在javascript变量中.使用谷歌浏览器的时间轴功能来查找和消除不必要的油漆和回流.以下是一些有用的链接:

Nicholas C. Zakas给你一些关于避免回流的提示. http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html

以下是Zakas向Google程序员介绍他的演示文稿: http ://www.youtube.com/watch?v = mHtdZgou0qU

Paul Irish在你面前加速了一个缓慢的JavaScript: http ://www.youtube.com/watch?v = Vp524yo0p44 请注意,在该视频发布时,时间轴是Chrome中的测试版功能.它现在是Chrome 20的标准配置.如果您没有看到它,请更新您的Chrome.

不幸的是......即使有了所有这些优化......截至2012年......

最安静的设备仍然很慢:-(

触摸事件的触发速度不如Apple设备那么快,因为Apple设备的硬件比运行Android操作系统的大多数设备都要好.有快速的Android平板电脑和手机,但它们的成本通常与Apple设备一样多 - 可能是因为它们有类似的硬件规格.除了主CPU之外,Apple设备还有特殊的浮点数学芯片和图形芯片.许多Android设备不包含那些额外的芯片,而是拥有虚拟浮点数学芯片.

为了适应速度较慢的Android设备,您唯一能做的就是检测它们并优雅地降低用户体验.例如,我创建了一个可拖动的产品轮播.对于Androids,我消除了拖动选项并添加了可点击的滚动箭头,这些箭头一次将轮播向左或向右移动一组固定的像素.