2012-03-29 8 views
9

私は簡単なhtmlベースの描画アプリケーション(スタンドアロンの簡略化されたコードを添付)を書こうとしています。Androidで遅いJavascriptタッチイベント

  • のiPad 1および2:Windowsのを実行している偉大な
  • ASUS T101作品:私は、次のデバイス上でこれをテストしてみた作品の偉大
  • サムスンギャラクシータブ:非常に遅いと斑状 - 使用できません。
  • Lenovo IdeaPad K1:非常に遅く、不安定です。使用できません。
  • Asusトランスフォーマープライム:iPadとの比較が目立つ - 利用可能に近い。

AsusタブレットはICSを実行していて、他のアンドロイドタブレットは3.1と3.2で動作しています。 Androidのブラウザを使ってテストしました。私もAndroid Chrome Betaを試しましたが、それはさらに悪化しました。

ここでの問題を示してビデオだ:Androidタブレットはとても遅いですなぜhttp://www.youtube.com/watch?v=Wlh94FBNVEQ

私の質問はありますか?間違ったことをやっているのですか、それとも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 }); 
}); 

答えて

8

コードを見ると、最適化を行う必要があります。バットからすぐに、jQueryの$ .each()を使ってループを実行しないでください。また、何かの左、上、幅、高さをポーリングするたびに、ブラウザーが行っていることをやめて画面全体を再描画し、最も正確な値を取得します。代わりにこれらの値をjavascript変数に格納します。不要な塗料やリフローを見つけて除去するには、Google Chromeのタイムライン機能を使用します。役に立つリンクがあります:

Nicholas C. Zakasはリフローを避けるためのヒントを与えています。ここで http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html

、Googleのプログラマーに彼のプレゼンテーションを行うZakasです: http://www.youtube.com/watch?v=mHtdZgou0qU

ポール・アイリッシュは、あなたの目の前でゆっくりとJavaScriptを高速化: http://www.youtube.com/watch?v=Vp524yo0p44 注意してください、時そのビデオはタイムラインがChromeのベータ版の機能でした現在はChrome 20の標準です。表示されない場合は、Chromeを更新してください。 2012年のようであっても、これらすべての最適化と残念ながら

... ... ...

ほとんどのAndroid搭載端末では、STILLタッチイベントをとして急速に発生しません

SLOW :-(ARE AppleのデバイスはAppleのOSが動作するほとんどのデバイスよりも優れたハードウェアしか持っていないため、高速のAndroidタブレットと携帯電話がありますが、Appleデバイスと同じくらいのコストがかかりますAppleのデバイスには、メインCPUに加えて特別な浮動小数点数学チップとグラフィックスチップがあります。多くのAndroidデバイスには、これらのext raチップではなく、仮想浮動小数点数学チップを持っています。

低速のAndroid搭載端末に対応するためにできるのは、Android搭載端末を検出して正常に使用できなくなることだけです。たとえば、私はドラッグ可能な製品カルーセルを作りました。アンドロイドについては、ドラッグオプションを削除し、クリック可能なスクロール矢印を追加して、カルーセルを固定したピクセルのセットを一度に左または右に移動させます。

+0

コレクションを列挙するjQueryの$ .each()で何が問題になっていますか? – simbolo

+0

domReadyやpageResizeのようにまれに起こることがある場合は、$ .each()に何も問題はありません。しかし、アニメーションを行っている場合、$ .each()は遅すぎます。これはエンクロージャーなので、オブジェクトを設定し、いくつかのクラッドを行い、次にオブジェクトを削除する必要があります。 Zakas氏は、Googleのプログラマーへのプレゼンテーションでよく説明しています(上記参照)。 – mrbinky3000

+0

ありがとう、私はいくつかのjsPerfの結果(http://jsperf.com/jquery-each-vs-regular-for-vs-optimized-for-vs-foreach/3)を調べたので、$ .eachは次のように見えます。ネイティブJavaScriptメソッドを使用するよりもはるかに時間がかかります。 – simbolo

3

どこで、なぜあなたのコードは不採算である本当に知っている唯一の方法は、それをプロファイリングすることです。

Chromeモバイルではconnect to the WebKit inspector from your desktopを使用できるため、Chromeのデベロッパーツールで慣れ親しんだ素晴らしいデバッグツールにアクセスできます。

Chromeモバイルに接続したら、スクリプトをプロファイルして、どの機能がCPU時間を詰まらせるかを確認します。次に、それらの機能を最適化する方法を理解することができます。

関連する問題