質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

4回答

4820閲覧

setintervalはループの時間が長くてもかなりCPU使うのでしょうか?

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2018/03/01 03:46

サイト上で下記のように画像などをループさせているのですが、CPUのファンが回りだしかなり使っているようです。setintervalはループの時間が長くてもかなりCPU使うのでしょうか?

```ここに言語を入力 function loop() { ループする処理 }; setInterval(loop, 17000);
もし思い込みではなく実際そのような問題がある場合解決方法があれば教えていただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

ループする処理の中身をもう少し具体的に欲しいですが、
setIntervalの仕様でこういう書き方してたらアウトです。

JavaScript

1function loop() { 2 // 1回分の処理 3 setInterval(loop, 17000); 4} 5setInterval(loop, 17000);

何故ダメかというと、setIntervalは第二引数の間隔で関数を叩き続ける機能だからです。

  • 17秒後: 1個目のloop関数が実行
  • 34秒後: 元々宣言してあったloopと、loop関数内で宣言されたloopの2個が同時に起動
  • 51秒後: 元々宣言してあった2個のloopと、新たに宣言された2個のloopが同時に起動

…このように倍々で増えているのがわかります。
2の10乗は1024倍なので、170秒経過しただけでノートPCから煙吹いてもおかしくないですね。
ちょっとトイレに行くだけでブラウザが固まる大惨事確定でしょう。

もしそうならばsetIntervalではなくsetTimeoutを利用してください。
1回だけで終わる事が約束されているので、ねずみ算式に起動する関数が増えたりはしません。

setintervalはループの時間が長くてもかなりCPU使うのでしょうか?

そんなことはありません。
JavaScriptのsetIntervalを始めとするイベントループの機能はとても優秀で、
発火すべきタイミングまでひたすらサボり続ける低燃費の設計になっています。


【おまけ】 コメント欄のコード

外にあるi変数に依存しないようにしました。
こんな感じかなぁと思います。

JavaScript

1// DOMを触るので描画完了まで遅延させたほうが良い 2document.addEventListener("load", function () { 3 var items = [0, 1, 2, 3].map(function(it){ return document.getElementById('slide' + it); }); 4 var fadeIn = function (i) { 5 items[i].classList.add('slide-fadein'); 6 items[i].classList.remove('slide-fadeout'); 7 } 8 var fadeOut = function (i) { 9 items[i].classList.add('slide-fadeout'); 10 items[i].classList.remove('slide-fadein'); 11 } 12 var slideShow = function (i) { 13 if (i => items.length) { 14 i = 0; 15 } 16 fadeIn(i); 17 fadeOut(i === 0 ? items.length - 1 : i - 1); 18 setTimeout(slideShow.bind(null, i + 1), 18000); 19 } 20 setTimeout(slideShow.bind(null, 0), 18000); 21});

投稿2018/03/01 04:00

編集2018/03/01 11:37
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/01 05:51

ありがとうございます。 function loop() { //setTimeout()を含む関数を呼び出す setTimeout("loop()",8000); }; このように自分自身を呼び出せば増えずにループ出来ると思い変更しましたが今度は一度しか実行されません。どこに不備がありますか?
miyabi-sun

2018/03/01 05:53

×: setTimeout("loop()",8000); ○: setTimeout(loop, 8000);
退会済みユーザー

退会済みユーザー

2018/03/01 06:04

ありがとうございます。 一度だけ実行されるのですがやはりその後ループしません。 インスペクタでみるとloop = ƒ loop()と出ているので呼び出しは出来ているという事でよいでしょうか? function loop() { //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); loop = ƒ loop() };
miyabi-sun

2018/03/01 06:10

まさかとは思いますが、こう書いてませんか? function loop() { setTimeout(loop, 8000); } function loop() { console.log("doing loop"); setTimeout(loop, 8000); } 等と具体的な処理も含んでください。 こうすれば'doing loop'という文字列が8秒毎にコンソール上に流れるようになります。
退会済みユーザー

退会済みユーザー

2018/03/01 06:15

一部抜粋します。 function loop() { arrayItem[i].classList.add('slide-text-fadeout'); arrayItem[i].classList.remove('slide-text-fadein'); ++i; arrayItem[i].classList.add('slide-text-fadein'); arrayItem[i].classList.remove('slide-text-fadeout'); //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); }; のように処理の最後に入れています
miyabi-sun

2018/03/01 06:22

基本的にMDNのような公式リファレンスに近い所で探して下さい。 個人ブログとか「わーいうごいたー」程度の事を大げさに書いてあるだけですからね、ある程度技術力が付いて良い記事と悪い記事が選別出来ない間は半分以上嘘くらいに思って置いたほうが良いです。 setTimeoutの例だとこれみてください。 https://developer.mozilla.org/ja/docs/Web/API/WindowTimers/setTimeout > 文字列リテラルの使用 > 関数の代わりに、文字列を setTimeout() に渡すと、eval を使うのと同様の危険性があります。 > setTimeout に渡した文字列はグローバルコンテキストで評価されます。そのため、setTimeout() が呼び出されたコンテキストのローカルシンボルは、文字列を評価したコードからは利用できません。 従って嘘ではありませんが相当やばいことをやらかしています。 また「グローバル領域での実行」と記載されていますが、 このloop関数は何か別の関数内で宣言されたものではないでしょうか? 例えば$(function(){});の中とか…そうでればloop関数を見つけられずにエラーになっている可能性があります。
退会済みユーザー

退会済みユーザー

2018/03/01 06:33

(function () { function loop() { arrayItem[i].classList.add('slide-text-fadeout'); arrayItem[i].classList.remove('slide-text-fadein'); ++i; arrayItem[i].classList.add('slide-text-fadein'); arrayItem[i].classList.remove('slide-text-fadeout'); //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); }; })(); このように、カプセル化のために全体を即時関数で囲んでいますが、中にスライドの処理が入っているのに問題が起こるのでしょうか?
miyabi-sun

2018/03/01 06:34

レスを書いている最中のコードですが… そもそもsetTimeoutのループで簡単に解決しなさそうですね。 目的は要素をチカチカさせたいのでしょうかね? このコードの書き方を見るに少々トリッキーな書き方が出来ないと解決するのは難しいかと思います。 一旦この質問は閉じて、コードを公開して仕切り直す事をオススメします。
退会済みユーザー

退会済みユーザー

2018/03/01 06:41

テキストを定期的に変更するスライドショーです。 setintervalの時は問題なく動いているのでループだけが問題だと思います。
miyabi-sun

2018/03/01 06:41

なるほど、文言のスライドを実装したかったのですね。 確かに即時関数でグローバルからはアクセスできなくなってますね。 JavaScriptは関数を宣言するとスコープを作ります。 そうすると、中から外には変数や関数を参照出来ますが、外から中には参照出来なくなります。 というか、その目的でカプセル化するために即時関数で包んだんじゃないんですか?
退会済みユーザー

退会済みユーザー

2018/03/01 06:53

その通りです。 ただスライドショーのjavascriptソース部分はすべてこの即時関数に入れています。 外にあれば確かに利用できないですが、中にすべてあるので関係ないと思っています。
退会済みユーザー

退会済みユーザー

2018/03/01 07:14

function loop() { arrayItem[i].classList.add('slide-text-fadeout'); arrayItem[i].classList.remove('slide-text-fadein'); ++i; arrayItem[i].classList.add('slide-text-fadein'); arrayItem[i].classList.remove('slide-text-fadeout'); //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); }; このようにすく時間数を外してもやはり止まりました。
miyabi-sun

2018/03/01 07:21

変数iの扱いに関する問題になってきてますね。 コンソールを開くとエラーが出てると思うので、それで対応してください。 またiが増えっぱなしのように思えますが、最後の要素を掴んだ場合はどうなるかも疑問です。 既に表題からはなにも関係無いところに話の主語が移動してしまっていますし、 どのようにスコープ作っていくか等の設計や戦略的な話も出てきます。 一旦この質問は閉じるようお願いします。
退会済みユーザー

退会済みユーザー

2018/03/01 08:02

(function () { var item0 = document.getElementById('slide0'); var item1 = document.getElementById('slide1'); var item2 = document.getElementById('slide2'); var item3 = document.getElementById('slide3'); var arrayItem = [ item0, item1, item2, item3 ]; var i = 0; function loop() { arrayItem[i].classList.add('slide-fadeout'); arrayItem[i].classList.remove('slide-fadein'); ++i; if(i === arrayItem.length) { i = 0; } arrayItem[i].classList.add('slide-fadein'); arrayItem[i].classList.remove('slide-fadeout'); setTimeout(loop, 18000); }; })(); このようになっています。 すべてお見せするのが遅れまして恐縮です。
退会済みユーザー

退会済みユーザー

2018/03/01 08:25

恥ずかしながら仕事で利用する可能性があるので、ご容赦ください。
guest

0

待たせる処理自体は重くないと思います。
while(true)的な処理はブラウザがすぐギブアップしますしね
おそらくloopの側の問題だと思います。
処理自体が重いか、不正な処理をしている、もしくはなんらかの競合しているなど

投稿2018/03/01 03:56

yambejp

総合スコア114784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/01 04:00

ありがとうございます。 setinterval自体が重いという事はないのでその中身の処理にCPUのファンが回りだす原因があるという事ですね。
guest

0

繰り返しそのものよりも中の処理自体に問題があるように思います。
処理内容の提示は可能でしょうか?

StackOverFlow(英語版)にも似たような質問があがっていました。

質問タイトルは「setIntervalはCPUに負荷をかけますか?」

に、対して、回答では幾つかコードや処理のロジックの最適化を促すようなコメントが付いています。

Google翻訳そのまま

私はsetIntervalが本質的にあなたに重大なパフォーマンス上の問題を引き起こすとは思わない。 私は、CPUがそれほど強力でない初期の時代から評判が来るかもしれないと思う。

ただし、パフォーマンスを向上させる方法はありますが、それを実行することをお勧めします。
1.文字列ではなく関数をsetIntervalに渡します。
2.可能な限り間隔をあけてください。
3.可能な限り間隔を長くします。
4.できるだけ短く簡単にコードを実行してください。

投稿2018/03/01 04:01

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

karamarimo

2018/03/01 04:19

google翻訳の2.は間違ってますね。「できるだけsetIntervalするのを減らそう」ということだと思います。
m.ts10806

2018/03/01 04:24 編集

あ、なるほど。 他の代替手段がないか考えようってことですね。 勉強になります
退会済みユーザー

退会済みユーザー

2018/03/01 06:06

ありがとうございます。 一度だけ実行されるのですがやはりその後ループしません。 インスペクタでみるとloop = ƒ loop()と出ているので呼び出しは出来ているという事でよいでしょうか? function loop() { //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); loop = ƒ loop() };
退会済みユーザー

退会済みユーザー

2018/03/01 06:08

setIntervalは、前に行ったタスクが削除されずに残ってしまうので、12345と処理のタスクが増えていって、ものすごく重くなるという事でしょうか?上記のようにsetTimeoutに変更しました。
m.ts10806

2018/03/01 06:15

個々にコードのやりとりをしていては手間もかかりますし 他の回答者の方にも分かりません。 質問本文に追記してください。
退会済みユーザー

退会済みユーザー

2018/03/01 06:17

了解しました。
guest

0

setInterval() は、 loop() の処理が終わってなかろうが、
正確に17000ミリ秒ごとに繰り返しますので処理が重なっていき高負荷の原因になりますが、
ループ間隔に関しては、逆に短くするほど負荷となるかと思います。
setTimeout でしたら、処理を終えてからループするので負荷は軽くなるかと思います。

投稿2018/03/01 04:00

pokkur

総合スコア76

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/01 06:05

ありがとうございます。 一度だけ実行されるのですがやはりその後ループしません。 インスペクタでみるとloop = ƒ loop()と出ているので呼び出しは出来ているという事でよいでしょうか? function loop() { //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); loop = ƒ loop() };
pokkur

2018/03/01 06:12

@kei344 さん、ご指摘どうもありがとうございます>< >「正確に」 調べてみましたが、どうしても遅延は生じるのですね。 setTimeout() と違い、概ね意図通りのタイミングで動くということで。 >「処理が重なっていき」 言われてみれば並列処理のように読ませる誤った表現でした。
pokkur

2018/03/01 06:26

@amebatvさん、 その例ですと、イベントが発生しないです。 下記で setTimeout() の動作確認できるかと思いますが、 実際は正しくイベントを設定しましょう。 ``` function loop () { console.log('test'); } setInterval(loop, 1000); ```
退会済みユーザー

退会済みユーザー

2018/03/01 06:44

一部抜粋します。 function loop() { arrayItem[i].classList.add('slide-text-fadeout'); arrayItem[i].classList.remove('slide-text-fadein'); ++i; arrayItem[i].classList.add('slide-text-fadein'); arrayItem[i].classList.remove('slide-text-fadeout'); //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); }; のように処理の最後に入れています これではループしないのですか? 理由が初心者なのでわからないのですが具体的に教えていただければ幸いです。
退会済みユーザー

退会済みユーザー

2018/03/01 06:44

一部抜粋します。 function loop() { arrayItem[i].classList.add('slide-text-fadeout'); arrayItem[i].classList.remove('slide-text-fadein'); ++i; arrayItem[i].classList.add('slide-text-fadein'); arrayItem[i].classList.remove('slide-text-fadeout'); //setTimeout()を含む関数を呼び出す setTimeout(loop, 8000); }; のように処理の最後に入れています これではループしないのですか? 理由が初心者なのでわからないのですが具体的に教えていただければ幸いです。
退会済みユーザー

退会済みユーザー

2018/03/01 08:25

(function () { var item0 = document.getElementById('slide0'); var item1 = document.getElementById('slide1'); var item2 = document.getElementById('slide2'); var item3 = document.getElementById('slide3'); var arrayItem = [ item0, item1, item2, item3 ]; var i = 0; function loop() { arrayItem[i].classList.add('slide-fadeout'); arrayItem[i].classList.remove('slide-fadein'); ++i; if(i === arrayItem.length) { i = 0; } arrayItem[i].classList.add('slide-fadein'); arrayItem[i].classList.remove('slide-fadeout'); setTimeout(loop, 18000); }; })(); このようになっています。 すべてお見せするのが遅れまして恐縮です。 恥ずかしながら仕事で利用する可能性があるので、ご容赦ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問