使用 papa 解析大的 csv 文件

using papa parse for big csv files

我正在尝试加载一个大约有 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");
}

您可能没有正确使用它,只是程序需要一些时间来解析所有 10 万行!

这可能是 Web Workers 的一个很好的用例场景。

注意: 根据 below, Papa Parse now has support for Web Workers out of the box。这可能比滚动你自己的工人更好。

如果您以前从未使用过它们,this site 给出了一个不错的概要,但关键部分是:

Web Workers mimics multithreading, allowing intensive scripts to be run in the background so they do not block other scripts from running. Ideal for keeping your UI responsive while also performing processor-intensive functions.

Browser coverage 也很不错,IE10 及以下版本是唯一不支持它的半现代浏览器。

Mozilla 有一个很好的视频,shows how web workers 也可以加快页面上的帧速率。

我会尝试为您获取一个使用网络工作者的工作示例,但同时请注意,这不会加速脚本,它只会使其异步处理,以便您的页面保持响应。

编辑:

(注意:如果您想在 worker 中解析 CSV,您可能需要使用 importScript 函数(在工作线程中全局定义)。有关详细信息,请参阅 MDN page。)

这是我的工作示例:

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,不到一秒(所有 运行 本地)

从 v5 开始,PapaParse 现在有 baked in WebWorkers

下面是一个在 Papaparse 中调用 worker 的简单示例

Papa.parse(bigFile, {
    worker: true,
    step: function(results) {
        console.log("Row:", results.data);
    }
});

如果您有自己的 PP 工人,则无需 re-implement,但对于未来的项目,有些人可能会发现使用 PapaParse 的解决方案更容易。