<script type="module">
import { produce } from 'https://cdn.jsdelivr.net/npm/immer@10.1.1/+esm';
window.immerProduce = produce;
</script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uuid@10.0.0/dist/index.min.js"></script>
const numSiblings = 500;
const depth = 3;
state = {
data: {
data1: {
data2: 'test',
siblings: Array.from({
length: numSiblings
}).map(() => ({
id: crypto.randomUUID()
})),
children: Array.from({
length: depth
}).map(() => ({
id: crypto.randomUUID(),
data: {
data1: {
data2: 'test',
siblings: Array.from({
length: numSiblings
}).map(() => ({
id: crypto.randomUUID()
})),
children: Array.from({
length: depth
}).map(() => ({
id: crypto.randomUUID(),
data: {
data1: {
data2: 'test',
siblings: Array.from({
length: numSiblings
}).map(() => ({
id: crypto.randomUUID()
})),
children: Array.from({
length: depth
}).map(() => ({
id: crypto.randomUUID(),
data: {
data1: {
data2: 'test',
siblings: Array.from({
length: numSiblings
}).map(() => ({
id: crypto.randomUUID()
})),
},
},
})),
},
},
})),
},
},
})),
},
data3: Array.from({
length: 1000
}).map(() => ({})),
},
};
const result = immerProduce(state, draft => {
draft.data.data1.data2 = 'updated';
for (let i; i < 500; i++) {
draft.data.data1.siblilngs[i] = { id: uuidv4() };
}
})
const result = structuredClone(state);
result.data.data1.data2 = 'updated';
for (let i; i < 500; i++) {
result.data.data1.siblilngs[i] = { id: uuidv4() };
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
produce | |
structuredClone |
Test name | Executions per second |
---|---|
produce | 359664.6 Ops/sec |
structuredClone | 141.1 Ops/sec |
Measuring the performance of two different approaches for deep cloning and updating objects in JavaScript, structuredClone
and immer
. Let's break down what's being tested and compare the options.
Benchmarked libraries:
Benchmarked scenarios:
The test cases consist of two benchmarks:
produce
: This benchmark uses the immer
library to update an object by creating a new draft and updating its properties. The script creates a deep clone of an object using produce
, updates it, and then creates 500 new objects with unique IDs.structuredClone
: This benchmark uses the structuredClone
function to perform a deep copy of an object, updates it, and then creates 500 new objects with unique IDs.Comparison:
Both approaches achieve similar results, but they differ in their implementation:
structuredClone
for large objects due to its mutable draft approach.immer
).produce
function.Other considerations:
immer
is likely a better choice due to its built-in support for immutable updates.structuredClone
might be more suitable due to its optimized implementation and faster execution times.Alternatives:
JSON
object to create a deep clone of an object. However, it has limitations, such as:JSON.parse(JSON.stringify(obj))
, it requires an additional import.In conclusion, the choice between structuredClone
and immer
(or other libraries) depends on your specific use case, performance requirements, and personal preference. If you need to clone and update large objects with complex data structures, consider using a library like Immer or exploring alternative approaches like JSON.parse(JSON.stringify(obj))
.