Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 95 additions & 13 deletions exercises/06.rerenders/01.problem.memo/tests/memoized.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,70 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
const scriptToInject = `
<script>
let internals
const PerformedWorkFlag = 0b000000000000000000000000001
const UserCodeFiberTags = new Set([0, 1, 9, 11, 15])

let activeFallbackComponentNames = null

function isUserCodeFiberTag(tag) {
return UserCodeFiberTags.has(tag)
}

function getDisplayNameFromType(type) {
if (!type) return null

if (typeof type === 'function') {
return type.displayName || type.name || null
}

if (typeof type === 'object') {
if (typeof type.displayName === 'string' && type.displayName) {
return type.displayName
}

if (typeof type.render === 'function') {
return type.render.displayName || type.render.name || null
}

if (type.type) {
return getDisplayNameFromType(type.type)
}
}

return null
}

function getFiberDisplayName(fiber) {
return getDisplayNameFromType(fiber.type) || getDisplayNameFromType(fiber.elementType)
}

function didFiberRender(previousFiber, nextFiber) {
if (!previousFiber) return true
return (nextFiber.flags & PerformedWorkFlag) === PerformedWorkFlag
}

function collectRenderedComponentsFromCommit(root) {
if (!activeFallbackComponentNames || !root?.current) return

const stack = [root.current]
while (stack.length > 0) {
const fiber = stack.pop()
if (!fiber) continue

if (fiber.sibling) stack.push(fiber.sibling)
if (fiber.child) stack.push(fiber.child)

if (!isUserCodeFiberTag(fiber.tag)) continue
if (!didFiberRender(fiber.alternate, fiber)) continue

const componentName = getFiberDisplayName(fiber) ?? 'Anonymous'
activeFallbackComponentNames.push(componentName)
}
}

function enhanceExistingHook(existingHook) {
const originalInject = existingHook.inject
const originalCommitFiberRoot = existingHook.onCommitFiberRoot

existingHook.inject = (injectedInternals) => {
internals = injectedInternals
Expand All @@ -23,6 +84,12 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
return originalInject?.call(existingHook, injectedInternals) ?? 1
}

existingHook.onCommitFiberRoot = (...args) => {
const [, root] = args
collectRenderedComponentsFromCommit(root)
return originalCommitFiberRoot?.apply(existingHook, args)
}

return existingHook
}

Expand All @@ -34,7 +101,9 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
internals = injectedInternals
return 1 // Returning a number as React expects a renderer ID
},
onCommitFiberRoot: () => {},
onCommitFiberRoot: (_rendererId, root) => {
collectRenderedComponentsFromCommit(root)
},
onCommitFiberUnmount: () => {},
}
}
Expand All @@ -45,19 +114,32 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
throw new Error('🚨 React DevTools is not available')
}

internals.enableProfilerTimer = true
internals.enableProfilerCommitHooks = true
internals.injectProfilingHooks({
markComponentRenderStarted: (fiber) => {
componentNames.push(fiber.type.name || 'Anonymous')
},
})

await cb()
const supportsInjectedProfilingHooks =
typeof internals.injectProfilingHooks === 'function'

if (supportsInjectedProfilingHooks) {
internals.enableProfilerTimer = true
internals.enableProfilerCommitHooks = true
internals.injectProfilingHooks({
markComponentRenderStarted: (fiber) => {
componentNames.push(fiber.type.name || 'Anonymous')
},
})
} else {
activeFallbackComponentNames = componentNames
}

internals.enableProfilerTimer = false
internals.enableProfilerCommitHooks = false
internals.injectProfilingHooks(null)
try {
await cb()
} finally {
if (supportsInjectedProfilingHooks) {
internals.enableProfilerTimer = false
internals.enableProfilerCommitHooks = false
internals.injectProfilingHooks(null)
} else {
activeFallbackComponentNames = null
}
}

return componentNames
}
Expand Down
108 changes: 95 additions & 13 deletions exercises/06.rerenders/01.solution.memo/tests/memoized.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,70 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
const scriptToInject = `
<script>
let internals
const PerformedWorkFlag = 0b000000000000000000000000001
const UserCodeFiberTags = new Set([0, 1, 9, 11, 15])

let activeFallbackComponentNames = null

function isUserCodeFiberTag(tag) {
return UserCodeFiberTags.has(tag)
}

function getDisplayNameFromType(type) {
if (!type) return null

if (typeof type === 'function') {
return type.displayName || type.name || null
}

if (typeof type === 'object') {
if (typeof type.displayName === 'string' && type.displayName) {
return type.displayName
}

if (typeof type.render === 'function') {
return type.render.displayName || type.render.name || null
}

if (type.type) {
return getDisplayNameFromType(type.type)
}
}

return null
}

function getFiberDisplayName(fiber) {
return getDisplayNameFromType(fiber.type) || getDisplayNameFromType(fiber.elementType)
}

function didFiberRender(previousFiber, nextFiber) {
if (!previousFiber) return true
return (nextFiber.flags & PerformedWorkFlag) === PerformedWorkFlag
}

function collectRenderedComponentsFromCommit(root) {
if (!activeFallbackComponentNames || !root?.current) return

const stack = [root.current]
while (stack.length > 0) {
const fiber = stack.pop()
if (!fiber) continue

if (fiber.sibling) stack.push(fiber.sibling)
if (fiber.child) stack.push(fiber.child)

if (!isUserCodeFiberTag(fiber.tag)) continue
if (!didFiberRender(fiber.alternate, fiber)) continue

const componentName = getFiberDisplayName(fiber) ?? 'Anonymous'
activeFallbackComponentNames.push(componentName)
}
}

function enhanceExistingHook(existingHook) {
const originalInject = existingHook.inject
const originalCommitFiberRoot = existingHook.onCommitFiberRoot

existingHook.inject = (injectedInternals) => {
internals = injectedInternals
Expand All @@ -23,6 +84,12 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
return originalInject?.call(existingHook, injectedInternals) ?? 1
}

existingHook.onCommitFiberRoot = (...args) => {
const [, root] = args
collectRenderedComponentsFromCommit(root)
return originalCommitFiberRoot?.apply(existingHook, args)
}

return existingHook
}

Expand All @@ -34,7 +101,9 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
internals = injectedInternals
return 1 // Returning a number as React expects a renderer ID
},
onCommitFiberRoot: () => {},
onCommitFiberRoot: (_rendererId, root) => {
collectRenderedComponentsFromCommit(root)
},
onCommitFiberUnmount: () => {},
}
}
Expand All @@ -45,19 +114,32 @@ test('Only ListItem should not rerender when clicking force rerender', async ({
throw new Error('🚨 React DevTools is not available')
}

internals.enableProfilerTimer = true
internals.enableProfilerCommitHooks = true
internals.injectProfilingHooks({
markComponentRenderStarted: (fiber) => {
componentNames.push(fiber.type.name || 'Anonymous')
},
})

await cb()
const supportsInjectedProfilingHooks =
typeof internals.injectProfilingHooks === 'function'

if (supportsInjectedProfilingHooks) {
internals.enableProfilerTimer = true
internals.enableProfilerCommitHooks = true
internals.injectProfilingHooks({
markComponentRenderStarted: (fiber) => {
componentNames.push(fiber.type.name || 'Anonymous')
},
})
} else {
activeFallbackComponentNames = componentNames
}

internals.enableProfilerTimer = false
internals.enableProfilerCommitHooks = false
internals.injectProfilingHooks(null)
try {
await cb()
} finally {
if (supportsInjectedProfilingHooks) {
internals.enableProfilerTimer = false
internals.enableProfilerCommitHooks = false
internals.injectProfilingHooks(null)
} else {
activeFallbackComponentNames = null
}
}

return componentNames
}
Expand Down
Loading