/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-reconciler/src/__tests__/ReactPerformanceTrack-test.js
443 строки
12 KB
Ruslan Lesiutin
Fix/add missing else branch for renders with no props change (#34837)
14 окт 2025, 00:23
Не верифицирован
14 окт 2025, 00:23
47905a7
Код
Авторство
О чём код?
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails react-core * @jest-environment node */ let React; let ReactNoop; let Scheduler; let act; let useEffect; describe('ReactPerformanceTracks', () => { const performanceMeasureCalls = []; beforeEach(() => { performanceMeasureCalls.length = 0; Object.defineProperty(performance, 'measure', { value: jest.fn((measureName, reusableOptions) => { performanceMeasureCalls.push([ measureName, { // React will mutate the options it passes to performance.measure. ...reusableOptions, }, ]); }), configurable: true, }); console.timeStamp = () => {}; jest.spyOn(console, 'timeStamp').mockImplementation(() => {}); jest.resetModules(); React = require('react'); ReactNoop = require('react-noop-renderer'); Scheduler = require('scheduler'); act = require('internal-test-utils').act; useEffect = React.useEffect; }); function getConsoleTimestampEntries() { try { return console.timeStamp.mock.calls.filter(call => { const [, startTime, endTime] = call; const isRegisterTrackCall = startTime !== 0.003 && endTime !== 0.003; return isRegisterTrackCall; }); } finally { console.timeStamp.mockClear(); } } // @gate __DEV__ && enableComponentPerformanceTrack it('shows a hint if an update is triggered by a deeply equal object', async () => { const App = function App({items}) { Scheduler.unstable_advanceTime(10); useEffect(() => {}, [items]); }; Scheduler.unstable_advanceTime(1); const items = ['one', 'two']; await act(() => { ReactNoop.render(<App items={items} />); }); expect(performanceMeasureCalls).toEqual([ [ 'Mount', { detail: { devtools: { color: 'warning', properties: null, tooltipText: 'Mount', track: 'Components ⚛', }, }, end: 11, start: 1, }, ], ]); performanceMeasureCalls.length = 0; Scheduler.unstable_advanceTime(10); await act(() => { ReactNoop.render(<App items={items.concat('4')} />); }); expect(performanceMeasureCalls).toEqual([ [ 'App', { detail: { devtools: { color: 'primary-dark', properties: [ ['Changed Props', ''], [' items', 'Array'], ['+ 2', '…'], ], tooltipText: 'App', track: 'Components ⚛', }, }, end: 31, start: 21, }, ], ]); }); // @gate __DEV__ && enableComponentPerformanceTrack it('bails out of diffing wide arrays', async () => { const App = function App({items}) { Scheduler.unstable_advanceTime(10); React.useEffect(() => {}, [items]); }; Scheduler.unstable_advanceTime(1); const items = Array.from({length: 1000}, (_, i) => i); await act(() => { ReactNoop.render(<App items={items} />); }); expect(performanceMeasureCalls).toEqual([ [ 'Mount', { detail: { devtools: { color: 'warning', properties: null, tooltipText: 'Mount', track: 'Components ⚛', }, }, end: 11, start: 1, }, ], ]); performanceMeasureCalls.length = 0; Scheduler.unstable_advanceTime(10); await act(() => { ReactNoop.render(<App items={items.concat('-1')} />); }); expect(performanceMeasureCalls).toEqual([ [ 'App', { detail: { devtools: { color: 'primary-dark', properties: [ ['Changed Props', ''], [' items', 'Array'], [ 'Previous object has more than 100 properties. React will not attempt to diff objects with too many properties.', '', ], [ 'Next object has more than 100 properties. React will not attempt to diff objects with too many properties.', '', ], ], tooltipText: 'App', track: 'Components ⚛', }, }, end: 31, start: 21, }, ], ]); }); // @gate __DEV__ && enableComponentPerformanceTrack it('does not show all properties of wide objects', async () => { const App = function App({items}) { Scheduler.unstable_advanceTime(10); React.useEffect(() => {}, [items]); }; Scheduler.unstable_advanceTime(1); await act(() => { ReactNoop.render(<App data={{buffer: null}} />); }); expect(performanceMeasureCalls).toEqual([ [ 'Mount', { detail: { devtools: { color: 'warning', properties: null, tooltipText: 'Mount', track: 'Components ⚛', }, }, end: 11, start: 1, }, ], ]); performanceMeasureCalls.length = 0; Scheduler.unstable_advanceTime(10); const bigData = new Uint8Array(1000); await act(() => { ReactNoop.render(<App data={{buffer: bigData}} />); }); expect(performanceMeasureCalls).toEqual([ [ 'App', { detail: { devtools: { color: 'primary-dark', properties: [ ['Changed Props', ''], [' data', ''], ['– buffer', 'null'], ['+ buffer', 'Uint8Array'], ['+ 0', '0'], ['+ 1', '0'], ['+ 2', '0'], ['+ 3', '0'], ['+ 4', '0'], ['+ 5', '0'], ['+ 6', '0'], ['+ 7', '0'], ['+ 8', '0'], ['+ 9', '0'], ['+ 10', '0'], ['+ 11', '0'], ['+ 12', '0'], ['+ 13', '0'], ['+ 14', '0'], ['+ 15', '0'], ['+ 16', '0'], ['+ 17', '0'], ['+ 18', '0'], ['+ 19', '0'], ['+ 20', '0'], ['+ 21', '0'], ['+ 22', '0'], ['+ 23', '0'], ['+ 24', '0'], ['+ 25', '0'], ['+ 26', '0'], ['+ 27', '0'], ['+ 28', '0'], ['+ 29', '0'], ['+ 30', '0'], ['+ 31', '0'], ['+ 32', '0'], ['+ 33', '0'], ['+ 34', '0'], ['+ 35', '0'], ['+ 36', '0'], ['+ 37', '0'], ['+ 38', '0'], ['+ 39', '0'], ['+ 40', '0'], ['+ 41', '0'], ['+ 42', '0'], ['+ 43', '0'], ['+ 44', '0'], ['+ 45', '0'], ['+ 46', '0'], ['+ 47', '0'], ['+ 48', '0'], ['+ 49', '0'], ['+ 50', '0'], ['+ 51', '0'], ['+ 52', '0'], ['+ 53', '0'], ['+ 54', '0'], ['+ 55', '0'], ['+ 56', '0'], ['+ 57', '0'], ['+ 58', '0'], ['+ 59', '0'], ['+ 60', '0'], ['+ 61', '0'], ['+ 62', '0'], ['+ 63', '0'], ['+ 64', '0'], ['+ 65', '0'], ['+ 66', '0'], ['+ 67', '0'], ['+ 68', '0'], ['+ 69', '0'], ['+ 70', '0'], ['+ 71', '0'], ['+ 72', '0'], ['+ 73', '0'], ['+ 74', '0'], ['+ 75', '0'], ['+ 76', '0'], ['+ 77', '0'], ['+ 78', '0'], ['+ 79', '0'], ['+ 80', '0'], ['+ 81', '0'], ['+ 82', '0'], ['+ 83', '0'], ['+ 84', '0'], ['+ 85', '0'], ['+ 86', '0'], ['+ 87', '0'], ['+ 88', '0'], ['+ 89', '0'], ['+ 90', '0'], ['+ 91', '0'], ['+ 92', '0'], ['+ 93', '0'], ['+ 94', '0'], ['+ 95', '0'], ['+ 96', '0'], ['+ 97', '0'], ['+ 98', '0'], ['+ 99', '0'], [ '+ Only 100 properties are shown. React will not log more properties of this object.', '', ], ], tooltipText: 'App', track: 'Components ⚛', }, }, end: 31, start: 21, }, ], ]); }); // @gate __DEV__ && enableComponentPerformanceTrack it('includes console.timeStamp spans for Components with no prop changes', async () => { function Left({value}) { Scheduler.unstable_advanceTime(5000); } function Right() { Scheduler.unstable_advanceTime(10000); } await act(() => { ReactNoop.render( <> <Left value={1} /> <Right /> </>, ); }); expect(performanceMeasureCalls).toEqual([ [ 'Mount', { detail: { devtools: { color: 'warning', properties: null, tooltipText: 'Mount', track: 'Components ⚛', }, }, end: 5000, start: 0, }, ], [ 'Mount', { detail: { devtools: { color: 'warning', properties: null, tooltipText: 'Mount', track: 'Components ⚛', }, }, end: 15000, start: 5000, }, ], ]); performanceMeasureCalls.length = 0; getConsoleTimestampEntries(); Scheduler.unstable_advanceTime(1000); await act(() => { ReactNoop.render( <> <Left value={2} /> <Right /> </>, ); }); expect(performanceMeasureCalls).toEqual([ [ 'Left', { detail: { devtools: { color: 'error', properties: [ ['Changed Props', ''], ['– value', '1'], ['+ value', '2'], ], tooltipText: 'Left', track: 'Components ⚛', }, }, end: 21000, start: 16000, }, ], ]); expect(getConsoleTimestampEntries()).toEqual([ ['Render', 16000, 31000, 'Blocking', 'Scheduler ⚛', 'primary-dark'], ['Right', 21000, 31000, 'Components ⚛', undefined, 'error'], ]); performanceMeasureCalls.length = 0; }); });