リサイズイベントのパフォーマンスチューニング
リサイズイベントで、所定の処理を再実行したり、レイアウト調整(Canvasのサイズ変更など)を行う。
私自身も頻繁に実装しますし、従来から存在するリサイズイベントですが、意図せず短期間に繰り返し(過剰に)実行されるケースが多々あります。
処理内容が低負荷であれば、繰り返し実行されても差し支えない(気づかない)ですが、
高負荷の場合(特にPCと比較して非力なモバイル端末)は、パフォーマンス低下の原因になり兼ねません。
この問題を解決するアプローチとして、従来のコードに少し手を加えるだけで不要な処理をキャンセルし、パフォーマンスを向上させるTipsをご紹介します。
ちなみにリサイズイベントは、スマホ/タブレット端末の向き(縦向き=ポートレート or 横向き=ランドスケープ)を変更した場合でも発生しています。
通常のリサイズイベント
通常、リサイズイベント実装は下記のようなコードになると思います。
window.addEventListener( 'resize', function() { // リサイズ時に行う処理 }, false );
過剰発生対策のリサイズイベント
キューを発行して指定ミリ秒後に実行させる事で、過剰に発生した場合は直前のイベントをキャンセル(上書き)します。
こうする事で最後のリサイズイベントのみ実行する事が可能になり、必要最小限の負荷で済みます。
var queue = null, // キューをストック wait = 300; // 0.3秒後に実行の場合 window.addEventListener( 'resize', function() { // イベント発生の都度、キューをキャンセル clearTimeout( queue ); // waitで指定したミリ秒後に所定の処理を実行 // 経過前に再度イベントが発生した場合 // キューをキャンセルして再カウント queue = setTimeout(function() { // リサイズ時に行う処理 }, wait ); }, false );
実用例
HTML5で追加されたCanvas要素はサイズ(横幅・高さ)設定が必須ですが、
パーセント指定に対応しておらず、ピクセル指定のみ対応といった問題があります。
レスポンシブWebデザインを始め、Canvasの表示サイズが可変となる場合、ピクセル指定でコンテナ(領域)内で
100%表示を実現するには、JSでコンテナサイズを取得してCanvasへサイズ設定する方法がポピュラーでしょう。
下記コードは、リサイズイベントの過剰発生対策とCanvasの100%表示(リサイズ対応)を組み合わせた例です。
HTML
<div id="canvasContainer"> <canvas id="canvas"></canvas> </div>
JavaScript
window.addEventListener( 'load', function() { var container = document.getElementById( 'canvasContainer' ), canvas = document.getElementById( 'canvas' ), queue = null, wait = 300; // ページ読込時にCanvasサイズ設定 setCanvasSize(); // リサイズ時にCanvasサイズを再設定 window.addEventListener( 'resize', function() { clearTimeout( queue ); queue = setTimeout(function() { setCanvasSize(); }, wait ); }, false ); // Canvasサイズをコンテナの100%に function setCanvasSize() { canvas.width = container.offsetWidth; canvas.height = container.offsetHeight; } }, false );