Skip to content

Instantly share code, notes, and snippets.

@burnpiro
Last active August 9, 2019 18:48
Show Gist options
  • Save burnpiro/fec834b8473ffecd439ae5c98855bc61 to your computer and use it in GitHub Desktop.
Save burnpiro/fec834b8473ffecd439ae5c98855bc61 to your computer and use it in GitHub Desktop.
Simple React Fiber Internals

run following code with

d8 --trace-ic --allow-natives-syntax --trace-maps index.js
const N = 100000;

class Component {
	constructor() {
		this.name = 'Component';
	}

	render () {}
}

class MyComponent1 extends Component {
	constructor() {
		super();
		this.name = 'My Component1';
	}

	render () {
		return '<span>Test 1</span>'
	}
}

class MyComponent2 extends Component {
	constructor() {
		super();
		this.name = 'My Component2';
	}

	render () {
		return '<span>Test 2</span>'
	}
}

class MyComponent3 extends Component {
	constructor() {
		super();
		this.name = 'My Component3';
	}

	render () {
		return '<span>Test 3</span>'
	}
}

function createElement(element, ...rest) {
	return {
		type: element
	}
}

const ReactWorkTags = {
	ClassComponent: 1,
	HostComponent: 5,
}

class FiberNode {
    constructor(tag, ...rest) {
        this.tag = tag;
        this.name = 'Fiber';
        // Other important staff...
    }
}

const createFiberFromElement = function(element, ...rest) {
  // another simplification, there are different WorkTags
  const fiberTag = typeof element.type === 'string' ? ReactWorkTags.HostComponent : ReactWorkTags.ClassComponent;
  const fiber = new FiberNode(fiberTag, ...rest);
  fiber.type = element.type;
  
  return fiber;
}

const comp1 = createElement(MyComponent1);
const comp2 = createElement(MyComponent2);
const comp3 = createElement(MyComponent3);
const comp4 = createElement('div');
const comp5 = createElement('span');

const fiber1 = createFiberFromElement(comp1);
const fiber2 = createFiberFromElement(comp2);
const fiber3 = createFiberFromElement(comp3);
const fiber4 = createFiberFromElement(comp4);
const fiber5 = createFiberFromElement(comp5);

console.log(%HaveSameMap(fiber1, fiber2)); // true
console.log(%HaveSameMap(fiber1, fiber3)); // true
console.log(%HaveSameMap(fiber1, fiber4)); // true
console.log(%HaveSameMap(fiber1, fiber5)); // true
console.log(%HaveSameMap(fiber2, fiber3)); // true
console.log(%HaveSameMap(fiber2, fiber4)); // true
console.log(%HaveSameMap(fiber3, fiber4)); // true


const unOptComp1 = new MyComponent1();
const unOptComp2 = new MyComponent2();
const unOptComp3 = new MyComponent3();
const unOptComp4 = {
	type: 'div',
	name: 'DIV Component',
};
const unOptComp5 = {
	type: 'span',
	name: 'Span Component',
	customProp: true,
};

console.log(%HaveSameMap(unOptComp1, unOptComp2)); // true
console.log(%HaveSameMap(unOptComp1, unOptComp3)); // true
console.log(%HaveSameMap(unOptComp1, unOptComp4)); // true
console.log(%HaveSameMap(unOptComp1, unOptComp5)); // true
console.log(%HaveSameMap(unOptComp2, unOptComp3)); // true
console.log(%HaveSameMap(unOptComp2, unOptComp4)); // true
console.log(%HaveSameMap(unOptComp3, unOptComp4)); // true

function doSomeWork(unitOfWork) {
	let result = '';
	for(let i=0; i<1000; i += 1) {
		// work that takes a while
		result += unitOfWork.name;
	}
	return unitOfWork;
}
function doSomeWork2(unitOfWork) {
	let result = '';
	for(let i=0; i<1000; i += 1) {
		// work that takes a while
		result += unitOfWork.name;
	}
	return unitOfWork;
}

const startComp = Date.now();
for(let i=0; i<N; i += 1) {
	doSomeWork(unOptComp1);
	doSomeWork(unOptComp2);
	doSomeWork(unOptComp3);
	doSomeWork(unOptComp4);
	doSomeWork(unOptComp5);
}
console.log("test with components:", Date.now() - startComp, "ms.");

const startFiber = Date.now();
for(let i=0; i<N; i += 1) {
	doSomeWork2(fiber1);
	doSomeWork2(fiber2);
	doSomeWork2(fiber3);
	doSomeWork2(fiber4);
	doSomeWork2(fiber5);
}
console.log("test with fibers:", Date.now() - startFiber, "ms.");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment