Skip to content

Commit

Permalink
FY-215/perf(changedBits): remove
Browse files Browse the repository at this point in the history
changedBits 삭제

facebook/react#20953
  • Loading branch information
JinmuGo committed Mar 17, 2024
1 parent b3d4f78 commit f423bed
Show file tree
Hide file tree
Showing 16 changed files with 39 additions and 371 deletions.
17 changes: 3 additions & 14 deletions srcs/context/constructor/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@
/**
*
* @param {Symbol} $$typeof
* @param {Function} _calculateChangedBits
* @param {any} _currentValue
* @param {any} _currentValue2
* @param {Number} _threadCount
* @param {TProvider} Provider
* @param {TConsumer} Consumer
*/
const context = class {
constructor($$typeof, _calculateChangedBits, _currentValue, _currentValue2, _threadCount, Provider, Consumer) {
constructor($$typeof, _currentValue, _currentValue2, _threadCount, Provider, Consumer) {
this.$$typeof = $$typeof;
this._calculateChangedBits = _calculateChangedBits;
this._currentValue = _currentValue;
this._currentValue2 = _currentValue2;
this._threadCount = _threadCount;
Expand All @@ -28,23 +26,14 @@ const context = class {
/**
*
* @param {Symbol} $$typeof
* @param {Function} _calculateChangedBits
* @param {any} _currentValue
* @param {any} _currentValue2
* @param {Number} _threadCount
* @param {TProvider} Provider
* @param {TConsumer} Consumer
*/
const createContextInst = (
$$typeof,
calculateChangedBits,
currentValue,
currentValue2,
threadCount,
Provider,
Consumer
) => {
return new context($$typeof, calculateChangedBits, currentValue, currentValue2, threadCount, Provider, Consumer);
const createContextInst = ($$typeof, currentValue, currentValue2, threadCount, Provider, Consumer) => {
return new context($$typeof, currentValue, currentValue2, threadCount, Provider, Consumer);
};

export default createContextInst;
11 changes: 4 additions & 7 deletions srcs/context/constructor/contextItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,22 @@
/**
*
* @param {TContext} context
* @param {number} observedBits
* @param {import("../../../type/TContextItem").TContextItem | null} next
*/
const contextItem = class {
constructor(context, observedBits, next) {
constructor(context, next) {
this.context = context;
this.observedBits = observedBits;
this.next = next;
}
};

/**
*
* @param {TContext} context
* @param {number} observedBits
* @param {import("../../../type/TContextItem").TContextItem | null} next
* @param {number, * @param {import("../../../type/TContextItem").TContextItem | null}} next
*/
const createContextItem = (context, observedBits, next) => {
return new contextItem(context, observedBits, next);
const createContextItem = (context, next) => {
return new contextItem(context, next);
};

export default createContextItem;
4 changes: 2 additions & 2 deletions srcs/context/core/contextCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { createCursor } from "../../fiber/fiberStack.js";
* 개발 모드에서 warning을 출력하기 위해 사용된다.
* @property {Fiber | null} currentlyRenderingFiber - 현재 렌더링 중인 fiber를 가리킨다.
* @property {TContextItem | null} lastContextDependency - 마지막으로 의존성을 가진 contextItem를 가리킨다.
* @property {TContext | null} lastContextWithAllBitsObserved - 마지막으로 모든 bit를 관찰한 context를 가리킨다.
* @property {TContext | null} lastFullyObservedContext - 마지막으로 완전히 관찰된 context를 가리킨다.
*/
export default {
valueCursor: createCursor(null),
rendererSigil: undefined,
currentlyRenderingFiber: null,
lastContextDependency: null,
lastContextWithAllBitsObserved: null,
lastFullyObservedContext: null,
};
22 changes: 2 additions & 20 deletions srcs/context/createContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,17 @@ import createProvider from "./constructor/provider.js";
/**
*
* @param {any} defaultValue
* @param {Function | undefined} calculateChangedBits
* @see ReactNewContext-test.internal.js 1055 line
*
* @description - 단순히 context 객체를 생성하는 함수입니다. 그 과정에서
* Provider와 Consumer를 생성합니다.
*
* @description - calculateChangedBits
* 비트 마스킹을 사용하여 변경되었다면 Context.consumer를 re-render합니다. 그것을
* 클라이언트 코드에서 조정할 수 있도록 직접 second argument로 넘겨줄 수 있습니다.
* 관련 링크는 아래에 있습니다.
* @link https://dev.to/alexkhismatulin/react-context-a-hidden-power-3h8j
* @returns
*/
const createContext = (defaultValue, calculateChangedBits) => {
// client Code에서 calculateChangedBits를 넘겨주지 않았다면 null을 할당합니다.
if (calculateChangedBits === undefined) {
calculateChangedBits = null;
}

const createContext = (defaultValue) => {
// context Object를 생성합니다.
const context = createContextInst(
RFS_CONTEXT_TYPE,
calculateChangedBits,
defaultValue,
defaultValue,
0,
null,
null
);
const context = createContextInst(RFS_CONTEXT_TYPE, defaultValue, defaultValue, 0, null, null);

// Provider 객체 생성.
const provider = createProvider(RFS_PROVIDER_TYPE, context);
Expand Down
34 changes: 8 additions & 26 deletions srcs/context/newContext.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { MAX_SIGNED_31_BIT_INT } from "../const/CExpirationTime.js";
import { pop, push } from "../fiber/fiberStack.js";
import { markWorkInProgressReceivedUpdate } from "../work/beginWork.js";
import createContextItem from "./constructor/contextItem.js";
import contextCore from "./core/contextCore.js";
// TODO: import { isPrimaryRenderer } from "react-dom";
// ReactDOMHostConfig에서 isPrimaryRenderer를 가져옵니다.
// RFS의 ReactDOMHostConfig에서 isPrimaryRenderer를 가져옵니다.

/**
*
Expand Down Expand Up @@ -102,7 +101,7 @@ const scheduleWorkOnParentPath = (parent, renderExpirationTime) => {
* // 이때 변경되었다는 것을 알리는 용도로 해당 fiber의 expirationTime을 변경합니다.
* @returns
*/
const propagateContextChange = (workInProgress, context, changedBits, renderExpirationTime) => {
const propagateContextChange = (workInProgress, context, renderExpirationTime) => {
let fiber = workInProgress.child;
if (fiber !== null) {
// Set the return pointer of the child to the work-in-progress fiber.
Expand All @@ -122,14 +121,9 @@ const propagateContextChange = (workInProgress, context, changedBits, renderExpi
// Check if the context matches.
// 현재 fiber의 context list중에서 현재 변경된 context와 일치하는 context가 있는지 확인합니다.
// 만약에 일치하면서 변경되었다면 해당 fiber를 re-render해야합니다.
if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
if (dependency.context === context) {
// Match! Schedule an update on this fiber.

if (fiber.tag === ClassComponent) {
// NOTE: we don't implement ClassComponent.
// 저희는 함수형 컴포넌트만 사용하기 때문에 해당 부분은 구현하지 않습니다.
}

// fiber를 re-render하기 때문에 해당 fiber의 expirationTime을 변경합니다.
if (fiber.expirationTime < renderExpirationTime) {
fiber.expirationTime = renderExpirationTime;
Expand Down Expand Up @@ -161,12 +155,10 @@ const propagateContextChange = (workInProgress, context, changedBits, renderExpi
} else if (fiber.tag === ContextProvider) {
// Don't scan deeper if this is a matching provider
nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
} else if (fiber.tag === DehydreatedFragment) {
// NOTE: we don't implement DehydreatedFragment.
// it's server components
} else {
nextFiber = fiber.child;
}
// NOTE: we don't implement DehydreatedFragment.

// nextFier가 null이라는 것은 더이상 child가 없다는 것.
// 그러면 sibling을 확인하고 그마저도 존재하지 않는다면 parent로 올라갑니다.
Expand Down Expand Up @@ -210,7 +202,7 @@ const propagateContextChange = (workInProgress, context, changedBits, renderExpi
const prepareToReadContext = (workInProgress, renderExpirationTime) => {
contextCore.currentlyRenderingFiber = workInProgress;
contextCore.lastContextDependency = null;
contextCore.lastContextWithAllBitsObserved = null;
contextCore.lastFullyObservedContext = null;

// component는 여러개의 context를 사용할 수 있습니다.
// dependencies는 해당 fiber에서 사용되는 컨텍스트의 리스트입니다.
Expand Down Expand Up @@ -240,21 +232,11 @@ const prepareToReadContext = (workInProgress, renderExpirationTime) => {
* 이 함수에서 context의 값을 읽습니다.
* @returns
*/
const readContext = (context, observedBits) => {
if (contextCore.lastContextWithAllBitsObserved === context) {
const readContext = (context) => {
if (contextCore.lastFullyObservedContext === context) {
// Nothing to do. We already observe everything in this context.
} else if (observedBits === false || observedBits === 0) {
// Do not observe any updates.
} else {
let resolvedObservedBits;
if (typeof observedBits !== "number" || observedBits === MAX_SIGNED_31_BIT_INT) {
contextCore.lastContextWithAllBitsObserved = context;
resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
} else {
resolvedObservedBits = observedBits;
}

const contextItem = createContextItem(context, resolvedObservedBits, null);
const contextItem = createContextItem(context, null);

if (contextCore.lastContextDependency === null) {
// this is the first dependency for this component. Create a new list.
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions srcs/fiber/childFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,8 @@ const ChildReconciler = (shouldTrackSideEffects) => {
//그리고 마지막으로 배치가 바뀌지 않은 파이버의 인덱스를 가르키는 변수를 업데이트해야됨
//NOTE: place-배치란 list에서의 배치를 의미함-> 이것은 array에서 index를 바꾸는 것이
//NOTE:아닌 인접한것을 기준을 의미함 (fiber 자체가 list구조이므로)
//NOTE: placeChild의 알고리즘은 placeChild를 참고하면
//NOTE: placeChild의 알고리즘은 placeChild를 참고하면

lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);

//딱 한번만 resultFirstFiber를 세팅해야됨
Expand Down
3 changes: 1 addition & 2 deletions srcs/hooks/core/renderWithHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const finishRenderingHooks = (hookCore, hookExpirationTime) => {
hookCore.sideEffectTag = 0;

// finish hookExpirationTime
// TODO: import NoWork
hookExpirationTime.renderExpirationTime = NoWork;
hookExpirationTime.remainingExpirationTime = NoWork;
};
Expand Down Expand Up @@ -55,7 +54,7 @@ const renderWithHooks = (current, workInProgress, Component, props, refOrContext
}

// Component render
// TODO: ?? 그러면 props랑 context랑 같이 들어오는데? 이게 뭐지.
// NOTE: refOrContext를 넣어주는 이유는 ClassComponent 때문.
let children = Component(props, refOrContext);

// render phase시에 update가 발생했다면 해당 Component를 다시 렌더링합니다.
Expand Down
17 changes: 8 additions & 9 deletions srcs/hooks/shared/dispatchAction.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { NoWork } from "../../const/CExpirationTime.js";
import is from "../../shared/objectIs.js";
import { computeExpirationForFiber, requestCurrentTimeForUpdate, scheduleWork } from "../../work/workloop.js";
import createHookUpdate from "../constructor/hookUpdate.js";
import hookCore from "../core/hookCore.js";
import hookExpirationTime from "../core/hookExpirationTime.js";
import hookRenderPhase from "../core/hookRenderPhase.js";
import hookRenderPhase, { RE_RENDER_LIMIT } from "../core/hookRenderPhase.js";
import enqueueRenderPhaseUpdate from "./enqueueRenderPhaseUpdate.js";

/**
Expand All @@ -26,6 +27,10 @@ import enqueueRenderPhaseUpdate from "./enqueueRenderPhaseUpdate.js";
*/

const dispatchAction = (fiber, queue, action) => {
if (hookRenderPhase.numberOfReRenders < RE_RENDER_LIMIT) {
throw new Error("Too many re-renders. React limits the number of renders to prevent an infinite loop.");
}

const alternate = fiber.alternate;

// TODO: isRenderPhaseUpdate 함수로 Refactor
Expand Down Expand Up @@ -64,14 +69,9 @@ const dispatchAction = (fiber, queue, action) => {
}
} else {
// this is an idle status update

// TODO: Implement this function. requestCurrentTimeForUpdate
const currentTime = requestCurrentTimeForUpdate();
// TODO: Implement this function. requestCurrentSuspenseConfig 사용하지 않을 수 있음
const suspenseConfig = requestCurrentSuspenseConfig();
// TODO: Implement this function. computeExpirationForFiber
// hookupdate에서 suspenseConfig를 사용하고 있는데 이후 updateReducer의 markRenderEventTimeAndConfig에서만 사용된다
const expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
const expirationTime = computeExpirationForFiber(currentTime, fiber);

const update = createHookUpdate(expirationTime, suspenseConfig, action, null, null, null);
enqueueRenderPhaseUpdate(queue, update);
Expand All @@ -94,7 +94,7 @@ const dispatchAction = (fiber, queue, action) => {
// The queue is currently empty, which means we can eagerly compute the
// next state before entering the render phase. If the new state is the
// same as the current state, we may be able to bail out entirely.
//NOTE:여기서의 Bailout은 scheduleWork를 호출하지 않는다는 것인듯.
//NOTE: 여기서의 Bailout은 scheduleWork를 호출하지 않는다는 것인듯.
const lastRenderedReducer = queue.lastRenderedReducer;
if (lastRenderedReducer !== null) {
try {
Expand All @@ -113,7 +113,6 @@ const dispatchAction = (fiber, queue, action) => {
}
}
}
// TODO: Implement this function. scheduleWork
scheduleWork(fiber, expirationTime);
}
};
Expand Down
4 changes: 2 additions & 2 deletions srcs/hooks/useContext/useContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import hookCore from "../core/hookCore.js";
* @param {TContext} context
* @param {number | undefined} observedBits
*/
const useContext = (context, observedBits) => {
return hookCore.RfsCurrentDispatcher.current.useContext(context, observedBits);
const useContext = (context) => {
return hookCore.RfsCurrentDispatcher.current.useContext(context);
};

export default useContext;
1 change: 0 additions & 1 deletion srcs/hooks/useEffect/useEffectImpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ export const updateEffectImpl = (fiberFlags, hookFlags, create, deps) => {
//가정4. 지우지 못하는 이유는 circularlist
//가정4. (모름) 가르키는 곳을 바꿔서 거기부터 처리한다.
pushEffect(NoHookEffect, create, inst, nextDeps);
// NOTE: 16.12.0에서는 새롭게 생성된 effect를 사용하지 않는데, 이건 reconciler쪽을 봐야할 것 같다.
return;
}
}
Expand Down
10 changes: 3 additions & 7 deletions srcs/hooks/useReducer/useReducerImpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { mountWorkInProgressHook, updateWorkInProgressHook } from "../core/workI
import { createHookUpdateQueue } from "../constructor/index.js";
import hookExpirationTime from "../core/hookExpirationTime.js";
import dispatchAction from "../shared/dispatchAction.js";
import { markWorkInProgressReceivedUpdate } from "../../work/beginWork.js";
import { markRenderEventTimeAndConfig, markUnprocessedUpdateTime } from "../../work/workloop.js";

/**
* @param {THookObject} hook
Expand Down Expand Up @@ -55,9 +57,6 @@ const updateReducerImpl = (hook, reducer) => {
} while (update !== null);

if (is(newState, hook.memoizedState) === false) {
// TODO: Implement this function.
// 함수 구현이 간단하긴 하지만 beginWork의 module scope를 참조해야 하기 때문에
// 이후 추가 구현을 위해 주석처리 하였습니다
markWorkInProgressReceivedUpdate();
}

Expand Down Expand Up @@ -115,13 +114,11 @@ const updateReducerImpl = (hook, reducer) => {

if (updateExpirationTime > hookExpirationTime.remainingExpirationTime) {
hookExpirationTime.remainingExpirationTime = updateExpirationTime;
// TODO: Implement this function.
markUnprocessedUpdateTime(hookExpirationTime.remainingExpirationTime);
}
} else {
// This update does have sufficient priority.
// TODO: implement this function.
markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
markRenderEventTimeAndConfig(updateExpirationTime);

if (update.eagerReducer === reducer) {
newState = update.eagerState;
Expand All @@ -140,7 +137,6 @@ const updateReducerImpl = (hook, reducer) => {
}

if (!is(newState, hook.memoizedState)) {
// TODO: Implement this function.
markWorkInProgressReceivedUpdate();
}

Expand Down
Loading

0 comments on commit f423bed

Please sign in to comment.