その他

Reactで並列処理を実装してみた

その他
この記事は約5分で読めます。

こんにちは!開発部の大西です!
今回はReactで並列処理を実装してみました。

Javascriptはシングルスレッドで動作しています。
そのため重たい処理を行なった場合、入力などが効かなくなる可能性があります。
そんな重たい処理はWebWorkerを使ってあげましょう!

WebWorkerとは


例えば料理を作るとしましょう。
おかずを一人で複数作るのって大変ですよね。シングルスレッドのJavascriptくんは料理を一人で作っているんです・・・。(大変)
そこでWebWorkerで働く人を増やすのです!


※以下はMDNのリファレンスなので、詳しく知りたい方はご参照ください。

ウェブワーカーの使用 - Web API | MDN
ウェブワーカーは、ウェブコンテンツがスクリプトをバックグラウンドのスレッドで実行するためのシンプルな手段です。ワーカースレッドは、ユーザーインターフェイスを妨げることなくタスクを実行できます。さらに、fetch() や XMLHttpRequest など API を用いて、ネットワークリクエストを行うことができます。ワ...

実装

まず、以下のコマンドでReactの環境を準備します。

npx create-react-app {APPNAME}

作成できたら、src/App.jsを編集していきます。

以下はsrc/App.jsのソースコードです。

import { useState } from 'react'

function App() { 
  const [num1, setNum1] = useState(""); 
  const [num2, setNum2] = useState(""); 
  const [result, setResult] = useState(""); 
  const worker = new Worker( 
   new URL('./worker', import.meta.url), 
   { type: 'module' } 
  );

  const SingleCalc = () => { 
   let r = 0; 
   for (let i = 1; i <= num1; i++) { 
    if (i % num2 === 0)  r++; 
  } 
  setResult(r) };

  const MultiCalc = () => { 
   worker.addEventListener('message', (e) => { setResult(e.data); }, false);
   worker.postMessage([num1,num2]); 
  }
  return ( 
   <div> 
    <input type="text" onChange={(event) => setNum1(event.target.value)} />
    <br/> 
    <input type="text" onChange={(event) => setNum2(event.target.value)} /> 
    <button onClick={SingleCalc}>シングル計算</button> 
    <button onClick={MultiCalc}>並列計算</button>
    <p>{result}</p> 
   </div> 
 );
}
export default App;

次にsrcフォルダに’worker.js’を作成し、以下のソースコードを書いていきます。
※WebWorkerの記法がESlintに引っかかるため無効化しています。

/* eslint-disable*/
self.addEventListener('message',(e) => {
 let r = 0;
 for (let i = 1; i <= e.data[0]; i++) {
  if (i % e.data[1] === 0) r++;
 }
 self.postMessage(r);
}, false);
/* eslint-disable*/

上記の内容は、1から’num1’の値に’num2’の倍数はいくつあるかを計算してくれる処理です。

それでは、ターミナルに以下のコマンドを入力して起動しましょう!

npm start

以下のアプリケーションが出来上がりました!

シングル計算はシングルスレッドで通常の計算、並列計算はスレッドを増やして並列での計算を行います。

では一番目のテキストボックスに’100000000’、二番目のテキストボックスに’2’を入力します。

次にシングル計算を押下します。

計算に時間がかかるため、結果が返ってくるまでテキストボックスの入力ができないと思います。

次は並列計算を押下します。

別のスレッドで計算しているため、テキストボックスの入力ができる状態になっているでしょう。

このように、計算処理を別で行うことで、UI上の操作をメインスレッドで継続して行うことができます。

後書き

いかがでしょうか?
実行に時間がかかる処理を別のスレッドで行うことで、ユーザー体験を損なうことなく処理できました。

WebWorkerは今使われている基本的なブラウザで使用することができるので、重たい処理をWebWorkerにまかせるのも一つの手だと思います!

またPWAの通知にも’ServiceWorker’という別の技術が使われているので、どんどん使われるのではないでしょうか!

ここまで読んでいただきありがとうございます!