SlideShare a Scribd company logo
Immutable Libraries
for React
Simon Bächler, ti&m
Simon Bächler
ti&m
@simonbaechler
The Flux Pattern
Immutable Libraries for React
Redux
Immutable state
Redux requires
• Immutable objects for state
• Pure functions for reducers and selectors.
Immutable Libraries for React
With mutations
case ADD_VIDEO_TO_SERVICE:
state.profile.accounts[action.serviceId]
.videos[action.videoInfo.id] = action.videoInfo;
return state;
With Immer
case ADD_VIDEO_TO_SERVICE:
return produce(state, draft => {
draft.profile.accounts[action.serviceId]
.videos[action.videoInfo.id] = action.videoInfo;
});
Immer
• By Michel Weststrate (Released January 2018)
• Producer function: mutable copy of the state.
• Simple API: Only one function:
produce<S>(currentState: S, draft: (S) => void): S
• Partial application is possible (by providing a function as the
first argument).
• Auto Freezing in Dev mode.
• Requires a Proxy-Polyfill für IE11.
Immutable Libraries for React
With Immutable.js
case ADD_VIDEO_TO_SERVICE:
return state.setIn(
['profile', 'accounts', action.serviceId, 'videos', action.videoInfo.id],
action.videoInfo
);
Immutable.js
• By Facebook
• Uses a tree data type: Well suited for very large states.
• Comes with its own API. e.g. getters for accessing properties.
• Many helper methods for the Collection type.
• Lazy sequences and Records
• Requires a browser extension for debugging.
• The main developer has left Facebook.
• Immutable structures should not be mixed with JS structures
• toJS() is an expensive operation.
Tries
• Prefix tree
• The path is the key
• The leaf is the value
Updating a value
• Change the value of
'tea'.
Updating a value
• A new tree is created
(clone the root node)
• Only the leaves in the
path are re-created
• The old tree is still
there as long as a
reference is pointing
at it.
Immutable Libraries for React
https://medium.com/@dtinth/immutable-js-persistent-data-structures-and-structural-sharing-6d163fbd73d2
Code and
Performance
Adding nodes
state => {
for (let i = 0; i < 1000; i++) {
state = {
ids: [...state.ids, i],
map: {
...state.map,
[i]: {
a: 1,
b: "Some data here"
}
}
}
}
}
Adding nodes
state => {
for (let i = 0; i < 1000; i++) {
state = state.withMutations(draft => {
draft.update("ids", ids => ids.push(i))
draft.setIn(["map", i], Immutable.Map({
a: 1,
b: "Some data here"
}))
})
}
}
Adding nodes
state => {
for (let i = 0; i < 1000; i++) {
state = produce(state, draft => {
draft.ids.push(i)
draft.map[i] = {
a: 1,
b: "Some data here"
}
})
}
}
Update lists
0
40
80
120
160
JS ImmutableJS Immer
t(ms)
Update lists
0
300
600
900
1200
1500
JS ImmutableJS Immer Immer ES5
t(ms)
Update a tree (1.2M nodes)
Update a tree (1.2M nodes)
state => {
for (let i = 0; i < 1000; i++) {
k = getKey(i);
state = {
...state,
[k]: {
...state[k],
[k]: {
...state[k][k],
[k]: {
...state[k][k][k],
[k]: {
...state[k][k][k][k],
[k]: {
...state[k][k][k][k][k],
[k]: {
...state[k][k][k][k][k][k],
[k]: i
}
}
}
}
}
}
}
}
Update a tree (1.2M nodes)
state => {
for (let i = 0; i < 1000; i++) {
k = getKey(i);
state = state.setIn([k, k, k, k, k, k, k], i)
}
}
Update a tree (1.2M nodes)
state => {
for (let i = 0; i < 1000; i++) {
k = getKey(i);
state = produce(state, draft => {
draft[k][k][k][k][k][k][k] = i
})
}
}
Update a tree (1.2M nodes)
0
7.5
15
22.5
30
JS ImmutableJS Immer
t(ms)
Update a tree (1.2M nodes)
0
22.5
45
67.5
90
JS ImmutableJS Immer Immer ES5
t(ms)
Update a tree (1.2M nodes)
state => {
for (let i = 0; i < 1000; i++) {
selectId = i % childrenCount
state = {
...state,
children: state.children.map((n, j) => {
if (j !== selectId) {
return n
}
return {
...n,
children: n.children.map((n, j) => {
if (j !== selectId) {
return n
}
return {
...n,
children: n.children.map((n, j) => {
if (j !== selectId) {
return n
}
return {
...n,
children: n.children.map((n, j) => {
if (j !== selectId) {
return n
}
return {
...n,
children: n.children.map(
(n, j) => {
if (j !== selectId) {
return n
}
return {
...n,
children: n.children.map(
(n, j) => {
if (
j !==
selectId
) {
return n
}
return {
...n,
value:
n.value +
1
Update a tree (1.2M nodes)
state => {
for (let i = 0; i < 1000; i++) {
selectId = i % childrenCount
state = state.updateIn(
[
"children",
selectId,
"children",
selectId,
"children",
selectId,
"children",
selectId,
"children",
selectId,
"children",
selectId,
"value"
],
value => value + 1
)
}
}
Update a tree (1.2M nodes)
state => {
for (let i = 0; i < 1000; i++) {
selectId = i % childrenCount
state = produce(state, draft => {
draft
.children[selectId].children[selectId]
.children[selectId].children[selectId]
.children[selectId].children[selectId]
.value += 1
})
}
}
Update a tree (1.2M nodes)
0
5
10
15
20
25
30
35
40
JS ImmutableJS Immer
t(ms)
Update a tree (1.2M nodes)
0
30
60
90
120
150
JS ImmutableJS Immer Immer ES5
t(ms)
Summary
• Use a helper library for updating immutable state.
• Native JS is really fast on small and nested structures.
• Immutable.js shines on large, flat data structures but
comes with some downsides (API, overhead, deep
integration)
• Immer makes your code more readable and is about 2x
slower in ES6, but massively slower when transpiled to
ES5.

More Related Content

PPTX
DroidKnight 2018 State machine by Selaed class
PDF
How to separate frontend from a highload python project with no problems - Py...
PDF
Having fun with graphs, a short introduction to D3.js
PDF
Android mix Java and C++
PDF
Bindings: the zen of montage
DOCX
Create methods to_insert
PPTX
Using Arbor/ RGraph JS libaries for Data Visualisation
PDF
Mercado iOS & Swift vs Objective-C
DroidKnight 2018 State machine by Selaed class
How to separate frontend from a highload python project with no problems - Py...
Having fun with graphs, a short introduction to D3.js
Android mix Java and C++
Bindings: the zen of montage
Create methods to_insert
Using Arbor/ RGraph JS libaries for Data Visualisation
Mercado iOS & Swift vs Objective-C

What's hot (20)

PDF
Fun with D3.js: Data Visualization Eye Candy with Streaming JSON
PDF
GraphQL: APIs the New Way.
PPTX
array of object pointer in c++
PPTX
Sql server ___________session_20(ddl triggers)
PDF
Taming the browser with the YUI Dom Component
PDF
Machine Learning on GCP
PDF
High performance GPU computing with Ruby
PPTX
Luca Passani - Essential Tools for Mobile-Aware Web Professionals | Codemoti...
PDF
Forecast stock prices python
PDF
Reactive data visualisations with Om
PDF
pewPew<s>xxd
PDF
Functional Programming from OO perspective (Sayeret Lambda lecture)
PPTX
Vancouver Canada MuleSoft Meetup Nov 2020
PPTX
Classing up ES6 - Web Directions code 2015 (1)
PPTX
Kotlin Mullets
DOC
addition of two matrices
 
PDF
The Future of Qt Widgets
PPTX
Java card and flow layout
PDF
The Next Generation Qt Item Views
PDF
Combined presentation init
Fun with D3.js: Data Visualization Eye Candy with Streaming JSON
GraphQL: APIs the New Way.
array of object pointer in c++
Sql server ___________session_20(ddl triggers)
Taming the browser with the YUI Dom Component
Machine Learning on GCP
High performance GPU computing with Ruby
Luca Passani - Essential Tools for Mobile-Aware Web Professionals | Codemoti...
Forecast stock prices python
Reactive data visualisations with Om
pewPew<s>xxd
Functional Programming from OO perspective (Sayeret Lambda lecture)
Vancouver Canada MuleSoft Meetup Nov 2020
Classing up ES6 - Web Directions code 2015 (1)
Kotlin Mullets
addition of two matrices
 
The Future of Qt Widgets
Java card and flow layout
The Next Generation Qt Item Views
Combined presentation init
Ad

Similar to Immutable Libraries for React (20)

PPTX
PyCon SG x Jublia - Building a simple-to-use Database Management tool
PDF
Vuexと入力フォーム
PDF
Redux "Bad" Practices - A List of 13 Bad Practices and How to Avoid Them
PPTX
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
PDF
첫 리액트 경험기
KEY
Better Together: Building Scalable Real Time Collaborative Apps with Node.js
PDF
Func up your code
PDF
Crossing platforms with JavaScript & React
PDF
Compose Async with RxJS
PDF
State managment in a world of hooks
PPTX
AWS IoTで家庭内IoTをやってみた【JAWS DAYS 2016】
PDF
React new features and intro to Hooks
PDF
Taming forms with React
PPTX
Managing Complex UI using xState
PDF
NoSQL meets Microservices
PDF
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
PDF
Introduction to Redux
PDF
Data in Motion: Streaming Static Data Efficiently
PPT
GHC Participant Training
PPTX
Svcc 2013-d3
PyCon SG x Jublia - Building a simple-to-use Database Management tool
Vuexと入力フォーム
Redux "Bad" Practices - A List of 13 Bad Practices and How to Avoid Them
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
첫 리액트 경험기
Better Together: Building Scalable Real Time Collaborative Apps with Node.js
Func up your code
Crossing platforms with JavaScript & React
Compose Async with RxJS
State managment in a world of hooks
AWS IoTで家庭内IoTをやってみた【JAWS DAYS 2016】
React new features and intro to Hooks
Taming forms with React
Managing Complex UI using xState
NoSQL meets Microservices
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Introduction to Redux
Data in Motion: Streaming Static Data Efficiently
GHC Participant Training
Svcc 2013-d3
Ad

More from stbaechler (8)

PPTX
Distributed apps
PPTX
Javascript Bundling and modularization
PPTX
Testing React Applications
PPTX
User stories schreiben
PPTX
Nested sets
PPTX
Microformats
PPTX
Zeitplanung mit PERT
PPTX
Bower Paketmanager
Distributed apps
Javascript Bundling and modularization
Testing React Applications
User stories schreiben
Nested sets
Microformats
Zeitplanung mit PERT
Bower Paketmanager

Recently uploaded (20)

PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
System and Network Administraation Chapter 3
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Essential Infomation Tech presentation.pptx
PPTX
Introduction to Artificial Intelligence
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
L1 - Introduction to python Backend.pptx
PDF
Digital Strategies for Manufacturing Companies
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
AI in Product Development-omnex systems
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Odoo Companies in India – Driving Business Transformation.pdf
System and Network Administraation Chapter 3
How to Choose the Right IT Partner for Your Business in Malaysia
CHAPTER 2 - PM Management and IT Context
Operating system designcfffgfgggggggvggggggggg
Essential Infomation Tech presentation.pptx
Introduction to Artificial Intelligence
Understanding Forklifts - TECH EHS Solution
L1 - Introduction to python Backend.pptx
Digital Strategies for Manufacturing Companies
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Design an Analysis of Algorithms I-SECS-1021-03
Upgrade and Innovation Strategies for SAP ERP Customers
Wondershare Filmora 15 Crack With Activation Key [2025
AI in Product Development-omnex systems
PTS Company Brochure 2025 (1).pdf.......
Navsoft: AI-Powered Business Solutions & Custom Software Development
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
VVF-Customer-Presentation2025-Ver1.9.pptx

Immutable Libraries for React

  • 6. Redux requires • Immutable objects for state • Pure functions for reducers and selectors.
  • 9. With Immer case ADD_VIDEO_TO_SERVICE: return produce(state, draft => { draft.profile.accounts[action.serviceId] .videos[action.videoInfo.id] = action.videoInfo; });
  • 10. Immer • By Michel Weststrate (Released January 2018) • Producer function: mutable copy of the state. • Simple API: Only one function: produce<S>(currentState: S, draft: (S) => void): S • Partial application is possible (by providing a function as the first argument). • Auto Freezing in Dev mode. • Requires a Proxy-Polyfill für IE11.
  • 12. With Immutable.js case ADD_VIDEO_TO_SERVICE: return state.setIn( ['profile', 'accounts', action.serviceId, 'videos', action.videoInfo.id], action.videoInfo );
  • 13. Immutable.js • By Facebook • Uses a tree data type: Well suited for very large states. • Comes with its own API. e.g. getters for accessing properties. • Many helper methods for the Collection type. • Lazy sequences and Records • Requires a browser extension for debugging. • The main developer has left Facebook. • Immutable structures should not be mixed with JS structures • toJS() is an expensive operation.
  • 14. Tries • Prefix tree • The path is the key • The leaf is the value
  • 15. Updating a value • Change the value of 'tea'.
  • 16. Updating a value • A new tree is created (clone the root node) • Only the leaves in the path are re-created • The old tree is still there as long as a reference is pointing at it.
  • 20. Adding nodes state => { for (let i = 0; i < 1000; i++) { state = { ids: [...state.ids, i], map: { ...state.map, [i]: { a: 1, b: "Some data here" } } } } }
  • 21. Adding nodes state => { for (let i = 0; i < 1000; i++) { state = state.withMutations(draft => { draft.update("ids", ids => ids.push(i)) draft.setIn(["map", i], Immutable.Map({ a: 1, b: "Some data here" })) }) } }
  • 22. Adding nodes state => { for (let i = 0; i < 1000; i++) { state = produce(state, draft => { draft.ids.push(i) draft.map[i] = { a: 1, b: "Some data here" } }) } }
  • 25. Update a tree (1.2M nodes)
  • 26. Update a tree (1.2M nodes) state => { for (let i = 0; i < 1000; i++) { k = getKey(i); state = { ...state, [k]: { ...state[k], [k]: { ...state[k][k], [k]: { ...state[k][k][k], [k]: { ...state[k][k][k][k], [k]: { ...state[k][k][k][k][k], [k]: { ...state[k][k][k][k][k][k], [k]: i } } } } } } } }
  • 27. Update a tree (1.2M nodes) state => { for (let i = 0; i < 1000; i++) { k = getKey(i); state = state.setIn([k, k, k, k, k, k, k], i) } }
  • 28. Update a tree (1.2M nodes) state => { for (let i = 0; i < 1000; i++) { k = getKey(i); state = produce(state, draft => { draft[k][k][k][k][k][k][k] = i }) } }
  • 29. Update a tree (1.2M nodes) 0 7.5 15 22.5 30 JS ImmutableJS Immer t(ms)
  • 30. Update a tree (1.2M nodes) 0 22.5 45 67.5 90 JS ImmutableJS Immer Immer ES5 t(ms)
  • 31. Update a tree (1.2M nodes)
  • 32. state => { for (let i = 0; i < 1000; i++) { selectId = i % childrenCount state = { ...state, children: state.children.map((n, j) => { if (j !== selectId) { return n } return { ...n, children: n.children.map((n, j) => { if (j !== selectId) { return n } return { ...n, children: n.children.map((n, j) => { if (j !== selectId) { return n } return { ...n, children: n.children.map((n, j) => { if (j !== selectId) { return n } return { ...n, children: n.children.map( (n, j) => { if (j !== selectId) { return n } return { ...n, children: n.children.map( (n, j) => { if ( j !== selectId ) { return n } return { ...n, value: n.value + 1
  • 33. Update a tree (1.2M nodes) state => { for (let i = 0; i < 1000; i++) { selectId = i % childrenCount state = state.updateIn( [ "children", selectId, "children", selectId, "children", selectId, "children", selectId, "children", selectId, "children", selectId, "value" ], value => value + 1 ) } }
  • 34. Update a tree (1.2M nodes) state => { for (let i = 0; i < 1000; i++) { selectId = i % childrenCount state = produce(state, draft => { draft .children[selectId].children[selectId] .children[selectId].children[selectId] .children[selectId].children[selectId] .value += 1 }) } }
  • 35. Update a tree (1.2M nodes) 0 5 10 15 20 25 30 35 40 JS ImmutableJS Immer t(ms)
  • 36. Update a tree (1.2M nodes) 0 30 60 90 120 150 JS ImmutableJS Immer Immer ES5 t(ms)
  • 38. • Use a helper library for updating immutable state. • Native JS is really fast on small and nested structures. • Immutable.js shines on large, flat data structures but comes with some downsides (API, overhead, deep integration) • Immer makes your code more readable and is about 2x slower in ES6, but massively slower when transpiled to ES5.

Editor's Notes

  • #4: Recommended Architecture Pattern for React Apps
  • #8: Javascript objects are mutable. When you want to update a deeply nested item it gets ugly.
  • #9: Mutations are not allowed in Redux.
  • #10: Immer provides a function called produce, which creates a mutable copy of the state.
  • #13: Immutable provides the function setIn which takes an array of keys for the path (keys can be anything).
  • #18: Structure of an Immutable Map with 100'000 entries. During an update, only the yellow nodes are re-created. A native Javascript object would copy all properties.
  • #19: There are different implementations for the trees and nodes. Immutable.js choses the best one transparently depending on the structure of the tree.
  • #21: Native JS Code State has a list and a map. We add 1000 items to each.
  • #22: Immutable.js code
  • #23: Immer code
  • #24: 106 3 160 1150
  • #25: 106 3 160 1150
  • #26: The tree has 6 levels with 9 children per node. It is only made of Javascript objects.
  • #27: The tree is only made of objects. The native Javascript code.
  • #28: The immutable.js code.
  • #29: The immer code.
  • #30: 4 3 7 90
  • #31: 4 3 7 90
  • #32: The tree has 6 levels with 9 children per node. Every node has a 'children' property that contains an array of child nodes.
  • #33: Javascript code
  • #34: Immutable.js code. Immutable.js gives you updateIn.
  • #35: Immer code.
  • #36: 2 3 20 120
  • #37: 2 3 20 120