時間のかかる処理をワーカーに置き換える
実際に時間がかかる処理をWeb Workersを使って並列処理してみましょう。前回のFile APIを使ったファイル処理のスクリプトを少し変更して、ファイル内に0がいくつあるか調べるプログラムを作ります(Firefox 3.6以降でのみ動作します)。
ワーカーを使わないプログラムがサンプル4です。サンプル4を実行すると以下の図のようにスクリプトの停止を確認するダイアログが表示され、スクリプトの動作を停止させるまでウィンドウ内のボタン(ホームや戻るボタンなど)が操作できなくなります。
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>バイナリデータ内に0がいくつあるか調べる</title>
</head>
<body>
<h1>バイナリデータ内に0がいくつあるか調べる</h1>
<form action="./test.cgi" method="get">
<input type="file" id="myFile" />
<input type="button" id="checkStart" value="調査開始" />
</form>
<div id="result"></div>
<script>
document.getElementById("checkStart").addEventListener("click", function(){
document.getElementById("result").innerHTML = "調査中...";
var fileData = document.getElementById("myFile").files[0]; // 最初のファイルだけ
var reader = new FileReader();
reader.onload = function(evt){
var count = 0;
for(var i=0; i<fileData.size; i++){
var data = evt.target.result.charCodeAt(i); // 1バイト読み出し
if (data == 0) {
count++; // 読み出したデータが0だったらカウントアップ
}
}
document.getElementById("result").innerHTML = count+"<br />"; // 結果をページ上に表示
}
reader.readAsBinaryString(fileData);
}, true);
</script>
</body>
</html>
このサンプル4をワーカーを使ったプログラムに変更します。
処理に時間がかかる「reader.onload〜」の部分を抜き出して別ファイルとして保存します。ワーカーではDOM操作ができませんのでDOM操作部分を削除し、代わりにpostMessage()メソッドを使って、呼び出し元に結果をメッセージとして送信します。
実際のプログラムはサンプル5です。
●サンプル5[HTML]
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>Web Workersを使ってバイナリデータ内に0がいくつあるか調べる</title>
</head>
<body>
<h1>Web Workersを使ってバイナリデータ内に0がいくつあるか調べる</h1>
<form action="./test.cgi" method="get">
<input type="file" id="myFile" />
<input type="button" id="checkStart" value="調査開始" />
</form>
<div id="result"></div>
<script>
document.getElementById("checkStart").addEventListener("click", function(){
document.getElementById("result").innerHTML = "調査中...";
var fileData = document.getElementById("myFile").files[0]; // 最初のファイルだけ
var reader = new FileReader();
reader.onload = function(evt){
// ワーカー設定
var myWorker = new Worker("analysis.js");
myWorker.addEventListener("message", function(event){
document.getElementById("result").innerHTML = event.data+"個ありました。";
}, true);
myWorker.postMessage({
size: fileData.size,
contents: evt.target.result
});
}
reader.readAsBinaryString(fileData);
}, true);
</script>
</body>
</html>
●サンプル5[analysis.js]
addEventListener("message", analysis, false);
function analysis(event){
var count = 0;
var fSize = event.data.size; // ファイルサイズ
var fData = event.data.contents; // ファイルデータ
for(var i=0; i<fSize; i++){
var data = fData.charCodeAt(i); // 1バイト読み出し
if (data == 0) {
count++; // 読み出したデータが0だったらカウントアップ
}
}
postMessage(count);
}
◆
次回は、引き続きWeb Workersを使って、画像分析するプログラムを作成します。