6

序文

私は JavaScript でプログラミングを始めたばかりで、現在、この趣味の Web サイト プロジェクトに取り組んでいます。このサイトは、左または右に「パン」できる製品画像で満たされたページを表示することになっています。各「ページ」には約 24 枚の中サイズの写真が含まれており、1 ページでほぼ画面いっぱいに表示されます。ユーザーが次のページを見ることを選択した場合、クリックして左にドラッグし (たとえば)、新しいページ (AJAX スクリプトによって動的に読み込まれる) がビューにスライドするようにする必要があります。

問題

これには、私のJavaScriptが、これらの言及されたページのうち2つを同期的に画面の幅で「スライド」する必要があります。これにより、フレームレートが非常に低くなります。Firefox と Opera は少し遅れますが、Chrome は特に悪いです: アニメーションの 1 フレームに約 100 ミリ秒なので、アニメーションが非常に「ラグ」に見えます。

私はjQueryを使用していませんし、jQueryや他のライブラリを使用して「自分のために仕事をする」こともしたくありません。少なくとも、私がやろうとしていることは、数行の自己記述コードでは実行できないことを確実に知るまでは。

これまでのところ、DOM を操作する特定の方法がパフォーマンスの低下を引き起こしていることがわかりました。ルーチンは次のようになります。

function slide() {
  this.t = new Date().getTime() - this.msBase;

  if( this.t > this.msDura ) {
    this.callB.call(this.ref,this.nFrames);
    return false;
  }

  //calculating the displacement of both elements

  this.pxProg = this.tRatio * this.t;

  this.eA.style.left = ( this.pxBaseA + this.pxProg ) + 'px';
  this.eB.style.left = (this.pxBaseB + this.pxProg) + 'px';

  if ( bRequestAnimationStatus )
    requestAnimationFrame( slide.bind(this) );
  else
    window.setTimeout( slide.bind(this), 16 );

  this.nFrames++;

}

//starting an animation

slide.call({
  eA:      theMiddlePage,
  eB:      neighboorPage, 
  callB:   theCallback,
  msBase:  new Date().getTime(),
  msDura:  400,
  tRatio:  ((0-pxScreenWidth)/400),
  nFrames: 0,
  ref:     myObject,
  pxBaseA: theMiddlePage.offsetLeft,
  pxBaseB: neighboorPage.offsetLeft
});

質問

AJAX スクリプトが各ページにロードする画像を減らすと、アニメーションがはるかに高速になることに気付きました。別々の画像は、私が予想していたよりも多くのオーバーヘッドを生み出しているようです.

これを行う別の方法はありますか?

4

1 に答える 1

1

JavaScript ソリューション

OK、これを高速化するには 2 つの方法があります。

まず、要素のスタイルを変更すると、ブラウザーにページの再レンダリングを強制します。これをリペイントと呼びます。特定の変更は、ページのジオメトリの再計算も強制します。これをリフローと呼びます。リフローは、常にその直後に再描画をトリガーします。要素が増えるとパフォーマンスが低下するのは、各要素を更新するたびに少なくとも再描画がトリガーされるためだと思います。1 つの要素で複数のスタイルを変更する場合に通常推奨されるのは、クラスを追加または削除して一度にすべてを行うか、要素を非表示にし、操作を行ってから表示することです。これは、2 回の再描画のみを意味します (場合によってはリフローします)。

この特定のケースでは、反復ごとに各アイテムを 1 回しか操作していないため、おそらくすでにうまくいっているようです。

第 2 に、requestAnimationFrame() は canvas 要素でアニメーションを実行するのには適していますが、DOM 要素ではパフォーマンスがやや悪いようです。Chrome のプロファイラーでページを開いて、ハングアップした場所を正確に確認します。setTimeout() を使用して JUST を試して、それが当てはまるかどうかを確認してください。繰り返しますが、プロファイラーはハングアップがどこにあるかを教えてくれます。requestAnimationFrame() の方が優れているはずですが、これを検証してください。以前、裏目に出たことがあります。

本当の解決策

回避できる場合は、JavaScript でこれを行わないでください。CSS トランジションと変換を使用して、各アニメーション要素の onTransitionEnd イベント ハンドラーとして登録された JavaScript 関数でアニメーションを実行します。ブラウザーにネイティブにこの処理をさせると、ほとんどの場合、誰でも作成できる JS コードよりも高速になります。

唯一の問題は、CSS3 アニメーションが新しいブラウザーでしかサポートされていないことです。あなた自身の教化のために、このようにしてください。実際の実用的なアプリケーションについては、ライブラリに委任してください。優れたライブラリは、可能であればそれをネイティブで行い、古いブラウザーでは JS で行う最善の方法にフォールバックします。

このことについて読むための良いリンク: http://www.html5rocks.com/en/tutorials/speed/html5/

于 2013-03-20T03:49:13.077 に答える