Pot.js 概要

Pot.js とは

Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。

for (var i = 0, len = items.length; i < len; i++) {
    var item = items[i];
    // 何らかの重い処理
}

このような JavaScript のループが、処理によっては負荷となり「応答のないスクリプト」になってしまうことがあります。
これを Pot.js ライブラリのループ関数に置き換えます。

Pot.Deferred.forEach(items, function(item, i) {
    // 何らかの重い処理
})

この変化で、どれくらい CPU 使用率に違いあるか示した図です。

イテレータ データサイズ CPU 最大使用率 CPU 平均使用率 実行時間 (ms)
for 文 1MB 14.52% 10.61% 1211ms.
jQuery.each 1MB 16.28% 13.53% 1362ms.
Pot.Deferred.forEach 1MB 11.65% 5.53% 1647ms.
for 文 5MB 24.85% 21.71% 4717ms.
jQuery.each 5MB 27.78% 24.29% 5570ms.
Pot.Deferred.forEach 5MB 13.74% 8.61% 8925ms.
for 文 10MB 28.14% 25.92% 10699ms.
jQuery.each 10MB 31.09% 30.77% 15844ms.
Pot.Deferred.forEach 10MB 18.62% 9.77% 38909ms.

この結果は、jQuery と JavaScript Pot.js ループの CPU 使用率比較グラフ の記事から得られたものです (Core i5)。
各サイズの JSON ファイルを対象としています。
Pot.js イテレータは、処理時間が他と比べ長めになっていますが CPU 最大使用率、CPU 平均使用率 共に安定しているのがわかると思います。
速度に関しては調節ができ、より高速に実行したい場合は並列処理にすることもできます。
また、「応答のないスクリプト」警告を出さずに実行することが可能です。

このページで実際に実行して体験できます

ダウンロード

最新

Pot.js

PotLite.js (lite)

レポジトリ

$ git clone git://github.com/polygonplanet/Pot.js

GitHub : polygonplanet/Pot.js - GitHub

概要

Pot.js は、
JavaScript のループ処理における CPU 負荷を抑え、UI にストレスを与えることなく実行できるライブラリです。

負荷に関して、とくにプログラマが意識する必要なくアプリケーションを実装することができます。

Pot.js は、Deferred による非同期処理や、非同期イテレータを中心に作られています。
MochiKit ライク (または JSDeferred ライク) な Pot.Deferred によって、
多様なイテレート (forEach, filter, map, reduce, zip, repeat, some など) を可能とします。

また、様々なアルゴリズムを扱った文字列処理や、アスペクト指向 (AOP) で書ける シグナルやイベント処理
HTML5 に関する File API などを扱うことができる汎用ユーティリティライブラリです。

そして、グローバルオブジェクトの prototype を汚染しません。
基本的にグローバルに定義されるのは 'Pot' オブジェクトだけなので
コンフリクトの心配なく、他の JavaScript ライブラリと共に利用できます。

Pot.js は、クロスブラウザであり、Web ブラウザ上や Node.js、
userscript (Greasemonkey, Scriptish) や XUL (Firefox アドオン) 上などで動きます。

PotLite.js は、
Pot.js で実装されている Deferred などの非同期処理の部分だけを抽出したライトバージョンです。

インストール

一般的な方法で動作します。

例:

<script type="text/javascript" src="pot.min.js"></script>

<!-- または下記で説明する API サーバが利用できます -->
<script type="text/javascript" src="http://api.polygonpla.net/js/pot/1.21/pot.min.js"></script>

読み込み後の例:

<script type="text/javascript">
// 任意に globalize で短い記述にできます (下記参照)
Pot.globalize();

begin(function() {
    return request('./hoge.json', {
        mimeType : 'text/javascript'
    }).then(function(res) {
        return parseFromJSON(res.responseText);
    });
}).then(function(res) {
    return Deferred.forEach(res.items, function(value, key) {
        // ...
    });
});
// ...
</script>

Node.js の場合。

// Example to define Pot object on Node.js.
var Pot = require('./pot.min.js');
Pot.debug(Pot.VERSION);

Pot.Deferred.begin(function() {
    Pot.debug('Hello World!');
}).then(function() {...})
// ...

Greasemonkey (userscript) の例。

// ==UserScript==
// ...
// @require  https://github.com/polygonplanet/Pot.js/raw/master/pot.min.js
// ...
// ==/UserScript==

Pot.Deferred.begin(function() {
    return Pot.request('http://www.example.com/data.json').then(function(res) {
        return Pot.parseFromJSON(res.responseText);
    });
}).then(function(res) {
    Pot.debug(res);
    // do something...
});
//...

Pot.js をバージョンを限定して Web から直接読み込みたい場合、 上の GitHub リンクでは常に最新になってしまうため 実装の差異による不具合が発生するかもしれません。
その場合、ホスティング用の API サーバが利用できます。

Pot.js Version 1.21 を使う場合:

これは、1.21 の部分をリリース済みのバージョンに合わせて変更できます。
レポジトリに (例えば 1.xx と) バージョンをタグ付けした時に、 あわせて API サーバに置くようにしています。

例えば Greasemonkey で 1.21 を使う場合、

// ==UserScript==
// ...
// @require  http://api.polygonpla.net/js/pot/1.21/pot.min.js
// ...
// ==/UserScript==

と記述できます。

この例では 1.21 としていますが、このマニュアルは常に更新しているわけではないので 最新とは限りません。
より安定したバージョンを選び使ってください。

PotLite.js を利用する場合は、

Pot.js と同様にリンクを変えて利用できます。

Greasemonkey (userscript) に限らず HTML 上の script タグからなど、用途に応じてご利用ください。
API サーバからの Pot.js および PotLite.js の読み込みに関して、利用はフリーです。

最新のバージョンの URL は Pot.js + PotLite.js - Hosting API Index から確認できます。


jQuery プラグインとして。

// jQuery を読み込んだ後に実行。
Pot.deferrizejQueryAjax();

// Ajax 系の関数が Pot.Deferred を返すようになる
$.getJSON('/hoge.json').then(function(data) {
    alert(data.results[0].text);
}).rescue(function(err) {
    alert('Error! ' + err);
}).ensure(function() {
    return someNextProcess();
});

// エフェクトなどを Deferred 化する 'deferred' が追加される
$('div#hoge').deferred('hide', 'slow').then(function() {
    // ...( hide() が終了したあとの処理)
});

Pot.deferrizejQueryAjax() は現状、ライブラリ側で実行しません。 なので、プラグインを使用する場合は コードの最初などで実行する必要があります。

動作環境

以下の Web ブラウザで動作確認済みです。

  • Mozilla Firefox *
  • Internet Explorer 6+
  • Safari *
  • Opera *
  • Google Chrome *

また、以下の環境でも動作するよう設計されています。

  • Greasemonkey (userscript)
  • Mozilla Firefox Add-On (on XUL)
  • Node.js
  • Other non-browser environment

動作テスト

以下のページで動作テストができます。

ライセンス

Dual licensed under the MIT and GPL v2 licenses.

Copyright © 2012 polygon planet

連絡先

Author: polygon planet

@polygon_planet または (polygon.planet.aqua[at]gmail.com) まで、
バグ・意見・感想・要望などなんでも送っていただけるとうれしいです。

謝辞

ロゴを作成してくれた yinyang302mg さん、 そして Pot.js / PotLite.js を作る切欠となった JSDeferred, MochiKit (Mochi Media, Inc.), Tombloo developers に感謝いたします。

JSDoc ドキュメント

Closure Compiler によりソースコードから自動生成されたドキュメントです。

殆どの関数ごとにサンプルコードを載せているので、ある程度は参考になると思います。
生成物をすべて確認しているわけではないので、誤認識してる箇所もあるかもしれません。
より詳細な実装などは直接ソースコードを参照ください。

導入

Pot.js および PotLite.js は、 他のライブラリと名前などが衝突しないよう
Pot というオブジェクトのみグローバルに定義されます。
Node.js などモジュールが有効な環境では、 グローバルに定義する代わりに exports を使用し require によって利用できるよう定義されます。

関数名などを短い記述で書きたい場合、

Pot.globalize();

と最初に記述することで、 例えば Pot.Deferred.begin が begin だけの記述で呼び出せるようになります。
もし、他のライブラリ等と名前の衝突してしまう場合は 無理と短い記述をする必要ありません。

また、Pot.globalize()

var obj = {
    foo: function() { return 'foo' },
    bar: function() { return 'bar' }
};
Pot.globalize(obj);

alert(foo() + bar()); // 'foobar'

上のように引数に何らかのオブジェクトを与えることで、 任意のオブジェクトをグローバルスコープに置きたい時に活用できます。

ブログ

Pot.js 公式ブログ。

Twitter

Pot.js 公式 Twitter アカウント

関連記事

Pot.js / PotLite.js に関する関連記事やブログなど紹介。