0

CSS で複数の html 要素の位置を変更すると、iOS html5 webapp で大きなパフォーマンスの問題が発生します。また、要素を手動で移動したいと思います。アニメーションを停止することができないため、CSS 変換を使用したくありません (非常に応答性の高いゲームを作成しています)。

私の例は、Android のデスクトップ ブラウザー (chrome、firefox など) で正常に動作します。しかし、iPad 2 と iPhone 4S (両方とも iOS 5.1 を実行) では非常に遅いです。Phonegap アプリで html5 コードを実行すると、ブラウザーで直接実行するよりも優れていますが、それでも低速です。

物事を改善するために何を提案しますか?
編集可能な例
フルスクリーンの例

4

2 に答える 2

1

まず第一に、遅くないものが必要な場合は、できる限りすべての jQuery 呼び出しを避けてください。

コードを(非常に迅速に)書き直す方法は次のとおりです。

// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

var canvas = document.getElementById('canvas-test');
    canvas.height = 500;
    canvas.width = 500;
    var context = canvas.getContext('2d');

    // in this example, the fillstyle is always the same. no need to change it at every loop
    context.fillStyle = "#FF0000";


var balls = [];
var ballcanvas = [];
var ballctx = [];

// create 30 balls in canvases
var eDivBody = document.getElementById('divbody');
for (var i = 0; i < 30; i++){
    balls[i] = {
        x : 250,
        y : 100 + i * 2,
        dx : 3, // direction
    };

    // create the canvas
    var eBall = document.createElement('canvas');
    eBall.id = 'ballcanvas' + i;
    eBall.width = 75;
    eBall.height = 75;
    eDivBody.appendChild(eBall);

    // some css
    // no need for jQuery
    eBall.style.position = "absolute";
    eBall.style.left = balls[i].x + "px";
    eBall.style.top = balls[i].y + "px";
    eBall.style.backgroundColor = "#000000";

    // associate the element to the ball, no need to go threw the DOM after
balls[i].element = eBall;
}


var ball_test = {
    x : 250,
    y : 300,
    dx : 3 // direction
};


function loop(ball_test, balls, canvas, context, ballcanvas, ballctx){
    //change of direction on the sides
    if (ball_test.x > 400 || ball_test.x < 100)
        ball_test.dx *= -1;
    // movement
    ball_test.x += ball_test.dx;

    // the same for balls in canvases
    // never use array.legth in a loop condition. put it in a variable then compare. 
    for (var i = 0, j = balls.length; i < j; i++){
        // balls are following the test ball, no need to re-check the bounds
        // we take the test ball direction
        balls[i].dx =  ball_test.dx;

        //movement   
        balls[i].x += balls[i].dx;
        // change left style - No need for jQuery
        balls[i].element.style.left = balls[i].x + "px";
    }

    // display ball_test
    displayBallTest(ball_test, canvas, context);

    // Prefer the use of requestAnimationFrame
    requestAnimFrame(function(){
        loop(ball_test, balls, canvas, context, ballcanvas, ballctx);
    });
};

// no need to recalculate Math.PI * 2 for every loop.
// do it just the first time then use the value
var pi2 = Math.PI * 2;

function displayBallTest(ball, canvas, context){
    // clear canvas    
    // you don't need to clear all the canvas, just the zone where you now the ball is.
    // must need some calculation to be the most efficient possible
    context.clearRect(ball.x - 50 , ball.y  - 50, 100, 100);

    context.beginPath();
    context.arc(ball.x, ball.y, 40, 0, pi2 );
    context.fill();
};

// start main loop
loop(ball_test, balls, canvas, context, ballcanvas, ballctx);

コードにコメントしましたが、これが私がしたことです:

  • jQueryを完全に避けます。コンテンツの最後にスクリプトを配置しないことを選択した場合の準備を除いて、必要はありません
  • 可能な場合は requestAnimationFrame を使用する
  • グローバルな場合の値の再計算またはリセットの回避 (Math.PI*2 、 context.fillStyle ... )
  • .length if for ループ条件の使用を避ける

しかし、あなたの問題は、コンテンツをメインのキャンバスに描画する代わりに、30 個のキャンバス要素を移動したいという事実から来ていると思います。Canvas Drawing を使用すると、iOS は高速であることが知られています。私にとっては、DOM 要素を移動する代わりにメイン キャンバスに描画することを選択すると、パフォーマンスの問題が解決されます。

于 2012-07-25T14:41:26.753 に答える
0

できることの 1 つは、セレクターを毎回実行する代わりにキャッシュすることです。

   // some css            
    $('#ballcanvas' + i).css("position", "absolute");
    $('#ballcanvas' + i).css("left", balls[i].x + "px");
    $('#ballcanvas' + i).css("top", balls[i].y + "px");
    $('#ballcanvas' + i).css("background-color", "#000000");

次のようになります。

var thisBall = $('#ballcanvas' + i)
thisBall.css("position", "absolute");
... rest of your code ....

document.getElementById余談: Jquery が既にあるのに、わざわざ を使用する必要はありません$

于 2012-07-25T13:50:53.773 に答える