0

I have an HTML table with different columns and rows. The table can be edited inline by a user. When a user edits the table, I calculate some sums on the rows of table.

The function that calculates the sums was in the main script and took a lot of time making the browser unresponsive. To solve this performance issue, I have created a web worker in JavaScript to calculate the sums on the table.

The problem is that the web worker cannot access the DOM. I'm looking for a way to pass a jQuery object table to the web worker.

If I try to pass the jQuery object I receive an error:

Uncaught DataCloneError: Failed to execute 'postMessage' on 'Worker': An object could not be cloned.

How I can pass the table to the Web Worker?

Thank you

[EDIT adding some further information ]

The sum take a long time because the table has a lot of rows and calculate different sums (total, subtotal,etc). The values to sum are stored in table (so worker need to access to table to perform the calculation).

My idea is to pass DOM object to worker to calculate sums. After calculation, worker return the sums to main thread in order to update values in the DOM.

fciri
  • 305
  • 7
  • 20
  • 3
    You should get the numbers you need, and pass them instead of the elements – adeneo Apr 29 '15 at 15:08
  • 3
    You can't pass DOM elements to the worker. – Felix Kling Apr 29 '15 at 15:12
  • 1
    "Calculating some sums" on the rows of a table really shouldn't take very long unless the table has tens of thousands of rows, or the rows are extremely long. Have you profiled your code to investigate what's taking up the time? – Pointy Apr 29 '15 at 15:14
  • @pointy the sums make UI not reacting in some cases. For this reason I want to use web worker. Keep in mind that when user modify data in the tables, we need to recalculare the sums. – fciri Apr 29 '15 at 15:47
  • 1
    @fciri yes, I understand. My question is, have you used the browser's profiling tools to investigate why the code is slow? Computing some sums really shouldn't take very long. – Pointy Apr 29 '15 at 15:49

2 Answers2

2

In short you cannot pass a DOM element to a worker. Only data, typically as strings, can be passed to webworkers not objects. You should extract your data from your table, wrap it up in an object, turn your object into json, send the json to the worker, process it and return some json back to the main thread.

bhspencer
  • 13,086
  • 5
  • 35
  • 44
  • thanks @bhspencer. Do you know if I can serialize via jquery object like a table in this way and reuse table in web worker just to read value? `var params = { table: $("#table").serialize() }` – fciri Apr 29 '15 at 15:53
  • 1
    I have never tried to serialize a DOM element to pass to a worker thread. I wouldn't expect it to work and even if it did I don't think it is a elegant solution. – bhspencer Apr 29 '15 at 15:56
  • 1
    I just tried to serialize a DOM element using JSON.stringify(myElement); and it failed because of the circular structure of the element. – bhspencer Apr 29 '15 at 15:59
  • 1
    A DOM element contains references to its parent and its children, and its children contain references back to it. You really don't want to try and serialize it. – bhspencer Apr 29 '15 at 16:01
1

you could do this remember you can pass string or numbers as objects. then loop through the number and keep receiving strings. then use table.innerHTML to change it.

const row = '<tr></tr>';
const worker = new Worker('worker.js');

worker.postmessage({'row': row});

worker.onmessage = function(e){

 const result = e.data.result;
 //do something

 };

worker.terminate();