Help us understand the problem. What is going on with this article?

非同期処理を挟んで CPU 使用率を抑える JS ライブラリを作った

More than 1 year has passed since last update.

tl;dr

  • coolit.js を作った
  • 非同期を挟んで CPU 使用率を抑える npm パッケージ
  • 元ネタは chillout.js
  • 戦略を選んで Iterator を AsyncIterator に変換する
  • 小さなライブラリ (非圧縮状態で 3.3 KB の 1 ファイルのみ)

coolit.js の紹介

重たい処理を JavaScript で書くときに同期的にメインスレッドで動かすと UI が固まってしまうため、適宜 休憩 をはさみつつ実行させることで UI が固まってしまうことを防ぐのをサポートする。

(async () => {
  let sum = 0;
  for await (const i of coolit([1, 2, 3, 4, 5])) {
    // heavy task
    sum += i;
  }
  console.assert(sum === 15);
})();
(async () => {
  let sum = 0;
  function* heavyTask() {
    for (const i of [1, 2, 3, 4, 5]) {
      yield;
      // heavy task
      sum += i;
    }
  }
  for await (const _ of coolit(heavyTask())) {
  }
  console.assert(sum === 15);
})();

coolit.js を使うとこんな感じのコードになる。
自分で試してみたい方は以下で。

See the Pen coolit.js demo by KoharaKazuya (@koharakazuya) on CodePen.

詳細は GitHub を参照。

ただ、重い処理の対策は素直に Worker (別スレッド) に逃がすことを始めに検討するのが良い。

作った動機と工夫点

chillout.js を GitHub で見かけて、そういえば requestAnimationFrame だったり setImmediate を使ってループを書くことはたまにあるけどライブラリ使ったことないな、と気付いた。
chillout の API を眺めてると自分なら Async Iterators 使うなーと思ったので作った。

ES2018 の for-await-of 構文で扱えるようにした後に、Edge などまだ動かない環境もあるのでそれを必須にするには時期尚早だろうと思い直して無くても動くように修正した。もちろん for-await-of が使える環境なら使って書ける。
Symbol.asyncIterator が無い環境では AsyncIterableIterator ではなく単に Iterator となるようにした。

ES2017 Async Functions の環境を前提としているが、これは 2018/11 現在のモダンブラウザなら使える。
IE 11 などは……トランスパイルとポリフィルがあれば多分動く。試してないけど。

また、処理進行の戦略は選べたほうがいいだろうと思い、オプションで選べるようにしている。
requestAnimationFrame や時間指定などを選べるようにした。デフォルトは requestIdleCallback

今回初めて rollup を使った。
これにより npm 配布を UMD 形式と ESM (mjs) 形式を両立させた。今まであまり理解していなかったが、ようやく学べた。


こんな小さな量でも TypeScript で書くとサポートを受けられるし、実際助かったシーンがあったんだけど、TypeScript 使うだけでもすぐにビルドやテストなどのツールチェーン周りが複雑になっていくからしんどい。EcmaScript だけだったらすごく簡単に終わるので。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away