React optimization

上次聽了Parker 的 slides
Why we use the client-side framework

覺得有點東西,深受啟發

想說也可以來講講關於這方面的東東

就這麼恰巧ㄉ看到了這個 tech talk

所以我們這次就來談談 react 及 angular

的底層優化吧!

monomorphic

bit fields

bloom filters

先來溫故知新談一下 react fiber

react fiber -> react v.16

解決什麼問題: 以往的更新機制會造成畫面卡頓

react fiber 重寫了 core 將更新的過程『切片化』,讓

更新可以以更有效率的方式被執行

recursive -> whileLoop

function workLoop(nextUnitOfWork) {
  while (
    !!nextUnitOfWork
    // && 接下來的時間是否還夠用以及
    // 是否有更高優先級的任務
  ) {
    nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
  }
}

Link List + DFS

但還有一些不常被提及到的優化手段

也是今日的主題

shape(hidden class) & monomorphic 

不過在此之前讓我們先聊聊框架

是怎麼處理更新 Node 這件事

function updateNode(node, ...) {
	let value = node.property
    ....
}

In framework, this function

is often called or used

Property Access

Locating of an object's property

in memory

is a complicated process

Why is complicated?

shape (hidden class)

const obj = {
  x: 1,
  y: 1,
};

Because Javascript is a dynamic language, 

V8 enginge need some hack to improve execution efficiency

const obj1 = {
  x: 1,
  y: 1,
};
const obj2 = {
  x: 3,
  y: 4,
};
const obj3 = {
  x: 5,
  y: 6,
};

shape helps reduce memory footprint

const obj1 = {
  x: 1,
  y: 1,
};
const obj2 = {};
obj2.x = 1;
obj2.y = 1;

console.log(%HaveSameMap(obj1, obj2)); 
//false

Transition chain

const obj2 = {};
// Shape M0
// add "x": Transition to M1, offset 12

obj2.x = 1;
// Shape M1
// "x": at offset 12
// add "y": Transition to M2, offset 16

obj2.y = 1;
// Shape M2
// "x": at offset 12
// "y": at offset 16

Inline Cache

Inline Cache

function getX(o) => o.x;

Every single Javascript function is represented internally by the object called closure

  • Monomorphic: function has been called in one type of shape
  • Polymorphic:  2~4 type
  • Megamorphic: 5 ⬆️

Frameworks enforce the same shape(hidden class)

for fiber node to enable monomorphic property access

these frameworks merge everything into one data structure, one class

and use one tag to distinguish between types of node

monomorphic property access

function beginWork(fiberNode, ...) {
	...
    switch(fiberNode.tag) {
    	case FunctionalComponent: {...}	
        case ClassComponent: {...}
        case HostComponent:
        	return updateHostComponent(fiberNode, ...);
        case ...
    }
}

Bit fields

use case: permission, multiple select

Advantages of bit fields

  • No need to allocate memory for JS objects and shapes
  • Simplified garbage collection
  • Smaller and contiguous memory usage
  • Fast access using a single bitwise operator

Bloom Filter

data structure that answers the question

Is element in the set?

Definitely No

Maybe

Time & Space complexity O(1)

data 

hash

mod

Bit Array

hashed data

get m position

["Jay", "Liz",  "Ariel",  "Ayo"]

let calculatBit1Value = (value) => value.charCodeAt(0) % 8

Set bits for "Jay"

const bitNumber = calculateBitValue('Jay');
bloomFilter = bloomFilter | bitNumber;

Check bits for "Jay"

Jay (2)

const bitNumber = calculateBitValue('Jay');
cosnt isInTheSet = (bloomFilter & bitNumber) !== 0;

Jay (2)

Ariel (0)

Ayo (0)

Liz (4)

Collision

Less slots, more collision

Use case

React optimization

By Jay Chou

React optimization

  • 295