8

行数が約 100k のファイルを読み込もうとしていますが、これまでのところブラウザーがクラッシュしています (ローカル)。インターネットで調べたところ、Papa Parse が大きなファイルを処理しているようです。現在、テキストエリアへのロードは約 3 ~ 4 分に短縮されています。ファイルが読み込まれたら、さらに jQuery を実行してカウントなどを行う必要があるため、プロセスに時間がかかります。csv の読み込みを速くする方法はありますか? プログラムを正しく使用していますか?

<div id="tabs">
<ul>
  <li><a href="#tabs-4">Generate a Report</a></li>
</ul>
<div id="tabs-4">
  <h2>Generating a CSV report</h2>
  <h4>Input Data:</h4>      
  <input id="myFile" type="file" name="files" value="Load File" />
  <button onclick="loadFileAsText()">Load Selected File</button>
  <form action="./" method="post">
  <textarea id="input3" style="height:150px;"></textarea>

  <input id="run3" type="button" value="Run" />
  <input id="runSplit" type="button" value="Run Split" />
  <input id="downloadLink" type="button" value="Download" />
  </form>
</div>
</div>

$(function () {
    $("#tabs").tabs();
});

var data = $('#input3').val();

function handleFileSelect(evt) {
    var file = evt.target.files[0];

Papa.parse(file, {
    header: true,
    dynamicTyping: true,
    complete: function (results) {
        data = results;
    }
});
}

$(document).ready(function () {

    $('#myFile').change(function(handleFileSelect){

    });
});


function loadFileAsText() {
    var fileToLoad = document.getElementById("myFile").files[0];

    var fileReader = new FileReader();
    fileReader.onload = function (fileLoadedEvent) {
        var textFromFileLoaded = fileLoadedEvent.target.result;
        document.getElementById("input3").value = textFromFileLoaded;
    };
    fileReader.readAsText(fileToLoad, "UTF-8");
}
4

2 に答える 2

11

あなたはおそらくそれを正しく使用しています。それは、プログラムが 100k 行すべてを解析するのに時間がかかるだけです!

これはおそらく、 Web Workersの適切なユース ケース シナリオです。

注:以下の@tomBryerの回答によると、Papa Parse はすぐに使用できる Web Workers をサポートするようになりました。これは、独自のワーカーをローリングするよりも優れたアプローチかもしれません。

以前にそれらを使用したことがない場合は、このサイトで適切な概要が説明されていますが、重要な部分は次のとおりです。

Web ワーカーはマルチスレッドを模倣し、負荷の高いスクリプトをバックグラウンドで実行できるようにするため、他のスクリプトの実行をブロックしません。プロセッサを集中的に使用する機能を実行しながら、UI の応答性を維持するのに最適です。

ブラウザのカバレッジもかなりまともで、IE10以下はそれをサポートしていない唯一のセミモダンブラウザです.

Mozilla には、ウェブ ワーカーがページのフレーム レートを高速化する方法を示す優れたビデオもあります。

Web ワーカーを使用した実際の例を取得しようとしますが、これはスクリプトを高速化するものではなく、非同期で処理するだけなので、ページの応答性が維持されることに注意してください。

編集

(importScript: ワーカー内で CSV を解析する場合は、関数 (ワーカー スレッド内でグローバルに定義されている)を使用して、worker.js 内に Papa パーサー スクリプトをインポートする必要があります。詳細については、 MDN ページを参照してください。その上で。)

これが私の実際の例です:

csv.html

<!doctype html>
<html>
<head>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.2/papaparse.js"></script>
</head>

<body>
  <input id="myFile" type="file" name="files" value="Load File" />
  <br>
  <button class="load-file">Load and Parse Selected CSV File</button>
  <div id="report"></div>

<script>
// initialize our parsed_csv to be used wherever we want
var parsed_csv;
var start_time, end_time;

// document.ready
$(function() {

  $('.load-file').on('click', function(e) {
    start_time = performance.now();
    $('#report').text('Processing...');

    console.log('initialize worker');

    var worker = new Worker('worker.js');
    worker.addEventListener('message', function(ev) {
      console.log('received raw CSV, now parsing...');

      // Parse our CSV raw text
      Papa.parse(ev.data, {
        header: true,
        dynamicTyping: true,
        complete: function (results) {
            // Save result in a globally accessible var
          parsed_csv = results;
          console.log('parsed CSV!');
          console.log(parsed_csv);

          $('#report').text(parsed_csv.data.length + ' rows processed');
          end_time = performance.now();
          console.log('Took ' + (end_time - start_time) + " milliseconds to load and process the CSV file.")
        }
      });

      // Terminate our worker
      worker.terminate();
    }, false);

    // Submit our file to load
    var file_to_load = document.getElementById("myFile").files[0];

    console.log('call our worker');
    worker.postMessage({file: file_to_load});
  });

});
</script>
</body>

</html>

worker.js

self.addEventListener('message', function(e) {
    console.log('worker is running');

    var file = e.data.file;
    var reader = new FileReader();

    reader.onload = function (fileLoadedEvent) {
        console.log('file loaded, posting back from worker');

        var textFromFileLoaded = fileLoadedEvent.target.result;

        // Post our text file back from the worker
        self.postMessage(textFromFileLoaded);
    };

    // Actually load the text file
    reader.readAsText(file, "UTF-8");
}, false);

処理の GIF、1 秒もかからない (すべてローカルで実行)

実施例のGIF

于 2016-06-29T13:13:59.453 に答える