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

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

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

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

Q&A

解決済

2回答

327閲覧

JS new FileReader() 非同期なのに読み込み完了まで操作不能になるのはなぜ

aquest

総合スコア13

JavaScript

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

0グッド

1クリップ

投稿2025/03/14 02:32

編集2025/03/14 02:33

new FileReader()で1MBのファイルを読み込みしたとします
読み込んでる間(読み込み完了までの間)
ブラウザがフリーズ状態になります
プログレスで見ると80%まではすんなり読み込みされるものの残り20%は1秒に1%づつ読み込んでるような状態です
その影響でブラウザが操作不能になり、完了までうんともすんともいわなくなります
非同期なのになぜですか?
setIntervalを回しつつ、setIntervalと別でnew FileReader()の読み込み処理をかけると読み込み完了までsetIntervalが停止しているのか、そのような錯覚かわかりませんが、全て停止されている(実際は動いているかもしれませんが)フリーズ現象のようなことが起こります
これは私のPCスペックがクソで読み込みが遅い=メモリ負荷による問題でしょうか?

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

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

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

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

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

yambejp

2025/03/14 02:47

状況がわからないです。 ローカルの1Mのファイルをtype=fileで掴んだあと読み込ませているのでしょうか? とりあえず現象が確認できるソースを提示ください。
Lhankor_Mhy

2025/03/14 06:03

具体的な解決方法を知りたいのであれば、コードをご提示いただいた方がいいかもしれません。 たとえば、setInterval をアニメーションに使っているなど、他の部分のコードに問題がある可能性もあるかと思います。 どうしてもの場合は、FileReader はワーカーで使えるので外に出してしまう、というのも手かと思います。 また、FileReader って現在の実装ですと、回答にあるようなストリーム処理とか、なにか低レベルな処理をするとき以外には使わないと思います。たいていの場合、Blob のインターフェースで事が済んでしまうと思うので。
guest

回答2

0

ベストアンサー

元のものは File でしょうか? それなら 直接 .stream() で逐次読み出しすれば いいのでは……?

js

1/** @type {File} */ 2const file; 3 4for await (const text of file.stream().pipeThrough(new TextDecoderStream())) 5 console.log(text);

Blob: stream() メソッド - Web API | MDN

TextDecoderStream - Web API | MDN

読み込むコード例

こんな感じで良いのでは?

js

1openReadButton.addEventListener("click", openReadStart); 2 3/** 4 * ファイルの読み込みを実施する関数 5 */ 6async function openReadStart() { 7 const file = await showPicker(); 8 log(`file: name:${file.name} size:${file.size}`); 9 const arrayBuffer = await readToArrayBuffer(file, ({ offset, length }) => 10 log(`read ... ${offset}/${length}`), 11 ); 12 log(`read complete: ${arrayBuffer.byteLength} byte`); 13 console.log(arrayBuffer); 14} 15 16/** 17 * ファイルを選択する 18 */ 19async function showPicker() { 20 const input = document.createElement("input"); 21 input.type = "file"; 22 const { resolve, promise } = Promise.withResolvers(); 23 input.addEventListener("change", resolve); 24 input.showPicker(); 25 await promise; 26 return input.files[0]; 27} 28 29/** 30 * ファイルを arrayBuffer に変換する 31 */ 32async function readToArrayBuffer(file, progress) { 33 const array = new ArrayBuffer(file.size, { maxByteLength: file.size }); 34 array.byteOffset = 0; 35 const buffer = new Uint8Array(array); 36 let offset = 0; 37 const iterator = file.stream(); 38 for await (const value of iterator) { 39 buffer.set(value, offset); 40 offset += value.byteLength; 41 if (progress) await progress({ offset, length: file.size }); 42 } 43 return buffer.buffer; 44}

https://livecodes.io/?x=id/bs5ddwfa9w2

1GB 読み込んでみましたが特に問題無いです。

ちなみに1GBのファイルは次のコマンドで作成しました。

cmd

1fsutil file createnew file.txt 1073741824

投稿2025/03/14 02:47

編集2025/03/14 06:01
juner

総合スコア700

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

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

0

new FileReader()で1GBを読み込んだ場合、さらに遅延 下手したらブラウザの強制終了が発生するかと思われますが、
このケースについてどう対応したらいいのでしょうか

投稿2025/03/14 02:36

編集2025/03/14 02:37
aquest

総合スコア13

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

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

utm.

2025/03/14 04:36

1GBを読み込んだ場合、さらに遅延 下手したらブラウザの強制終了が発生するかと思われますが、 > このケースについてどう対応したらいいのでしょうか この質問は曖昧です。 ファイルと言っても様々な種類がありますから、 例えば画像で1GBあって、全て読み込まないと意味が無いのであれば、ファイルサイズを確認する処理を入れて、事前に操作している人へメッセージを出した方がよいかも知れませんし、 テキストであれば1行ずつパーティションをかけて読み込めるかもしれません。 ファイル形式は様々ありますが、 それらはどういった目的でするのかによって、内容が異なりますよね。 聞いてみただけでは無いのであれば詳細を記載することをおすすめします。 一般的な発想でいえば回答にもあるようにStreamを使い一度に全てを読み込まないということが挙げられます。
juner

2025/03/14 06:16

用途に依る気がするのですが、 普通に Stream 処理した感じだと 特に問題無く 1GB 読み込めたのでなんとも感あります。(私の回答参照のこと
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.32%

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

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

質問する

関連した質問