2012年9月4日

重い処理を軽くできるJavaScriptライブラリ作ってみた

追記: この記事のものは古くメンテナンスされていません。
CPU負荷をかけずにループ処理するJavaScriptライブラリは「CPU負荷を抑えて重い処理を軽くするJavaScriptライブラリ「chillout.js」 | 圧縮電子どうのこうの」を参照ください。

lazyIter.js

lazyIter.js は CPU 負荷をかけずにループ処理が可能な JavaScript ライブラリです。

重いループ処理などを軽くすることができます。
ループ内で処理の負荷に応じて遅延させ、結果的に重い処理は軽くなり
元々軽い処理は、ほぼ従来の速度のまま実行できます。

処理の負荷だけでなく、時間のかかるループ処理は
「応答のないスクリプト」警告がでてしまいます。
そのような警告なしで実行できるのも特徴の一つです。

どうに違いがあるのかは CPU 負荷テストページ で実際に試してみてください

Pot.js が実装しているイテレータから派生しています。
パフォーマンスなどは Pot.js のイテレータとほとんど同じです

ループ処理は非同期で実行されます。

使い方は Pot.js のイテレータ と同じですが、Deferred を使っていないので
引数にコールバックを指定する点が違います。

動作環境

主な Web ブラウザで動作します
  • Mozilla Firefox *
  • Internet Explorer 6+
  • Safari *
  • Opera *
  • Google Chrome *
また、以下の環境でも動作します
  • Greasemonkey (userscript)
  • Mozilla Firefox Add-On (on XUL)
  • Node.js
  • Other non-browser environment

lazyIter.js は、CommonJS などに対応しています

使い方

lazyiter.js を読み込みます (Webページの場合)

<script src="lazyiter.js"></script>

読み込むと、lazyIter というオブジェクトが定義されます (定義されるのは lazyIter だけです)。

lazyIter.forEach :

オブジェクトや配列に対してループ実行します

// forEach:
//
// lazyIter.forEach(object, func, callback [, speed [, context]])

// Array.
lazyIter.forEach(['a', 'b', 'c'], function(val, i) {
  console.log(i + ':' + val);
}, function() {
  console.log('End loop');
});
// result:
//   '0:a'
//   '1:b'
//   '2:c'
//   'End loop'

// Object.
lazyIter.forEach({a: 1, b: 2, c: 3}, function(val, key) {
  console.log(key + ':' + val);
}, function() {
  console.log('End loop');
});
// result:
//   'a:1'
//   'b:2'
//   'c:3'
//   'End loop'

lazyIter.repeat :

指定の数だけループ実行します

// repeat:
//
// lazyIter.repeat(max, func, callback [, speed [, context]])

// Specify as number.
lazyIter.repeat(10, function(i) {
  console.log(i);
}, function() {
  console.log('End loop');
});
// result:
//   0
//   1
//   2
//   3
//   4
//   5
//   6
//   7
//   8
//   9
//   'End loop'

// for文のように 初め(begin)、ステップ(step)、終わり(end) を指定
lazyIter.repeat({begin: 0, step: 5, end: 30}, function(i) {
  console.log(i);
}, function() {
  console.log('End loop');
});
// result:
//   0
//   5
//   10
//   15
//   20
//   25
//   'End loop'

lazyIter.forEver :

lazyIter.StopIteration が throw されるまでループし続けます

// forEver:
//
// lazyIter.forEver(func, callback [, speed [, context]])

var end = 10;
lazyIter.forEver(function(i) {
  if (i === end) {
    throw lazyIter.StopIteration;
  }
  console.log(i);
}, function() {
  console.log('End loop');
});
// result:
//   0
//   1
//   2
//   3
//   4
//   5
//   6
//   7
//   8
//   9
//   'End loop'

throw lazyIter.StopIteration; により各イテレートを止めることができます。
引数 'context' は、コールバック関数の 'this' として使われます (省略可)。
引数 'speed' を指定することで速度の調節ができます (省略可)。
  • 'ninja' : もっと速い
  • 'rapid' : 速い
  • 'fast' : 速め
  • 'normal' : 通常 (default)
  • 'slow' : 遅め
  • 'doze' : 遅い
  • 'limp' : もっと遅い

速度の指定 (rapid, ninja など) は、Pot.js と同じです

Download

ダウンロード

動作テスト (サンプル)

レポジトリ



その他、なにか問題・バグ・感想・指摘などあれば、
コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。



2 件のコメント:

  1. 拡張子を.user.jsにしてScriptishにつっこんで、前頁を対象に読み込み開始時から機能するようにしたら、Firefoxがえらく軽くなったようなきがするんですが、プラシーボでしょうか?

    返信削除
    返信
    1. おおっ そんな使い方もあるんですね。負荷って分かり難いかもしれませんが効果はあると思います

      削除