0
# Web Workers
1
2
Background parsing using web workers to prevent UI blocking during large file processing. Automatically creates and manages worker threads with message passing for seamless integration.
3
4
## Capabilities
5
6
### Worker-Based Parsing
7
8
Enable background processing for large CSV files without blocking the main thread.
9
10
```javascript { .api }
11
/**
12
* Parse CSV using web worker
13
* @param input - CSV string, File object, or URL
14
* @param config - Configuration with worker: true
15
*/
16
Papa.parse(input: string | File, config: {
17
worker: true;
18
step?: (result: ParseResult) => void;
19
chunk?: (result: ParseResult) => void;
20
complete?: (result: ParseResult) => void;
21
error?: (error: ParseError) => void;
22
// Other parsing options...
23
}): void;
24
```
25
26
**Usage Examples:**
27
28
```javascript
29
// Parse large file in background
30
const largeFile = document.getElementById('csvFile').files[0];
31
32
Papa.parse(largeFile, {
33
worker: true, // Enable web worker
34
header: true,
35
dynamicTyping: true,
36
step: function(result) {
37
// This callback runs on main thread
38
console.log('Worker parsed row:', result.data);
39
updateUI(result.data);
40
},
41
complete: function(results) {
42
console.log('Worker completed parsing');
43
console.log('Total rows:', results.data.length);
44
hideLoadingSpinner();
45
},
46
error: function(error) {
47
console.error('Worker error:', error);
48
showErrorMessage('Failed to parse file');
49
}
50
});
51
52
// UI remains responsive during parsing
53
function updateUI(rowData) {
54
// Update progress bar, add rows to table, etc.
55
// This runs smoothly without blocking
56
}
57
```
58
59
### Worker Compatibility Check
60
61
Check if web workers are supported in the current environment.
62
63
```javascript { .api }
64
Papa.WORKERS_SUPPORTED: boolean; // True if web workers are available
65
```
66
67
**Usage Examples:**
68
69
```javascript
70
if (Papa.WORKERS_SUPPORTED) {
71
// Use worker-based parsing for better performance
72
Papa.parse(largeFile, {
73
worker: true,
74
header: true,
75
complete: function(results) {
76
console.log('Parsed with worker:', results.data.length, 'rows');
77
}
78
});
79
} else {
80
// Fall back to main thread parsing
81
console.warn('Web Workers not supported, using main thread');
82
Papa.parse(largeFile, {
83
header: true,
84
complete: function(results) {
85
console.log('Parsed on main thread:', results.data.length, 'rows');
86
}
87
});
88
}
89
```
90
91
### Large File Processing
92
93
Process very large CSV files without freezing the browser interface.
94
95
```javascript { .api }
96
interface WorkerConfig {
97
worker: true; // Enable web worker processing
98
step?: (result: ParseResult) => void; // Process rows as they're parsed
99
chunk?: (result: ParseResult) => void; // Process data in chunks
100
}
101
```
102
103
**Usage Examples:**
104
105
```javascript
106
// Process multi-megabyte CSV file
107
const hugeFile = event.target.files[0]; // 100MB+ CSV file
108
109
// Show progress indicator
110
showProgressSpinner('Processing large file...');
111
112
Papa.parse(hugeFile, {
113
worker: true,
114
header: true,
115
step: function(result) {
116
// Process each row without blocking UI
117
processRowData(result.data);
118
119
// Update progress counter
120
updateRowCounter();
121
},
122
chunk: function(result) {
123
// Update progress based on chunk size
124
const progress = (result.meta.cursor / hugeFile.size) * 100;
125
updateProgressBar(progress);
126
},
127
complete: function(results) {
128
hideProgressSpinner();
129
showCompletionMessage(`Processed ${results.data.length} rows`);
130
},
131
error: function(error) {
132
hideProgressSpinner();
133
showErrorMessage('Failed to process file: ' + error.message);
134
}
135
});
136
137
// User can continue interacting with the page while file processes
138
```
139
140
### Worker Thread Management
141
142
PapaParse automatically manages worker thread lifecycle.
143
144
```javascript { .api }
145
interface WorkerManagement {
146
// These properties are managed internally by PapaParse
147
Papa.WORKER_ID?: number; // Current worker ID (set automatically)
148
Papa.BLOB_URL?: string; // Worker blob URL (created automatically)
149
}
150
```
151
152
**Usage Examples:**
153
154
```javascript
155
// Multiple simultaneous worker operations
156
const files = Array.from(document.getElementById('multipleFiles').files);
157
158
files.forEach((file, index) => {
159
Papa.parse(file, {
160
worker: true,
161
header: true,
162
complete: function(results) {
163
console.log(`File ${index + 1} completed:`, results.data.length, 'rows');
164
165
// Each worker gets its own ID automatically
166
console.log('Worker ID was:', Papa.WORKER_ID);
167
}
168
});
169
});
170
171
// PapaParse handles creating and cleaning up workers automatically
172
```
173
174
### Worker Error Handling
175
176
Handle errors that occur in worker threads.
177
178
```javascript { .api }
179
interface WorkerErrorHandling {
180
error?: (error: ParseError) => void; // Worker error callback
181
}
182
183
interface WorkerError extends ParseError {
184
type: 'WorkerError'; // Error occurred in worker thread
185
code: string; // Specific error code
186
message: string; // Error description
187
}
188
```
189
190
**Usage Examples:**
191
192
```javascript
193
Papa.parse(problematicFile, {
194
worker: true,
195
header: true,
196
error: function(error) {
197
// Handle different types of worker errors
198
switch (error.type) {
199
case 'WorkerError':
200
console.error('Worker thread error:', error.message);
201
showUserMessage('Background processing failed');
202
break;
203
case 'NetworkError':
204
console.error('Network error in worker:', error.message);
205
showUserMessage('Failed to download file');
206
break;
207
default:
208
console.error('Parse error in worker:', error);
209
showUserMessage('File parsing failed');
210
}
211
212
// Optionally retry without worker
213
retryWithoutWorker();
214
}
215
});
216
217
function retryWithoutWorker() {
218
console.log('Retrying without web worker...');
219
Papa.parse(problematicFile, {
220
worker: false, // Disable worker for retry
221
header: true,
222
complete: function(results) {
223
console.log('Retry successful:', results.data.length, 'rows');
224
}
225
});
226
}
227
```
228
229
### Performance Optimization
230
231
Optimize worker usage for different file sizes and processing needs.
232
233
```javascript { .api }
234
interface WorkerOptimization {
235
worker: true;
236
chunkSize?: number; // Optimize chunk size for worker communication
237
step?: (result: ParseResult) => void; // Minimize data transfer
238
}
239
```
240
241
**Usage Examples:**
242
243
```javascript
244
function parseWithOptimalWorkerConfig(file) {
245
const fileSize = file.size;
246
let config = {
247
worker: true,
248
header: true
249
};
250
251
if (fileSize > 50 * 1024 * 1024) { // Files larger than 50MB
252
// Use larger chunks to reduce worker communication overhead
253
config.chunkSize = Papa.RemoteChunkSize * 2; // 10MB chunks
254
config.chunk = function(result) {
255
// Process larger chunks less frequently
256
processBigChunk(result.data);
257
};
258
} else if (fileSize > 5 * 1024 * 1024) { // Files 5-50MB
259
// Use step processing for better progress feedback
260
config.step = function(result) {
261
processRowWithProgress(result.data);
262
};
263
} else {
264
// Small files - just use worker for consistency
265
config.complete = function(results) {
266
processAllData(results.data);
267
};
268
}
269
270
Papa.parse(file, config);
271
}
272
273
function processBigChunk(chunkData) {
274
// Efficiently process large chunks
275
const batchSize = 1000;
276
for (let i = 0; i < chunkData.length; i += batchSize) {
277
const batch = chunkData.slice(i, i + batchSize);
278
processBatch(batch);
279
}
280
}
281
```
282
283
### Worker Limitations
284
285
Understanding what features are available in worker mode.
286
287
```javascript { .api }
288
interface WorkerLimitations {
289
// These features are NOT available when worker: true
290
// - Direct File object manipulation
291
// - DOM access from callbacks
292
// - Synchronous operations
293
// - Some advanced streaming features
294
}
295
```
296
297
**Usage Examples:**
298
299
```javascript
300
// Features that work in worker mode
301
Papa.parse(file, {
302
worker: true,
303
304
// ✅ These work in workers
305
header: true,
306
delimiter: ',',
307
dynamicTyping: true,
308
transformHeader: function(header) {
309
return header.toLowerCase();
310
},
311
transform: function(value, field) {
312
return value.trim();
313
},
314
315
// ✅ Callbacks work (run on main thread)
316
step: function(result) {
317
// Process data on main thread
318
updateDatabase(result.data);
319
},
320
321
complete: function(results) {
322
// Final processing on main thread
323
showResults(results.data);
324
}
325
});
326
327
// Features that don't work in worker mode
328
Papa.parse(file, {
329
worker: true,
330
331
// ❌ These don't work with workers
332
// download: true, // Network requests not supported
333
// withCredentials: true, // Credentials not supported
334
// Custom File handling // Limited File object access
335
});
336
```
337
338
### jQuery Integration with Workers
339
340
Use PapaParse workers with jQuery file input processing.
341
342
```javascript { .api }
343
// jQuery plugin supports worker mode
344
$('#fileInput').parse({
345
config: {
346
worker: true,
347
header: true,
348
complete: function(results, file) {
349
console.log('Worker parsed file:', file.name);
350
console.log('Results:', results.data.length, 'rows');
351
}
352
}
353
});
354
```
355
356
**Usage Examples:**
357
358
```javascript
359
// jQuery multiple file processing with workers
360
$('#multipleFileInput').parse({
361
config: {
362
worker: true,
363
header: true,
364
step: function(result) {
365
// Each file processes in its own worker
366
addRowToTable(result.data);
367
}
368
},
369
complete: function() {
370
// All files completed
371
console.log('All files processed by workers');
372
enableDownloadButton();
373
},
374
error: function(error, file) {
375
console.error('Worker error for file', file.name, ':', error);
376
},
377
before: function(file) {
378
// Check file size and conditionally use worker
379
if (file.size < 1024 * 1024) { // Less than 1MB
380
return { config: { worker: false } }; // Use main thread
381
}
382
// Use worker for larger files (default config)
383
}
384
});
385
```
386
387
### Browser Compatibility
388
389
Web worker support varies by browser and environment.
390
391
```javascript { .api }
392
// Check comprehensive worker support
393
function checkWorkerSupport() {
394
return Papa.WORKERS_SUPPORTED &&
395
typeof Worker !== 'undefined' &&
396
typeof Blob !== 'undefined' &&
397
typeof URL !== 'undefined';
398
}
399
```
400
401
**Usage Examples:**
402
403
```javascript
404
function parseWithBestAvailableMethod(file) {
405
if (checkWorkerSupport()) {
406
console.log('Using web worker for optimal performance');
407
Papa.parse(file, {
408
worker: true,
409
header: true,
410
complete: handleResults
411
});
412
} else {
413
console.log('Web workers not fully supported, using main thread');
414
415
// Use chunked processing to prevent blocking
416
Papa.parse(file, {
417
header: true,
418
chunk: function(result) {
419
// Process in smaller chunks to maintain responsiveness
420
setTimeout(() => processChunk(result.data), 0);
421
},
422
complete: handleResults
423
});
424
}
425
}
426
427
function processChunk(chunkData) {
428
// Process chunk with timeout to yield control
429
chunkData.forEach((row, index) => {
430
if (index % 100 === 0) {
431
// Yield control every 100 rows
432
setTimeout(() => processRow(row), 0);
433
} else {
434
processRow(row);
435
}
436
});
437
}
438
```