2012-10-19 5 views
6

以下のスクリプトでは、深刻な視覚的なエラー&の問題が発生しています。最大の問題は、オブジェクトのアニメーションがIE9では非常にぎこちないようになってきていますが、Firefoxではますます厄介なことです。JS/jQueryのパフォーマンスが悪い(特にIE9とFirefoxの場合)

最近までかなり速いですが、複雑さが減速していることが懸念されます。奇妙なことに、Sunspider benchmarkはFirefoxよりもIE9インスタンスで高速に動作します。

(大きなコレクションの一部です***)スクリプト:

  1. チェックし ゲームを通じてユーザー進行のHTML5セッションストレージログ。
  2. ステージによっては、crSplineを使用して2つの ポイントの間でオブジェクトをアニメーション化します。
  3. 最後に、それはcolorboxを経由してポップアップウィンドウをロード
  4. などscrollLeftを経由して、ブラウザウィンドウが大きなキャンバス全体にオブジェクト を以下のようにします。
  5. このボックスを閉じると、それに応じてユーザーの進行ログが増分され、オブジェクトが再び移動します。

私のコードに明白なスピードの改善がありますか?繰り返しの公正なビットが、どのように私はそれを減らすことができますか?実行中の無限ループがありますか? JSの低速ポイントをプロファイルするために使用できるソフトウェアはありますか?それは、公平なビットより多くのテストの後 :

***


UPDATE(私は他のJSファイルやHTMLを提供することはできませんが、私は問題として、このスクリプトを確認しています)スクロール・レフトを介してウインドウ内のオブジェクトに続くステップ・アニメート・ファンクションがぎこちないアニメーションを引き起こしているようです。それを削除すると、かなり改善されます。

しかしこれは実行可能な長期的な解決策ではありません。迅速な修正は、完了時にフォロー機能を呼び出すことですが、これは、特にオブジェクトが長距離移動する場合に、エンドユーザーにはあまりスムーズではありません。

私はステップの機能をより「より遅く」/より効率的に変更するにはどうしたらよいですか?私は、ジャーキネスが、ミリ秒ごとにオブジェクトを追跡するために利用可能なすべてのリソースを使用していることに起因すると思われます。

(function ($) { 

    sessionStorage.gameMainStage = 0 

    moveShip = function() { 

    switch (sessionStorage.gameMainStage) 

{ 
    case '1': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[715, 425], [582, 524], [556, 646], [722, 688], [963, 629], [1143, 467]]) },{ 
     duration: 10000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 
      complete: function() { 
      $.colorbox({href:"dialog-1.html", width:"737px", height:"474px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 

    case '2': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[1143, 467], [1343, 667], [1443, 367], [1243, 167], [1499, 285]]) }, 
     { 
      duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 
      complete: function() { 
      $.colorbox({href:"dialog-2", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 

     } 
    ); 
    break; 

    case '3': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[1499, 285], [1922, 423]]) }, 
     { 
      duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 
      complete: function() { 
      $.colorbox({href:"dialog-3.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 

     } 
    ); 
    break; 

    case '4': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[1922, 423], [2216, 578]]) },{ 
     duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"game-1.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 

    case '5': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[2216, 578], [2769, 904]]) },{ 
     duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"dialog-4.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 

    case '6': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[2769, 904], [3263, 903]]) },{ 
     duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"dialog-5.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 

    case '7': 
    $.colorbox({href:"game-2.html", width:"500px", height:"600px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
    break; 

    case '8': 
    $.colorbox({href:"dialog-6.html", width:"737px", height:"567px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
    break; 

    case '9': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[3263, 903], [4141, 820]]) },{ 
     duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"dialog-7.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 

    case '10': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[4141, 820], [4568, 949], [4447, 1175]]) },{ 
     duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"dialog-8.html", width:"737px", height:"434px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 

    case '11': 
    $.colorbox({href:"dialog-9.html", width:"737px", height:"567px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
    break; 

    case '12': 
    $("#object").animate(
     { crSpline: $.crSpline.buildSequence([[4447, 1175], [4701, 1124], [4816, 822]]) },{ 
     duration: 5000, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"dialog-10.html", width:"900px", height:"687px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
    break; 
} 

}; 

})(jQuery); 
+0

ベンチマークのページのちょっとしたメモ: 'このベンチマークは、DOMやその他のブラウザAPIではなく、中心的なJavaScript言語のみをテストします。あなたのカラーボックスやアニメーションはほとんど純粋なDOMです。 –

答えて

5

私はwindow.resizeとwindow.scrollにフック単一ページのアプリケーションでこの問題が発生しました。 IEでは他のブラウザよりもずっと遅いようでした。

最初に私が気づいたのは、IE(特定のバージョン8)では、window.scrollや.resizeに添付されたコールバックがChromeやFFよりも何度も起動するように見えました。またはスクロール)。したがって、添付されたコールバックは、クロームよりも相対コストに何倍も多く呼び出されます。

私たちは、最小限のコールバック内で何が行われているのかを最小限に抑えることで、私たちの問題を解決しました。そして、私たちが得た主な利益はjQueryセレクタを取り除くことでした。したがって、あなたの場合、コールバック関数にはvar mover = $( '#object')があります。イベントが発生するたびに、IEはオブジェクトを見つけてjQueryでラップしようとします。コールバックし、キャッシュされたオブジェクトを使用します。私たちのケースでは、それは大小の順序でパフォーマンスが改善されました。パフォーマンスの問題が発生していなくても(それは不必要に繰り返された操作でした)、それは良いことのようでした。

case '10':{ 
    //caching myObject once and then use it afterwards 
    var myObject = $("#object"), 
     $window = $(window); 

    myObject.animate(
     { 
     crSpline: $.crSpline.buildSequence([[4141, 820], [4568, 949], [4447, 1175]]) }, 
     { 
     duration: 5000, 
      step: function() { 
      var mover = myObject, //no need to refetch the object    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $window.scrollLeft(posX - $window.width()/2) 
      .scrollTop(posY - $window.height()/2); 
      }, 

      complete: function() { 
      $.colorbox({href:"dialog-8.html", width:"737px", height:"434px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
      } 
     } 
    ); 
} 

PS:

は、ですから、例えばケース8には、のようなものを持っているまた、私はあなたのアプリケーションの意味のわからない、しかし、あなたはPOSXを追跡するために、独自のロジックを追加する必要があるかもしれませんし、私は、セレクタのコストが(私の場合のように)問題を引き起こしていることを確認するために、私が言及した手順を実行します。

0

あなたはIEがIE9ブラウザモードとIE9のドキュメントモード、すなわち癖や互換モードとは異なるモードで動作するようにしようとしていないかどうかを確認するためにチェックするために試みることができます。それはデフォルトのものを使用するように強制しようとしている場合。 Force IE compatibility mode off using tags

11

私が使用しているライブラリが古すぎるため、素晴らしいパフォーマンスが期待できません。私は

(あなたが各スイッチの場合の設定引数を持つ関数を使用することもできましたが、それがパフォーマンスに大きな影響はありませんリファクタリングの問題だということを除いて)あなたのコードで間違った何も表示されません

CrSplineは左と上のCSSプロパティを使用します。

あなたは、ハードウェアアクセラレーションを活用するCSS 2D変換に見たいと思うかもしれません:

使用-webkit/moz/ms-transform: translateX(-1000px) translateY(200px) 代わりのleft: -1000px; top: 200px;

私はあなたが非常に簡単にその方向に向けてcrsplineライブラリにいくつかのコードを書き換えることができると思います。

さらに最新の「スプライン」ライブラリを探すこともできます。

別のポイント:crSplineはrequestAnimationFrame機能を使用していないようです。 JQueryのanimateメソッドもそうではありません。 TweenLite/TweenMaxライブラリをご覧になることをお勧めします。http://www.greensock.com/v12/

お疲れ様でした!

+0

CSS 2D変換はハードウェアアクセラレーションが保証されていません。ハードウェアアクセラレーションを確実に取得するには、translate3d(0、0、0)を使用する必要があります。これはブラウザにZ軸を使用するように指示します(GPUでキックされます)。それでも、上と左を使用してハードウェアアクセラレーションを得ることができます。 http://www.html5rocks.com/en/tutorials/speed/html5/ – skyline3000

+1

True-translate3dはハードウェアアクセラレーションが強化され、パフォーマンスが大幅に向上しますが、あまりにも多くの要素をあまりにも頻繁に呼び出すと、アクセラレーションされたリソースがあまりにも多く消費されます。 2d変換は通常加速されませんが、値を変更してもアニメーションで最大の性能を発揮する再計算や再計算が行われないため、パフォーマンスは大幅に向上します。 – nxtwrld

2

まず、あなたは、アニメーションのための関数を作成してコードを最適化する必要があります(テストしていないものでなければなら作品):

このようなあなたのコード内で呼び出され
function animateMyObjet(duration,sequence,callback) 
{ 
    $("#object").animate(
    { crSpline: $.crSpline.buildSequence(sequence), 
     { 
      duration: duration, 
      step: function() { 
      var mover = $('#object'),    
      posX = mover.position().left; 
      posY = mover.position().top; 

      $(window) 
      .scrollLeft(posX - $(window).width()/2) 
      .scrollTop(posY - $(window).height()/2); 
      }, 
      complete: function() { 
      callback(); 
     } 
    } 
} 

switch (sessionStorage.gameMainStage) 
{ 
    case '1': animateMyObjet(10000,[[715, 425], [582, 524], [556, 646], [722, 688], [963, 629], [1143, 467]],                     
function() { 
$.colorbox({href:"dialog-1.html", width:"737px", height:"474px", iframe: true, overlayClose: false, escKey: false, close: ""}); 
     break; 

case '2' : ... 

} 

第二に、私は数週間前にウェブページの要素の数がIE9のパフォーマンスに影響を与えていることを発見しました。スクロール可能なコンテナのために隠された要素のように、必要のないすべての要素を非表示にしてください。

時には、画面の表示要素の数がアニメーションのパフォーマンスに影響を与えていることがあります。テストでは、ブラウザのウィンドウサイズを縮小し、アニメーションを再生してみてください。私はアニメーションがよりスムーズになることを確信しています。

これらのアドバイスがお役に立てば幸いです。あなたの問題を把握したら、最終的なソリューションを公開することを忘れないでください!

そして最後に、IE9のパフォーマンスの問題についての潜在的関連のトピックを確認してください。IE9 : Always small CPU utilization on my web site

+0

Web DeveloperツールバーのJavascriptプロファイリングに関する関連トピックのリンクは本当に役に立ちます。ありがとうございます。 –

0

あなたのイベントハンドラがあまりにも頻繁に呼び出されているのを見ていると、タイムアウトが現在設定されていない場合、イベントハンドラはタイムアウトを設定してタイムアウト機能にムーブメントを持っているだけです。

関連する問題