Method, system, device and program product for tracking and analyzing rendering behavior of user interface component

By transforming component creation instructions during the build phase and intercepting rendering behavior at runtime, the rendering data of React components is collected and analyzed, solving the problem of automated tracking and analysis of user interface component rendering behavior, and achieving low-intrusion component rendering monitoring and performance optimization.

CN120973623APending Publication Date: 2025-11-18CTRIP TRAVEL NETWORK TECH SHANGHAI0
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202511072778.8
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-07-31
Publication Date
2025-11-18

AI Technical Summary

Technical Problem

Existing technologies cannot effectively track and analyze the rendering behavior of user interface components, leading to over-rendering issues that affect performance and user experience. Furthermore, they lack automated, continuous monitoring and diagnostic methods.

Method used

By transforming component creation instructions during the build phase, the component creation process is directed to a custom function. At runtime, component rendering is intercepted, rendering data is collected and the triggering cause is determined. Structured data records are generated and sent to the backend server. The componentization features and virtual DOM update mechanism of React components are used to achieve automated tracking and analysis.

Benefits of technology

It achieves low-intrusion, automated monitoring of component rendering behavior, supports long-term, continuous trend monitoring and performance regression analysis, provides a platform-level solution from data reporting to anomaly alerts, and supports front-end performance governance.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120973623A_ABST
    Figure CN120973623A_ABST
Patent Text Reader

Abstract

The invention discloses a method, a system, equipment and a program product for tracking and analyzing rendering behaviors of a user interface component, and the method comprises the following steps: a construction stage: converting a source code instruction for creating the component into calling of a preset self-defined function through a compiling tool; during running, responding to the calling, if the component is a tracking target, packaging the component by using a packaging component with built-in monitoring logic; when the packaging component is rendered, the monitoring logic of the packaging component acquires data such as rendering times and the like, and acquires the attribute and internal state of the rendering; comparing the data with pre-stored previous data to determine a trigger reason of rendering; finally, a record containing rendering data and triggering reasons is generated and sent to a back end, automatic tracking and accurate attribution of component rendering behaviors are achieved in a low-intrusion mode, the problems that in the prior art, manual debugging is relied on, and trend analysis cannot be conducted are solved, and support is provided for systematic performance optimization.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention relates to the field of Web front-end development technology, and in particular to a method, system, device, and program product for tracking and analyzing the rendering behavior of user interface components. Background Technology

[0002] In recent years, declarative user interface (UI) frameworks, represented by React, have become mainstream in modern web application development. React components, by introducing the Virtual DOM and a component-based development model, have greatly improved development efficiency and application performance. However, as application logic becomes more complex, React applications commonly face the problem of unnecessary or excessive re-renders of components. When a component's props or state changes, React triggers a re-render of that component and its child components. In complex applications, intertwined state management logic, prop drilling, and context abuse can easily lead to numerous re-renders of components in the component tree due to state changes, even if the final DOM output of these components remains unchanged. This over-rendering consumes significant CPU resources, causing performance issues such as stuttering page animations, delayed user interaction responses, and rapid battery drain on mobile devices, negatively impacting user experience.

[0003] Currently, the technical means relied upon by those skilled in the art to solve such problems mainly include manual instrumentation and log printing, browser developer tools, React developer tools (React DevTools), and third-party open-source libraries. These technical means have limitations such as lack of automation and continuity, lack of historical trend analysis, emphasis on immediate diagnosis over continuous monitoring, emphasis on manual operation over automatic discovery, emphasis on phenomenon exposure over root cause tracing, and emphasis on development and debugging over online operation and maintenance.

[0004] Therefore, there is an urgent need in this field for a low-intrusion, scalable, and automated component rendering count tracking and analysis mechanism to automatically and systematically monitor the rendering behavior of user interface components.

[0005] It should be noted that the information disclosed in the background section above is only used to enhance the understanding of the background of the present invention, and therefore may include information that does not constitute prior art known to those skilled in the art. Summary of the Invention

[0006] In view of this, the present invention provides a method, system, device and program product for tracking and analyzing the rendering behavior of user interface components, so as to solve the problem that the prior art cannot effectively track and analyze the rendering behavior of user interface components. By converting component creation instructions during the application building stage, intercepting rendering by wrapping components at runtime, collecting rendering data and determining the triggering cause, and finally sending the data to the backend server, the invention achieves automated tracking and analysis of component rendering behavior.

[0007] This invention provides a method for tracking and analyzing the rendering behavior of user interface components, applied to React components, including:

[0008] During the build phase of the user interface application, the instructions for creating the target component in the source code are obtained through the compilation tool, and the instructions are converted into calls to a pre-defined custom function;

[0009] When the user interface application is running, in response to a call to a custom function, if the target component is determined to be a preset tracking target, the target component is wrapped by a wrapper component, which is configured to execute monitoring logic each time it is rendered.

[0010] When executing monitoring logic, collect the rendering data of the target component and obtain the attribute data and internal state data received by the target component during this rendering.

[0011] Based on the comparison between the attribute data and internal state data during this rendering and the corresponding data of the target component in the previous rendering, the triggering cause of this rendering is determined.

[0012] Based on the collected rendering data and the determined triggering reasons, structured data records are generated and sent to the backend server.

[0013] In some optional embodiments, the step of converting instructions using compilation tools includes:

[0014] By configuring the importSource option of the Babel plugin, the JSX runtime of React components in the user interface application will be automatically directed to the module containing the preset custom function.

[0015] In some optional embodiments, the step of determining that the triggering cause is a change in internal state data includes:

[0016] Provide a rewritten useState Hook to replace the native useState Hook;

[0017] Leveraging the characteristic that Hooks are called in the same order during each render, a corresponding cache is maintained for each useStateHook call within the target component to store the previous state value.

[0018] Changes in internal state data are determined by comparing the current state value returned by the useState Hook in the current rendering cycle with the previous state value in the corresponding cache.

[0019] In some optional embodiments, the step of determining that the triggering cause is a change in internal state data further includes:

[0020] Provide a rewritten useReducer Hook to replace the native useReducer Hook, and maintain a corresponding cache for storing the previous state object for each useReducer Hook call;

[0021] Changes in internal state data are determined by comparing the current state object returned by the useReducer Hook in the current rendering cycle with the previous state object in the corresponding cache.

[0022] In some optional embodiments, the step of determining that the triggering cause is a change in internal state data further includes:

[0023] Provide a rewritten useContext Hook to replace the native useContext Hook;

[0024] For each call to the useContext Hook, dynamically inject a useEffect Hook whose only dependency is the return value of the useContext Hook;

[0025] When the dynamically injected useEffect Hook is executed, it is determined that the internal state data has changed due to changes in the Context object.

[0026] In some optional embodiments, the method further includes:

[0027] If the target component is determined to be a type of component, the steps of wrapping it with a wrapper component are as follows: the type component is automatically wrapped with a preset higher-order component. The higher-order component is a functional component, which internally caches and compares the attribute data and internal state data of the type component by calling one or more overridden Hooks.

[0028] In some optional embodiments, the method further includes:

[0029] Provide rewritten useMemo Hook or useCallback Hook to replace the corresponding native Hook;

[0030] For each call to useMemo Hook or useCallback Hook, maintain a corresponding cache to store the previous array of dependencies;

[0031] By comparing the dependency array in the current rendering cycle with the previous dependency array in the corresponding cache, it is determined whether the Hook needs to be recalculated, and this recalculation is recorded as part of the trigger reason.

[0032] In some alternative embodiments, the structured data record includes the name of the target component, the application version number, and a causal chain ID for associating the rendering behavior of the parent and child components.

[0033] In some optional embodiments, the method further includes:

[0034] After receiving the data records, the backend server aggregates the data records according to the name of the target component and the version number of the application;

[0035] Performance anomalies are detected by comparing the aggregated current render count metric with the pre-stored historical data baseline or the render count metric corresponding to the previous version number.

[0036] In some optional embodiments, the method further includes:

[0037] A configuration switch is provided to disable the comparison step of attribute data and internal state data in the production runtime environment of the user interface application to reduce performance overhead.

[0038] This invention provides a system for tracking and analyzing the rendering behavior of user interface components, comprising:

[0039] The front-end monitoring module is configured to obtain the instructions for creating the target component in the source code through the compilation tool during the construction phase of the user interface application, and convert the instructions into calls to preset custom functions; when the user interface application is running, in response to the call to the custom function, if the target component is determined to be the preset tracking target, the target component is wrapped by the wrapper component, and when the wrapped component is rendered, the rendering data is collected to obtain the attribute data and internal state data at this rendering time;

[0040] The attribution module is configured to determine the triggering cause of the current rendering by comparing the attribute data and internal state data at the time of the current rendering with the corresponding pre-stored data of the target component at the time of the previous rendering.

[0041] The reporting module is configured to generate structured data records based on the collected rendering data and the determined triggering reasons, and report them over the network.

[0042] The backend server is configured to receive and aggregate structured data records.

[0043] In some optional embodiments, the attribution module is also configured to:

[0044] Provide a rewritten useState Hook to replace the native useState Hook;

[0045] Leveraging the characteristic that Hooks are called in the same order during each render, a corresponding cache is maintained for each useStateHook call within the target component to store the previous state value.

[0046] Changes in internal state data are determined by comparing the current state value returned by the useState Hook in the current rendering cycle with the previous state value in the corresponding cache.

[0047] In some optional embodiments, the front-end monitoring module is also configured to:

[0048] If the target component is determined to be a type of component, a preset higher-order component is automatically used to wrap the type component. The higher-order component is a functional component that internally caches and compares the attribute data and internal state data of the type component by calling one or more overridden Hooks.

[0049] In some optional embodiments, the backend server is also configured as follows:

[0050] Aggregate the received data records by the name of the target component and the version number of the user interface application;

[0051] Performance anomalies are detected by comparing the aggregated current render count metric with the pre-stored historical data baseline or the render count metric corresponding to the previous version number, and an alarm notification is generated when a performance anomaly is detected.

[0052] This invention provides a device for tracking and analyzing the rendering behavior of user interface components, comprising:

[0053] processor;

[0054] Memory, which stores the processor's executable instructions;

[0055] The processor is configured to execute the steps of the method for tracking and analyzing the rendering behavior of user interface components by executing executable instructions.

[0056] This invention provides a product for tracking and analyzing the rendering behavior of user interface components. The program product includes computer instructions that, when executed by a processor, implement the functions of the method described above for tracking and analyzing the rendering behavior of user interface components.

[0057] It should be understood that the above general description and the following detailed description are exemplary and explanatory only, and are not intended to limit the invention.

[0058] The method, system, device, and program product of the present invention for tracking and analyzing the rendering behavior of user interface components have the following beneficial effects:

[0059] By employing compile-time instruction translation and runtime wrapping, automated monitoring of user interface component rendering behavior is achieved, allowing developers to monitor without modifying component code. Utilizing Hooks to track state changes avoids potential side effects from directly wrapping the `setState` function, enabling precise analysis of rendering trigger sources. Long-term, continuous trend monitoring of user interface component rendering performance is possible, along with inter-version performance regression analysis to proactively detect performance degradation. A platform-level solution can be built, encompassing data reporting, backend aggregation, visualization analysis, and automatic anomaly alerts, supporting frontend performance governance. Attached Figure Description

[0060] Other features, objects, and advantages of the invention will become more apparent from the following detailed description of non-limiting embodiments with reference to the accompanying drawings.

[0061] Figure 1 This is a flowchart of a method for tracking and analyzing the rendering behavior of user interface components according to an embodiment of the present invention;

[0062] Figure 2 This is a schematic diagram of the structure of a system for tracking and analyzing the rendering behavior of user interface components according to an embodiment of the present invention;

[0063] Figure 3 This is a schematic diagram of the structure of a device for tracking and analyzing the rendering behavior of user interface components according to an embodiment of this application. Detailed Implementation

[0064] Exemplary embodiments will now be described more fully with reference to the accompanying drawings. However, these exemplary embodiments can be implemented in many forms and should not be construed as limited to the examples set forth herein; rather, they are provided so that the invention will be more comprehensive and complete, and will fully convey the concept of the exemplary embodiments to those skilled in the art. The described features, structures, or characteristics may be combined in any suitable manner in one or more embodiments.

[0065] Furthermore, the accompanying drawings are merely illustrative of the invention and are not necessarily drawn to scale. The same reference numerals in the drawings denote the same or similar parts, and therefore repeated descriptions of them will be omitted. Some block diagrams shown in the drawings are functional entities and do not necessarily correspond to physically or logically independent entities. These functional entities can be implemented in software, in one or more hardware modules or integrated circuits, or in different network and / or processor devices and / or microcontroller devices.

[0066] The flowchart shown in the attached diagram is merely an illustrative example and does not necessarily include all steps. For example, some steps may be broken down, while others may be combined or partially combined. Therefore, the actual execution order may change depending on the specific circumstances.

[0067] The rendering behavior of user interface components is crucial in modern web applications, as its performance directly impacts user experience. React components achieve efficient updates through virtual DOM technology, but when a component receives new properties or states, it triggers a re-render. Unnecessary re-rendering leads to wasted performance. This invention addresses this by transforming component creation instructions during the build phase, directing the component creation process to a custom function, thereby intercepting component creation at runtime. By wrapping the component, rendering data can be collected during component rendering without modifying the original business logic. This data is then compared to the properties and states of the previous render to determine the reason for the rendering trigger. The collected data is ultimately sent to the backend server for analysis and monitoring of component rendering performance. This process leverages React's component-based features and virtual DOM update mechanism to track and analyze component rendering behavior.

[0068] like Figure 1 As shown, this embodiment of the invention provides a method for tracking and analyzing the rendering behavior of user interface components, applied to React components. This method aims to provide an automated, non-intrusive solution for monitoring and analyzing the rendering of user interface components. The method includes the following steps:

[0069] S100. During the build phase of the user interface application, the Babel build tool is used. By modifying Babel's configuration file, instructions in the source code that create target components, such as JSX syntax, are translated into calls to predefined custom functions. Specifically, the `presets` configuration item in the `babel.config.js` file in the project root directory is modified so that the `importSource` option of the plugin that handles JSX syntax, such as `@babel / preset-react`, points to the path of a custom module, such as `@my-company / react-tracker`. This configuration causes Babel to no longer translate JSX syntax into calls to `React.createElement` during compilation, but instead into calls to functions with the same name exported from the `@my-company / react-tracker` module.

[0070] Optionally, the compiler can be webpack or any other tool with code transformation capabilities. This pre-defined custom function intercepts the component creation process, preparing for subsequent monitoring steps.

[0071] S200. When the user interface application is running, and the aforementioned custom function is executed, the system determines whether the target component is a preset tracking target. The target component can be determined in several ways. For example, a tracking flag can be set in the component's props, such as `isRenderTracked = {true}`, or a global configuration object can be used to specify the type of component to be tracked, such as tracking all components whose names end with "Page". If the target component is determined to be a tracking target, the original component is not created directly; instead, it is wrapped by a wrapper component. This wrapper component is a functional component that receives the props of the original component and renders the original component as a child component.

[0072] Optionally, the wrapper component can also be a higher-order component (HOC). This wrapper component is configured to execute monitoring logic each time it is rendered, thus enabling monitoring of the component's rendering behavior without modifying the original component code.

[0073] S300. When executing monitoring logic, the system collects the rendering data of the target component and obtains the attribute data and internal state data received by the target component during this rendering. The collection of rendering data includes recording information such as the component's name, timestamp, and cumulative rendering count. Attribute data is obtained by directly retrieving the props object received by the wrapper component. The acquisition of internal state data relies on overriding Hooks such as useState and useReducer, maintaining a cache of state values ​​in the overridden Hooks to retrieve the previous state value.

[0074] S400. Based on the comparison between the attribute data and internal state data at the time of this rendering and the corresponding pre-stored data from the target component's previous rendering, the triggering cause of this rendering is determined. For attribute data, a shallow or deep comparison can be used to compare the currently received props object with the previously cached props object to determine whether the props have changed and, specifically, which prop keys have changed. For internal state data, the current state value or state object returned by useState or useReducer in this rendering cycle is compared with the corresponding previously cached state value or state object to determine whether the internal state data has changed. This comparison process can precisely pinpoint which state change triggered the rendering.

[0075] Optionally, if the component is a class component, the props and state of the class component can be cached and compared by combining the higher-order component and useRef.

[0076] S500 generates a structured data record based on the collected rendering data and the determined triggering reason, and sends it to the backend server. This structured data record uses JSON format and includes at least the following fields: component name, timestamp, cumulative render count, triggering reason type, and detailed triggering reason information. For example, if the triggering reason is due to a change in a prop, the data record will include the changed prop key.

[0077] Optionally, the data record may also contain a causal chain ID to associate the rendering behavior of the parent and child components. This data record is asynchronously sent to a specified API endpoint on the backend server via a POST request using a network API, such as fetch or XMLHttpRequest, for long-term storage and aggregation analysis.

[0078] Through the above steps, this invention provides a low-intrusion, automated, and scalable method for monitoring and analyzing user interface component rendering. By transforming code at compile time, the monitoring logic is completely decoupled from the business code, allowing developers to achieve full or targeted monitoring without manually modifying component code. By wrapping components and rewriting Hooks, accurate and reliable automated analysis of rendering trigger sources is achieved. By sending rendering data to the backend server, long-term, continuous monitoring of component rendering performance is achieved, providing support for developers to conduct performance regression analysis between versions and quantitatively evaluate the effectiveness of optimizations.

[0079] In some embodiments, to automatically redirect the runtime of JSX components in a user interface application to the module containing a predefined custom function, this is achieved by configuring the `importSource` option of a Babel plugin. Babel is a JavaScript compiler that translates JSX syntax into browser-executable JavaScript code. This step occurs during the application's build process, such as when the `npm run build` command is executed. Specifically, developers need to modify the Babel configuration file in the project's root directory, such as `babel.config.js` or `.babelrc`. This configuration file typically contains a `presets` configuration item that specifies the set of predefined plugins used by Babel, including plugins for handling React JSX syntax, such as `@babel / preset-react`. The original configuration might look like this:

[0080] ```javascript

[0081] / / babel.config.js example

[0082] module.exports={presets:['@babel / preset-react']

[0083] };

[0084] ```

[0085] To enable command conversion, the above configuration needs to be modified, specifically the configuration items of the @babel / preset-react plugin. The modified configuration is shown below:

[0086] ```javascript

[0087] / / babel.config.js example

[0088] module.exports={presets:[['@babel / preset-react',{runtime:'automatic',importSource:'@my-company / react-tracker'}]]

[0089] };

[0090] ```

[0091] Setting `runtime` to `automatic` enables Babel's new JSX transformation runtime. Then, set the value of the `importSource` option to `@my-company / react-tracker`. Here, `@my-company / react-tracker` represents the name of an NPM package containing pre-defined custom functions, such as `jsxDEV`. This NPM package needs to be pre-installed as a project dependency. After completing the above configuration, during compilation, if the Babel compiler encounters JSX syntax such as ``, it will not convert it into a call to `React.createElement` or `React.jsxDEV`, but will automatically convert it into a call to the function `jsxDEV` with the same name exported by the `@my-company / react-tracker` module. For example, `` in the source code might become after Babel compilation:

[0092] ```javascript

[0093] import{jsxDEV}from'@my-company / react-tracker / jsx-dev-runtime';jsxDEV(MyComponent,{prop1:"value1"},undefined,false,{fileName:"src / MyComponent.js",lineNumber:10

[0094] },this);

[0095] ```

[0096] Here, the `jsxDEV` function is a custom function that receives parameters such as component type and props, and is responsible for performing subsequent operations such as rendering interception, component wrapping, and data collection. This achieves non-intrusive redirection of React component creation directives. Optionally, instead of using the NPM package, the custom function `jsxDEV` can be placed in a specific directory of the project's source code, such as `. / src / tracker.js`. In this case, the value of the `importSource` option should be modified to a relative path to that file, for example:

[0097] ```javascript

[0098] / / babel.config.js example

[0099] module.exports={presets:[['@babel / preset-react',{runtime:'automatic',importSource:'. / src / tracker'}]]

[0100] };

[0101] ```

[0102] This approach does not require publishing and installing NPM packages, but it does require maintaining custom functions in the project code.

[0103] Through the above configuration and transformation, control over all component creation instructions was transferred without modifying any business component source code. This lays the foundation for subsequent rendering behavior tracking and analysis. Simultaneously, the officially recommended `runtime: 'automatic'` configuration was used, ensuring compatibility with future versions of React.

[0104] In some embodiments, the step of determining that the triggering cause is a change in internal state data includes:

[0105] Provide a rewritten useState Hook to replace the native useState Hook;

[0106] Leveraging the characteristic that Hooks are called in the same order during each render, a corresponding cache is maintained for each useStateHook call within the target component to store the previous state value.

[0107] Changes in internal state data are determined by comparing the current state value returned by the useState Hook in the current rendering cycle with the previous state value in the corresponding cache.

[0108] One specific method for determining changes in internal state data according to an embodiment of the present invention is as follows:

[0109] First, to replace the native `useState` hook, the system provides a function called `patchUseState`. This function takes an initial state value as its input parameter, which is the same as the parameter taken by the native `useState` hook. During the React component compilation phase, through the Babel plugin configuration as shown in point 2, all direct calls to `useState` hook in the source code are translated by the compiler into calls to the `patchUseState` function.

[0110] Secondly, inside the `patchUseState` function, a `trackerRef` object is created using the `useRef` hook. The `trackerRef` object is a container with a `.current` property used to store tracking information associated with the current `useState` hook call. Because React components ensure that the order of hook calls remains unchanged across multiple renders of the same component, each call to the same `useState` hook will correspond to the same `trackerRef` object. This `trackerRef.current` property is initialized to an object containing a `previousState` property, which is used to cache the state value from the previous render. During the first render, the value of this `previousState` property can be set to `undefined` or the initial state value.

[0111] Next, the `patchUseState` function calls the original `React.useState` Hook, passing the received initial state value as an argument. The `React.useState` Hook returns an array containing two elements: `currentState` (the current state value) and a state update function named `setState`. The `patchUseState` function captures these two return values. It compares `currentState` with the previous state value retrieved from `trackerRef.current.previousState`. One comparison method is to use the strict equality operator (===) to compare `currentState` and `previousState`. If they are not equal, it means the state has changed. For complex data types, such as objects or arrays, finer-grained shallow or deep comparisons, such as `lodash.isequal`, can be used to compare whether the properties of `currentState` and `previousState` have changed. Optionally, when the state is an object, you can first compare whether the references of the two objects are the same; if they are the same, the state is considered unchanged; if they are different, you further compare whether the values ​​of each property of the objects are the same. When a state change is detected, the `patchUseState` function records an attribution flag in the current global tracking context, indicating that the state change caused by the `useState` hook triggered a component re-render. To more accurately pinpoint which `useState` hook triggered the rendering, its index within all hook calls in the current component can be recorded. For example, the first `useState` hook in the component might have an index of 0, the second might have an index of 1, and so on. This index information helps developers quickly find the specific state variable that triggered the rendering. After completing the state comparison and attribution recording, the `patchUseState` function needs to update the value of `trackerRef.current.previousState` to the current `currentState` for comparison during the next rendering.

[0112] Finally, the `patchUseState` function returns the array containing `currentState` and `setState` obtained from the original `useState` Hook to the business component unchanged. The business component uses the returned state and state update function just like using the native `useState` Hook, without needing to be aware of the tracing logic.

[0113] Through the above steps, the `patchUseState` function achieves tracking of the `useState` Hook transparently to the business component code, avoiding potential side effects from directly wrapping the `setState` function. This method leverages the invariant call order of ReactHooks to achieve precise tracking and attribution of state changes.

[0114] In some embodiments, the present invention provides a rewritten patchUseReducer function to replace the useReducer Hook natively provided by React components for tracking changes in the internal state data of user interface components.

[0115] The patchUseReducer function is implemented as follows:

[0116] First, the `patchUseReducer` function receives parameters such as a reducer function and an initial state, which are the same parameters received by the native `useReducer` hook. The reducer function is used to define the logic for state updates, and the initial state defines the initial values ​​of the state.

[0117] Secondly, inside the `patchUseReducer` function, the `useRef` hook provided by React components is used to create a corresponding `trackerRef` for each call to the `patchUseReducer` function. This `trackerRef` is a persistent reference whose `current` property can store any JavaScript value and will not be reset due to component re-rendering. This `trackerRef` is specifically used to store tracking information related to the current `useReducer` hook call; specifically, it's the previous complete state object. Therefore, `trackerRef.current` is initialized to an object containing a `previousState` property to store the previous state object.

[0118] Then, the `patchUseReducer` function calls the original `React.useReducer` hook, passing in the previously received reducer function and initial state as parameters, and obtains the current state object and `dispatch` function returned by the `React.useReducer` hook. The `dispatch` function here is used to trigger the state update.

[0119] Next, the `patchUseReducer` function performs a shallow comparison between the current state object and the previous state object cached in `trackerRef`, such as using the JavaScript `!==` operator or the `isEqual` function from the `lodash` library. A shallow comparison only checks if two objects are the same reference, or compares the property values ​​of objects one by one for equality, but does not recursively compare the properties of nested objects. Optionally, a deep comparison can be used to determine if the state object has changed. A deep comparison recursively compares the property values ​​of nested objects to determine if the object has undergone a substantial change. If the comparison result is false, meaning the current state object is not equal to the previous state object, the `patchUseReducer` function determines that the state has changed and records an attribution flag for the `useReducer` state change. In some embodiments, this attribution flag can be a string constant, such as "USE_REDUCER_STATE_CHANGE". To more accurately pinpoint which `useReducer` hook triggered the rendering, the sequential index of this `useReducer` hook among all hook calls in the current component can be further recorded.

[0120] Then, the patchUseReducer function updates the cached previous state object in trackerRef with the current state object, that is, it executes trackerRef.current.previousState = currentState so that it can be compared during the next rendering.

[0121] Finally, the `patchUseReducer` function returns the `[state, dispatch]` array obtained from the original `React.useReducer` hook to the business component unchanged. This ensures that the business component can use the `patchUseReducer` function just like using the native `useReducer` hook, without needing to know the internal tracing logic.

[0122] In this way, when a user interface component is dispatched due to an action, causing the reducer function to be called and thus generating a new state, the rewritten patchUseReducer Hook can accurately detect the state change and record the change as the trigger reason for component rendering.

[0123] Optionally, to further reduce performance overhead, a configuration option can be added that allows developers to choose whether to enable tracing functionality for the useReducer Hook. If this configuration option is disabled, the patchUseReducer function directly calls the original React.useReducer Hook without executing any additional tracing logic.

[0124] The technical solution described in this embodiment enables precise tracking and attribution of component rendering caused by the useReducer Hook, without modifying the code of the business components. This provides a powerful tool for analyzing and optimizing the performance of React applications.

[0125] In some embodiments, to further and more accurately track the rendering of user interface components caused by the Context API, the system provides a rewritten patchUseContext function to replace the native useContext Hook of React components.

[0126] First, the `patchUseContext` function takes a `Context` object as its input parameter. The `Context` object is from the React Context API and contains the data that needs to be shared across the component tree, as well as the components that subscribe to that data.

[0127] Then, inside the `patchUseContext` function, the native `useContextHook` of the React component is called, passing the received Context object as a parameter. The native `useContextHook` returns the current `contextValue`, which is the value of the Context object in the current rendering cycle. This value is saved by the `patchUseContext` function and returned to the caller later, ensuring that the business component can access the data provided by the Context correctly. The tracing logic lies in the fact that inside the `patchUseContext` function, a `useEffect` hook is dynamically and additionally injected. This `useEffect` hook is not directly related to the native `useContext` hook; it is dynamically added to listen for changes in the Context. The `useEffect` hook accepts two parameters: a callback function and an array of dependencies.

[0128] In this embodiment, `contextValue` is set as the unique element of the dependency array of the `useEffect` Hook, i.e., `deps:[contextValue]`. This means that the callback function of the `useEffect` Hook will only be triggered when `contextValue` changes. The callback function of `useEffect` is where changes to the Context are monitored. Since `useEffect` also executes during the first render, inside the callback function, an `isFirstRenderRef` variable is first created using a `useRef` Hook and initialized to `true`. In subsequent render cycles, when the callback function of `useEffect` executes, it first checks the `isFirstRenderRef` variable. If it is the first render, this execution is skipped; otherwise, it indicates that `contextValue` has changed, and the subsequent attribution logging logic is executed, setting `isFirstRenderRef` to `false`.

[0129] Inside the `useEffect` callback function, when it's determined that the rendering was triggered by a change in `contextValue`, the system records an attribution flag, such as `CONTEXT_CHANGE`. This attribution flag indicates that the current component rendering was caused by a change in a `Context` object. In some embodiments, the system also records which specific `Context` object changed, along with the values ​​before and after the change, helping developers to more accurately pinpoint the problem.

[0130] The `patchUseContext` function ultimately returns the `contextValue` obtained from the native `React.useContext` to the business component without any changes, ensuring that the business logic is unaffected. The additional `useEffect` hook silently monitors changes to the `Context` in the background and records relevant information for subsequent analysis and diagnostics.

[0131] In this way, the present invention can accurately track component rendering caused by the Context API and correlate this information with other rendering data, thereby building a more complete performance monitoring system. By rewriting the useContext Hook and dynamically injecting the useEffect Hook, comprehensive monitoring of Context changes is achieved without modifying any business code, and the impact on performance is minimized.

[0132] Optionally, instead of using a dynamically injected useEffect Hook, change detection can be achieved by comparing the contextValue of the current render with that of the previous render. However, this approach may introduce additional performance overhead because it requires a deep comparison of the contextValue, especially when the Context object is complex. Therefore, using a useEffect Hook can more efficiently detect Context changes.

[0133] In some embodiments, if the target component is determined to be a class component, the step of wrapping it with a wrapper component specifically involves: automatically wrapping the class component with a preset higher-order component, wherein the higher-order component is a functional component that internally caches and compares the class component's attribute data and internal state data by calling one or more overridden Hooks. Specifically, first, it is necessary to identify the class component. In the runtime interception logic described in step S200 of the embodiment, the determination is made by checking whether the component type's typeof componentType === 'function' and whether its prototype has an isReactComponent marker. If it is a function and its prototype has an isReactComponent marker, or it is an ES6 class, then it is determined to be a class component. In specific implementation, the following methods can be used for detection: `componentType.prototype typeof componentType.prototype.isReactComponent! == 'undefined'` or `typeof componentType === 'function' String(componentType).startsWith('class')`. When it is determined to be a class component, the system automatically applies a preset higher-order component, here named withClassTracking. This higher-order component is essentially a function that takes an original class component, OriginalClassComponent, as an argument and returns a new functional component, WrapperComponent.

[0134] One way to implement WrapperComponent is as follows:

[0135] 1. Property reception: WrapperComponent receives all props passed to the original class component. These props are then passed to the instance of the class component.

[0136] 2. Class Component Instance Creation: Internally, `WrapperComponent` uses `useRef` to create a reference named `instanceRef`. During the initial rendering of `WrapperComponent`, an instance of the class component is created using `instanceRef.current = new OriginalClassComponent(props)`, and this instance is stored in `instanceRef`. In subsequent rendering processes, `instanceRef.current` is accessed directly to retrieve this instance, avoiding duplicate creation.

[0137] 3. Property and State Caching: WrapperComponent uses two additional useRefs The hooks, named propsRef and stateRef respectively, are used to store the properties and state of the component at the time of its last render. The state is obtained using `instanceRef.current.state`.

[0138] 4. Simulating Lifecycle: WrapperComponent uses the useEffect Hook to simulate the component lifecycle functions componentDidMount and componentDidUpdate. The dependency of useEffect is an empty array [], indicating that it only executes during the initial render, simulating componentDidMount. After the initial render, the dependency of useEffect is set to props, causing it to execute when subsequent properties change, thus simulating componentDidUpdate. Inside the effect function, properties and states are compared, and data is collected and attributed.

[0139] Property Comparison: A shallow comparison is performed between the currently received props and propsRef.current. If any property changes are found, the attribution information for those changes is recorded. The shallow comparison can be implemented using the following function, which takes two objects and returns a boolean value indicating whether the two objects are equal:

[0140] ```javascript function shallowCompare(obj1,obj2){if(Object.is(obj1,obj2)){return true;}if(typeof obj1!=='object'||obj1===null||typeof obj2!=='object'||obj2===null){return false;}const keys1=Object.keys(obj1); const keys2=Object.keys(obj2);if(keys1.length!==keys2.length){returnfalse;}for(let key of keys1){if(!obj2.hasOwnProperty(key)||!Object.is(obj1[key],obj2[key])){return false;}}return true;}```

[0141] State comparison: Retrieve the state of the current component instance and perform a shallow comparison with stateRef.current. If a state change is found, record the attribution information for the state change.

[0142] After the comparison is complete, update the current property of propsRef and stateRef to cache the current property and state values.

[0143] 5. Rendering: WrapperComponent calls the render() method of the class component instance and returns the rendered result. Example code for the withClassTracking function is as follows:

[0144] ```javascript

[0145] function withClassTracking(OriginalClassComponent,options={}){constWrapperComponent=(props)=>{const instanceRef=useRef(null); const propsRef=useRef(props); const stateRef=useRef(null); useEffect(()=>{ / / componentDidMount instanceRef.current=new OriginalClassComponent(props); stateRef.current=instanceRef.current.state; return()=>{ / / componentWillUnmount(simulation)if(instanceRef.current typeof instanceRef.current.componentWillUnmount==='function'){instanceRef.current.componentWillUnmount();}};},[]); useEffect(()=>{ / / componentDidUpdate(simulation)if(!instanceRef.current)return; / / Avoid first execution const prevState=stateRef.current; const currentProps = props; const currentState = instanceRef.current.state; / / Compare props if (!shallowCompare(currentProps, propsRef.current)) { / / Record props changes console.log('Props changed:', diffProps(currentProps, propsRef.current)); / / diffProps is a custom props comparison function / / Report data...} / / Compare state if (prevState !== currentState) { / / Record state changes console.log('State changed:', diffState(currentState, prevState)); / / diffState is a custom state comparison function / / Report data...} / / Update refs propsRef.current = currentProps; stateRef.current = currentState;},[props]); / / Rely on props to trigger update / / Force update mechanism, so that WrapperComponent can also be updated when the forceUpdate function of the original classComponent is called const[,forceUpdate] = useState({}); instanceRef.current.forceUpdate = useCallback(() => {forceUpdate({});},[]); return instanceRef.current.render();}; WrapperComponent.displayName = `withClassTracking(${OriginalClassComponent.displayName||OriginalClassComponent.name||'Component'})`; / / Set displayName for easy debugging return WrapperComponent;

[0146] }

[0147] ```

[0148] This implementation allows for the tracking and attribution of the rendering behavior of class components without modifying their source code. Leveraging the characteristics of functional components and Hooks, this approach maintains architectural consistency between monitoring class components and functional components, facilitating maintenance and expansion. Optionally, deep comparison can be used instead of shallow comparison for comparing class component properties and states, enabling more precise detection of deeper changes in properties or states. However, implementing deep comparison increases computational overhead, requiring a trade-off between monitoring accuracy and performance. This higher-order component plus Hooks approach not only tracks class components but also reuses the existing Hooks tracking capabilities of functional components, resulting in a unified architecture that is easy to maintain and extend. This solution monitors changes in class component props and state and records corresponding attribution information, facilitating developers in locating and optimizing rendering performance issues in class components.

[0149] In some embodiments, to track the rendering trigger reasons of the useMemo Hook or useCallback Hook, rewritten patchUseMemo and patchUseCallback functions are provided to replace the native useMemo Hook and useCallback Hook provided by React components. The following sections provide detailed descriptions of patchUseMemo and patchUseCallback respectively.

[0150] The `patchUseMemo` function is implemented as follows: First, it accepts two parameters: `factoryFn`, which is the factory function used to generate the cached value; and `deps`, which is an array of dependencies. Second, inside the `patchUseMemo` function, it calls the `useRef` hook provided by the React component to create a `trackerRef`. The `trackerRef` is specifically used to store tracking information related to this `useMemo` hook call, including the dependency array `previousDeps` passed in during the last render. This `trackerRef` is guaranteed to remain unchanged across multiple renders of the component through the `useRef` hook, ensuring that the previous dependency array can be correctly obtained. Then, it calls the original `React.useMemo(factoryFn, deps)`, passing `factoryFn` and `deps` as parameters to obtain `memoizedValue`, which is the cached value. Finally, it retrieves the previously cached dependency array `previousDeps` from the `current` property of the `trackerRef`.

[0151] The comparison logic involves comparing the two arrays, `deps` and `previousDeps`, item by item. First, the lengths of the two arrays are compared. If the lengths are different, it indicates that a dependency has changed. If the lengths are the same, the arrays are traversed, and the old and new dependencies at each index are compared. Once `deps[i]` is found to be different from `previousDeps[i]`, it is determined that a dependency has changed, and the specific dependency that changed is recorded. This comparison is a strict equality comparison, using the triple equals sign (===). Optionally, for non-primitive type dependencies, shallow or deep comparisons can be used to determine if a dependency has changed. If a dependency is determined to have changed, the system records an attribution flag in the current rendering tracking context, such as `MEMO_RECALCULATION`, along with detailed information, such as the index of the changed dependency. This information helps understand the specific reason for the component's rendering, i.e., why the prop passed to the child component changed. After all comparison logic has been executed, the cached dependency array in trackerRef needs to be updated. Specifically, the trackerRef.current property is assigned the current deps array, ensuring that the correct previous dependency array is obtained in the next render. Finally, the patchUseMemo function returns the memoizedValue obtained from the original React.useMemo unchanged.

[0152] The `patchUseCallback` function is implemented similarly to `patchUseMemo`, except that it calls the original `React.useCallback` function. The specific implementation process of `patchUseCallback` is as follows: First, the function receives two parameters: `callback`, which is the callback function; and `deps`, which is an array of dependencies. Second, inside `patchUseCallback`, it calls the `useRef` provided by the React component. A `Hook` is used to create a `trackerRef`. This `trackerRef` is specifically used to store tracking information related to the current `useCallback` hook call, including the dependency array `previousDeps` passed in during the last render. This `trackerRef` is guaranteed to remain unchanged across multiple renders of the component via `useRefHook`, ensuring that the previous dependency array can be correctly retrieved. Then, the original `React.useCallback(callback, deps)` is called, passing `callback` and `deps` as parameters to obtain a `memoizedCallback`, which is the cached callback function. Next, the cached dependency array `previousDeps` is retrieved from the `current` property of the `trackerRef`.

[0153] The comparison logic involves comparing the `deps` and `previousDeps` arrays item by item. First, the lengths of the two arrays are compared. If the lengths are different, it indicates a change in the dependency. If the lengths are the same, the arrays are traversed, and the old and new dependencies at each index are compared. Once `deps[i]` is found to be different from `previousDeps[i]`, it is determined that a dependency has changed, and the specific i-th dependency that changed is recorded. This comparison is a strict equality comparison, using the triple equals sign (===). Optionally, for non-primitive type dependencies, shallow or deep comparisons can be used to determine if a dependency has changed. If a dependency is determined to have changed, the system records an attribution flag in the current rendering tracking context, such as `CALLBACK_RECALCULATION`, along with detailed information, such as the index of the changed dependency. This information helps understand the specific reason for the component's rendering, i.e., why the prop passed to the child component changed.

[0154] After all comparison logic has been executed, the cached dependency array in trackerRef needs to be updated. Specifically, the trackerRef.current property is assigned the current deps array, ensuring that the correct previous dependency array is retrieved in the next render. Finally, the patchUseCallback function returns the memoizedCallback obtained from the original React.useCallback unchanged.

[0155] By tracing the useMemo Hook and useCallback Hook, a complete attribution chain can be built. For example, a change in the parent component's state causes a change in the parent component's useMemo dependency. useMemo is then recalculated and returns a new object, which is passed as a prop to the child component, ultimately causing the child component to re-render due to the prop change.

[0156] This embodiment enables the determination of whether a Hook has been recalculated and records this recalculation as part of the triggering reason.

[0157] In some embodiments, the structured data record includes the name of the target component, the application version number, and a causal chain ID used to associate the rendering behavior of parent and child components. The target component name is stored as a string representing the component's identifier. In React applications, this is typically the component's `displayName` property or constructor name. For example, a card component on a product details page might be recorded as "ProductDetailCard". This string is read directly from the React component's type property; if this property does not exist, the component's constructor name is used. The application version number is stored as a string representing the version information of the currently running application. This version number can be obtained from a global variable, such as one defined in the application's `package.json` file and injected into the global JavaScript variable `APP_VERSION` during the build process. An example value is "2.5.1". The causal chain ID is represented by a unique string. This ID is used to associate a series of component rendering events triggered by a single user interaction (such as clicking a button or a URL change), thereby tracing the causal relationship of rendering behavior.

[0158] The specific generation method is as follows: 1. At the starting point of user interaction with the page, such as when a user clicks a button to trigger a data update, the front-end monitoring module generates a unique string as the causal chain ID. This string can be generated using a UUID generation algorithm to ensure its global uniqueness. For example, "trace-xyz-789".

[0159] 2. Store the causal chain ID in a global, mutable context, such as a React Context or a custom global variable.

[0160] 3. The causal chain ID will be included in all data records rendered by components that are subsequently triggered directly or indirectly by this user interaction.

[0161] 4. If nested component rendering exists, the rendering behavior of the parent component triggers the rendering of the child component, and the child component's data record also contains the same causal chain ID as the parent component. The JSON structure of the data record can be as follows:

[0162] json

[0163] {"componentName":"ProductDetailCard","appVersion":"2.5.1","causalityChainId":"trace-xyz-789"

[0164] }

[0165] ```

[0166] Optionally, the causal chain ID can also be generated on the backend and sent to the frontend during the first rendering, and all subsequent data records reported by the frontend will carry this ID.

[0167] By including the target component's name, application version number, and causal chain ID, this embodiment achieves precise identification and association of component rendering behavior, providing the necessary data foundation for subsequent performance analysis. The backend server can use this information to aggregate data according to component name and version number, analyzing the rendering performance of a specific component under different versions. Through the causal chain ID, all rendering events triggered by a single user interaction can be linked together, thereby analyzing the causal relationships and performance bottlenecks in component rendering, and thus systematically managing frontend performance.

[0168] In some embodiments, after receiving data records reported by the frontend monitoring module, the backend server performs the following steps to detect performance anomalies: First, the data receiving module receives the data. The data receiving module is an API endpoint, such as the ` / api / performance` interface provided by an Express server based on Node.js, which listens for HTTP POST requests. This interface verifies whether the request's Content-Type is `application / json`, and then stores the received JSON data records in the raw data storage. The raw data storage can be a relational database such as MySQL, or a NoSQL database such as MongoDB. To improve write performance, the data can first be written to a message queue such as Kafka, and then a dedicated consumer service can write the data to the database. Then, the aggregation task is started. The data aggregation task is a background process that runs on a schedule, such as using Linux's Cron tool or Node.js's `setInterval` function, executing once per minute. This task reads data records from the raw data storage for the most recent minute. Read operations can use SQL queries such as `SELECT * FROM performance_data WHERE timestamp>=NOW()-INTERVAL 1MINUTE` to read data from a MySQL database, or use MongoDB's `find` method with timestamp range conditions. Next, the data records are aggregated according to the target component name and application version number. Aggregation is implemented programmatically, for example using JavaScript's `groupBy` function to group the read data records by the `componentName` and `appVersion` fields. For each group, the current render count metric is calculated. The render count metric can be the number of renders per minute, achieved by counting the number of data records within each group. For example, if a group contains 100 data records, the component corresponding to that group has rendered 100 times in that minute. Besides calculating the render count, other performance metrics can be calculated, such as average render time, by reading the render time field from the data records and calculating the average for each group. After the aggregation calculation is complete, the aggregated data is stored in the aggregate data store. The aggregate data store can be a time-series database such as InfluxDB or Prometheus. Time-series databases are specifically designed for storing time-series data and offer high write and query performance. When writing aggregated data to a time-series database, fields such as timestamp, component name, application version number, and render count metric need to be specified. Afterward, a performance anomaly detection task is started. This task is also a scheduled background process, for example, executing every 5 minutes.This task reads the latest performance metrics from the aggregated data store. The read operation can use query languages ​​for time-series databases such as InfluxQL or PromQL. The aggregated current render count metric is compared to a pre-stored historical baseline to detect performance anomalies. The historical baseline can be the average and standard deviation of render counts for the same time period over the past 7 days. For example, if the current time is 10:00 AM, the historical baseline is the average and standard deviation of render counts at 10:00 AM over the past 7 days. The average and standard deviation can be calculated using common statistical formulas. During the comparison, if the current render count exceeds the average plus three times the standard deviation, it is considered a performance anomaly. In addition to comparing with the historical baseline, it can also be compared with the render count metric corresponding to the previous version number. For example, if the current version number is 2.0, the render count metric for version 1.0 is read, and the render count growth rate between the two versions is calculated. If the growth rate exceeds 20%, it is considered an abnormal performance degradation.

[0169] Optionally, machine learning algorithms can be used to detect performance anomalies. For example, time-series anomaly detection algorithms such as Prophet or LSTM can be used to predict future render counts and compare the actual render counts with the predicted values. If the difference between the actual and predicted values ​​exceeds a certain threshold, it is considered a performance anomaly. Upon detecting a performance anomaly, an alert notification is generated. The alert notification includes the name of the component with the anomaly, the application version number, the specific metric deterioration, and the possible triggering cause. Alert notifications can be sent through various channels, such as email, SMS, or instant messaging tools like Slack.

[0170] Through the steps described above, this embodiment achieves automated performance anomaly detection for the rendering behavior of user interface components. By comparing the rendering count with historical data baselines or the rendering count corresponding to the previous version number, performance issues can be identified promptly, and developers can be notified to fix them. This helps improve the performance and stability of user interface applications.

[0171] In some embodiments, to further reduce performance overhead, especially in production environments of user interface applications, a configuration switch is provided to disable the comparison step between attribute data and internal state data. The specific implementation of this configuration switch can be a global JavaScript variable, such as `window.renderTrackerEnabled`, whose initial value defaults to `true`. By modifying the value of this variable, the monitoring logic can be controlled to be enabled or disabled. Optionally, the configuration switch is not a global variable, but a key-value pair stored in the browser's localStorage, such as `'renderTrackerEnabled':'true'`. In this case, the value of this key-value pair needs to be read from localStorage during the initialization of the front-end monitoring module and stored in an internal variable. In other optional implementations, the configuration switch can also be dynamically set via URL query parameters. For example, when a user accesses a page, the parameter `?renderTracker=false` can be added to the URL to disable monitoring. The front-end monitoring module needs to parse the query parameters in the URL and dynamically adjust the monitoring behavior based on the parameter values. Regardless of the specific implementation of the configuration switch, its function is to control the execution of the monitoring logic. In step S300 "Data Acquisition and Attribution" of the above embodiment, the monitoring logic first reads the state of the configuration switch. If the configuration switch is off, the comparison steps of attribute data and internal state data are skipped, and only basic information such as the number of renderings is collected. This means that steps S200 and S300 in the above embodiment are greatly simplified. The system only creates a useRef hook to create a counter variable that will not be reset due to re-rendering, and uses the useEffect hook to increment the counter. This operation has extremely low resource consumption. The useRef hook originally used to cache the previous props and state, as well as the logic for comparing the differences between props and state, will be completely skipped. The data records will not contain any information about the triggering cause. When the configuration switch is on, the complete monitoring logic is executed, including the comparison steps of attribute data and internal state data, as well as the determination and recording of the triggering cause.

[0172] This approach allows for flexible control over the granularity and performance overhead of monitoring in a production environment. By default, detailed monitoring can be disabled in production environments, with only simple render count statistics performed, thus avoiding a significant impact on user experience. When performance issues need to be investigated, detailed monitoring can be temporarily enabled by modifying the configuration switch value to obtain richer data. This configuration switch design allows the invention to achieve a good balance between monitoring accuracy and performance overhead, meeting performance monitoring needs without placing an excessive burden on the user experience.

[0173] like Figure 2 As shown, this embodiment of the invention provides a system for tracking and analyzing the rendering behavior of user interface components, applied to React components. The system includes a front-end monitoring module M100, an attribution module M200, a reporting module M300, and a back-end server M400, used to implement the method for tracking and analyzing the rendering behavior of user interface components as described in any of the above embodiments. The system includes:

[0174] The front-end monitoring module M100 is configured to, during the build phase of the user interface application, use a compiler to obtain the instructions in the source code used to create a target component and translate these instructions into calls to a pre-defined custom function. During runtime, in response to the call to the custom function, if the target component is determined to be a pre-defined tracking target, it wraps the target component with a wrapper component. When the wrapped component is rendered, it collects rendering data, obtaining attribute data and internal state data for this rendering. For example, the user interface application could be a single-page application built using React components. The compiler could be Babel, used to convert JSX syntax into JavaScript code.

[0175] The specific implementation of the M100 front-end monitoring module includes the following steps: First, during the application build process, the Babel plugin is configured by modifying its `importSource` option to point to a custom NPM package, such as `@my-company / react-tracker`. With this configuration, when the Babel compiler encounters JSX, it automatically inserts an `import` statement at the top of the compiled file, for example, `import {jsxDEV} from '@my-company / react-tracker / jsx-dev-runtime'`, and converts all JSX into calls to this imported `jsxDEV` function. Then, at application runtime, when the custom `jsxDEV` function is called to create a component, the function checks whether the component is a target to be tracked. This check can be achieved by reading the component's props object or preset tracking markers in the global configuration object, such as checking for the existence of a prop `isRenderTracked={true}`, or whether the component's name conforms to global tracking rules, such as the component name ending with "Page". If the component is not a tracking target, the original `React.createElement` function is called directly to create the component. If the component is the target being tracked, a wrapper component, `PatchedComponent`, is created, and the original target component is rendered as its child. `PatchedComponent` is a functional component that receives the original props and passes them to the original component. Inside `PatchedComponent`, a counter variable is created using a `useRef` hook to record the number of times the component has been rendered. Simultaneously, a `useEffect` hook is used to increment this counter in its callback function, thus accurately recording the component's cumulative rendering count. Furthermore, `PatchedComponent` uses a `useRef` hook to store the props object received during the last render for subsequent comparisons. The implementation of collecting property data and internal state data includes collecting prop data: `PatchedComponent` internally uses `useRef` to store the props object received during the last render. During the current render, a shallow comparison is performed between the newly received props object and the old props object cached in `useRef`. If the comparison result is false, the triggering reason is determined to be "property change," and the specific keys whose values ​​have changed can be further recorded. After the comparison is complete, the cache in `useRef` is updated with the new props object for use in the next render.

[0176] The attribution module M200 is configured to determine the triggering cause of the current rendering by comparing the attribute data and internal state data at the time of the current rendering with the corresponding pre-stored data from the previous rendering of the target component. The attribution module M200 receives data, such as props and state, collected by the front-end monitoring module M100 and compares it with previously stored values.

[0177] Attribution of state data can be achieved using the following method: Provide a rewritten `patchUseState` function. Internally, this function calls `useRef` to create a `trackerRef` to store tracking information related to the current `useState` call, including the previous state value. `patchUseState` calls the original `React.useState` and obtains the returned current state value `currentState` and the state update function `setState`. Then, it retrieves the previously cached state value `previousState` from the `trackerRef` and performs a comparison: `if(currentState !== previousState)`. If they are not equal, an attribution flag is recorded in the global tracking context of this rendering, indicating that the rendering was triggered by a change in `useState`. The sequential index of this `useState` in all Hook calls of the current component can be further recorded to accurately identify which `useState` was triggered. After all comparison logic has been executed, the cached state value in the `trackerRef` is updated with `currentState`: `trackerRef.current.previousState = currentState`. In this way, the triggering cause of the rendering can be accurately determined without modifying the original component's code. Optionally, deep comparisons can be used instead of shallow comparisons to more accurately detect changes in object or array properties. Deep comparisons are achieved by recursively comparing each property or element of an object or array.

[0178] The reporting module M300 is configured to generate a structured data record based on the collected rendering data and the determined triggering reason, and report it over the network. For example, the data record uses JSON format and includes at least the following fields: a unique timestamp, the current application version number, the component name, the cumulative number of renders, the type string of the triggering reason, and detailed information about the triggering reason. The reporting module M300 can use the browser's fetch API or XMLHttpRequest object to asynchronously send the JSON data record to a specified API endpoint of the backend server M400 via a POST request.

[0179] The backend server M400 is configured to receive and aggregate structured data records. It receives data records from the reporting module M300 and stores them in a database, such as the time-series database InfluxDB. The backend server M400 also periodically performs aggregation operations, grouping data by dimensions such as component name, application version number, and page URL, and calculating performance metrics, such as average number of renders. Optionally, the backend server M400 can also provide a data visualization interface to graphically display component rendering performance data, such as using a line chart to show the trend of render counts over time. The backend server M400 can also implement an alarm function; when performance anomalies are detected, such as render counts exceeding a preset threshold, an alarm notification is sent to the developers.

[0180] The above methods enable systematic tracking and analysis of the rendering behavior of user interface components, helping developers identify and resolve performance issues in React applications. This system automatically intercepts and records component rendering behavior, accurately attributes the triggering causes of rendering, and persistently stores and visualizes trend analysis of the data, thereby helping development teams systematically and proactively manage and optimize front-end application performance.

[0181] In some embodiments, the front-end monitoring module M100 is configured to provide a rewritten `patchUseState` function to replace the native React `useState` hook, enabling the tracking and attribution of changes in the component's internal state. This `patchUseState` function does not directly replace the native `useState`; instead, during the compilation phase, by modifying the Babel configuration, all calls to `useState` in the source code are transformed into calls to `patchUseState`.

[0182] The specific implementation is as follows: First, define the `patchUseState` function. This function takes an `initialState` as a parameter, which is the same as the parameter received by the native `useState`, representing the initial value of the state. Then, inside the `patchUseState` function, a `trackerRef` is created using React's `useRef` Hook. This `trackerRef` is a persistent reference that remains unchanged throughout the component's lifecycle and will not be reset due to component re-rendering. The `trackerRef.current` property is an object used to store tracking information related to this `useState` call, most importantly storing the state value `previousState` from the last render. Initially, `trackerRef.current.previousState` can be set to `undefined` or `initialState` itself. Next, call the original `React.useState` Hook, passing the received `initialState` as a parameter. The original `useState` Hook returns an array containing two elements: `currentState` and `setState`. `currentState` represents the current state value, and `setState` is a function used to update the state. The `patchUseState` function internally stores these two values ​​returned by `useState`. Next, the previously cached state value `previousState` is retrieved from `trackerRef.current`. `currentState` is then compared with `previousState`. The comparison operation needs to differentiate between data types: for primitive types (such as numbers, strings, and booleans), the strict equality operator (`===`) can be used directly; for objects or arrays, shallow or deep comparisons can be used. A shallow comparison compares whether the addresses of the two are the same, while a deep comparison compares whether the property values ​​are the same. For performance reasons, shallow comparison is used by default. If the comparison result of `currentState !== previousState` is true, it indicates that the state has changed. At this point, an attribution flag is recorded in the global tracking context of this rendering, indicating that the rendering was triggered by a change in `useState`. The sequential index of this `useState` in all Hook calls of the current component can be further recorded to accurately identify which `useState` caused the rendering. After completing the comparison logic, the value of `trackerRef.current.previousState` needs to be updated to `currentState` for comparison in the next rendering.Finally, the patchUseState function returns the currentState and setState obtained from the original React.useState to the business component unchanged.

[0183] In this way, the `patchUseState` function tracks the `useState` hook without modifying the business component code. Since React guarantees that the order of hook calls remains stable across multiple renders of the same component, the Nth call to `patchUseState` will always accurately find the corresponding `trackerRef` used to store its previous state. This method cleverly avoids the side effects of closures, performance inconsistencies, and other issues that can arise from directly wrapping the `setState` function. Optionally, a configuration option can be provided, allowing developers to choose between shallow or deep comparisons for comparing object or array-type state values. Deep comparisons can be implemented using a recursive algorithm, comparing each element of the object or array one by one.

[0184] The steps described above work together to track state changes managed by the useState Hook in React components, thereby determining the trigger for component rendering. This ability to precisely locate state changes helps developers quickly identify and resolve component over-rendering issues, improving application performance.

[0185] In some embodiments, when the user interface component is a class component, the front-end monitoring module M100 wraps it with a Higher-Order Component (HOC) to achieve a unified monitoring architecture with functional components. "Automatic usage" here refers to the front-end monitoring module M100 dynamically determining the component type at runtime. Specifically, the determination method is to check whether the component type is a function and whether the function prototype has an `isReactComponent` property. If both conditions are met, the component is determined to be a class component.

[0186] The default implementation of the higher-order component withClassTracking is as follows: Define a JavaScript function that takes a class component OriginalClassComponent as an argument and returns a new functional component WrapperComponent. This WrapperComponent function receives all the props of the original class component OriginalClassComponent.

[0187] The internal implementation of WrapperComponent works as follows: First, a reference named instanceRef is created using the useRef Hook to store the instance of the class component. Then, propsRef and stateRef are created using the useRef Hook to store the props and state from the last render, respectively. Next, the useEffect Hook simulates the lifecycle of the class component, including componentDidMount and componentDidUpdate. Upon the first execution of useEffect, an instance of the class component is created using new OriginalClassComponent(props), and this instance is stored in instanceRef.current. Simultaneously, the initial props are stored in propsRef.current, and the initial state instance.state is stored in stateRef.current. In subsequent executions of useEffect, the latest state instance.state of the class component instance is retrieved and compared with the previous state stored in stateRef.current. The currently received props are also compared with the props stored in propsRef.current. This prop comparison can be shallow, meaning only the references to the props are compared. For state comparison, you can directly compare references to the old and new state objects, or you can compare the individual property values ​​within each state object. If the comparison indicates a change in a property or state, the corresponding attribution information is recorded. For example, the key name of the changed property or the property name of the changed state is recorded. After each rendering, propsRef.current and stateRef.current are updated. Finally, WrapperComponent calls the instanceRef.current.render() method and returns its rendering result.

[0188] Optionally, deep comparison can be used for property comparison. Deep comparison recursively compares every property value in the property object, rather than just comparing references. Deep comparison can more accurately detect actual changes to properties, but it also incurs higher performance overhead. Whether to use shallow or deep comparison can be configured according to actual needs.

[0189] In this way, by utilizing the functional component `WrapperComponent` and Hooks, changes in the properties and states of the class component `OriginalClassComponent` can be tracked, enabling monitoring of the class component. This embodiment combines higher-order components and Hooks to track changes in the properties and states of class components, unifying the monitoring architecture of functional components and class components. This makes the overall monitoring system more complete and easier to maintain, and allows reuse of the Hooks-based tracking and comparison capabilities from functional components.

[0190] In some embodiments, the present invention relates to a backend server M400 processing received data records to achieve performance anomaly detection and alarm notification.

[0191] To aggregate received data records by target component name and user interface application version number, the backend server M400 can employ the following approach: First, the backend server M400 is configured with a data receiving module to receive structured data records reported by the frontend. This module can be built based on a RESTful API, using frameworks such as Node.js's Express or Python's Flask. The received data records are stored in the raw data storage system, such as a relational database like MySQL or a non-relational database like MongoDB. Then, a data aggregation service is configured to run periodically, for example, every 5 minutes, to read data from the raw data storage system. The read data is grouped according to the target component name and user interface application version number. This grouping operation can be implemented using the GROUP BY clause in an SQL statement, for example: `SELECT componentName, appVersion, COUNT(*) FROM raw_data WHERE timestamp>NOW()-INTERVAL 5MINUTE GROUP BY componentName, appVersion`. Optionally, big data processing frameworks such as MapReduce or Spark can also be used to implement grouping and aggregation to support larger data volumes. For each group, the data aggregation service calculates a rendering frequency metric for that group, such as average rendering frequency. The results are stored in an aggregate data storage system, such as the time-series database InfluxDB or Prometheus.

[0192] To detect performance anomalies by comparing the aggregated current render count metric with a pre-stored historical baseline or the render count metric corresponding to the previous version number, the backend server M400 can employ the following methods: First, the system maintains a historical baseline, which can be a moving average of render counts for the same period over the past 7 days. The moving average can be calculated using a sliding window algorithm. Second, an anomaly detection service is configured, which periodically reads the current render count metric and the historical baseline from the aggregated data storage system. The anomaly detection service compares the current render count metric with the historical baseline; if the current render count metric exceeds the historical baseline plus N times the standard deviation (e.g., 3 times the standard deviation), a performance anomaly is considered to exist. The system can also compare the current version's render count metric with the previous version's render count metric; if the current version's render count metric increases by more than a set threshold (e.g., 20%), a performance degradation anomaly is considered to exist. Optionally, machine learning algorithms, such as time series forecasting algorithms, can be used to predict future render counts, and the actual render counts are compared with the predicted values; if the difference between the actual and predicted values ​​exceeds a set threshold, a performance anomaly is considered to exist.

[0193] To generate alerts when performance anomalies are detected, the backend server M400 can use the following method: After detecting a performance anomaly, the anomaly detection service generates an alert message containing the name of the anomalous component, application version number, page URL, specific metric deterioration, and triggering cause. The alert message is sent to the alert notification service via a message queue, such as RabbitMQ or Kafka. Upon receiving the alert message, the alert notification service sends it to the designated development or operations team via email, SMS, instant messaging API (such as DingTalk or WeChat Work), or a ticketing system. Optionally, alert messages can be sent to a centralized monitoring platform, such as Prometheus Alertmanager or Grafana, for unified management of alert notifications.

[0194] Through the above implementation, the backend server M400 can aggregate received data records, detect anomalies, and issue alarms, thereby helping development and operations teams to promptly identify and resolve frontend performance issues and ensure user experience. The technical advantage of this embodiment lies in achieving automated, real-time performance monitoring and alarms, reducing the cost of manual troubleshooting, and proactively identifying potential performance risks.

[0195] like Figure 3As shown, the electronic device 600 is presented in the form of a general-purpose computing device. The components of the electronic device 600 may include, but are not limited to: at least one processing unit 610, at least one storage unit 620, a bus 630 connecting different system components (including storage unit 620 and processing unit 610), a display unit 640, etc.

[0196] The storage unit stores program code that can be executed by the processing unit 610, causing the processing unit 610 to perform the steps described in the method section of this specification according to various exemplary embodiments of this application. For example, the processing unit 610 can perform actions such as... Figure 1 The steps are shown in the figure.

[0197] The storage unit 620 may include a readable medium in the form of a volatile storage unit, such as a random access memory unit (RAM) 6201 and / or a cache storage unit 6202, and may further include a read-only memory unit (ROM) 6203.

[0198] The storage unit 620 may also include a program / utility 6204 having a set (at least one) program module 6205, such program module 6205 including but not limited to: an operating system, one or more application programs, other program modules and program data, each or some combination of these examples may include an implementation of a network environment.

[0199] Bus 630 can represent one or more of several types of bus structures, including a memory cell bus or memory cell controller, a peripheral bus, a graphics acceleration port, a processing unit, or a local bus using any of the various bus structures.

[0200] Electronic device 600 can also communicate with one or more external devices 700 (e.g., keyboard, pointing device, Bluetooth device, etc.), and with one or more devices that enable a user to interact with electronic device 600, and / or with any device that enables electronic device 600 to communicate with one or more other computing devices (e.g., router, modem, etc.). This communication can be performed via input / output (I / O) interface 650. Furthermore, electronic device 600 can also communicate with one or more networks (e.g., local area network (LAN), wide area network (WAN), and / or public networks, such as the Internet) via network adapter 660. Network adapter 660 can communicate with other modules of electronic device 600 via bus 630. It should be understood that, although not shown in the figures, other hardware and / or software modules can be used in conjunction with electronic device 600, including but not limited to: microcode, device drivers, redundant processing units, external disk drive arrays, RAID systems, tape drives, and data backup storage systems.

[0201] In the device for tracking and analyzing the rendering behavior of user interface components, when the program in the memory is executed by the processor, it implements the steps of the method for tracking and analyzing the rendering behavior of user interface components. Therefore, the device can also obtain the technical effects of the method for tracking and analyzing the rendering behavior of user interface components.

[0202] This invention also provides a program product for tracking and analyzing the rendering behavior of user interface components. The program product includes computer instructions, which, when executed by a processor, implement the functions of the method described above for tracking and analyzing the rendering behavior of user interface components. The computer instruction functions of this embodiment can be implemented using specific implementations of the system for tracking and analyzing the rendering behavior of user interface components as described above, and will not be elaborated upon here.

[0203] The above description, in conjunction with specific preferred embodiments, provides a further detailed explanation of the present invention. It should not be construed that the specific implementation of the present invention is limited to these descriptions. For those skilled in the art, various simple deductions or substitutions can be made without departing from the concept of the present invention, and all such modifications and substitutions should be considered within the scope of protection of the present invention.

Claims

1. A method for tracking and analyzing the rendering behavior of user interface components, applied to React components, characterized in that, include: During the construction phase of the user interface application, the instructions for creating the target component in the source code are obtained through the compilation tool, and the instructions are converted into calls to a preset custom function; When the user interface application is running, in response to a call to the custom function, if the target component is determined to be a preset tracking target, the target component is wrapped by a wrapping component, wherein the wrapping component is configured to execute monitoring logic each time it is rendered; When the monitoring logic is executed, the rendering data of the target component is collected, and the attribute data and internal state data received by the target component during this rendering are obtained. Based on the comparison between the attribute data and internal state data of the current rendering and the corresponding data of the target component in the previous rendering, the triggering cause of the current rendering is determined. Based on the collected rendering data and the determined triggering reasons, a structured data record is generated and sent to the backend server.

2. The method according to claim 1, characterized in that, The step of converting the instructions using a compilation tool includes: By configuring the importSource option of the Babel plugin, the JSX runtime of the React components in the user interface application will be automatically directed to the module where the preset custom function is located.

3. The method according to claim 1, characterized in that, The step of determining that the triggering cause is a change in internal state data includes: Provide a rewritten useState Hook to replace the native useState Hook; Leveraging the characteristic that Hooks are called in the same order during each rendering, a corresponding cache is maintained for each useStateHook call within the target component to store the previous state value; The change in the internal state data is determined by comparing the current state value returned by the useState Hook in the current rendering cycle with the previous state value in the corresponding cache.

4. The method according to claim 3, characterized in that, The step of determining that the triggering cause is a change in internal state data further includes: Provide a rewritten useReducer Hook to replace the native useReducer Hook, and maintain a corresponding cache for storing the previous state object for each useReducer Hook call; The change in the internal state data is determined by comparing the current state object returned by the useReducer Hook in the current rendering cycle with the previous state object in the corresponding cache.

5. The method according to claim 1, characterized in that, The step of determining that the triggering cause is a change in internal state data further includes: Provide a rewritten useContext Hook to replace the native useContext Hook; For each call to the useContext Hook, dynamically inject a useEffect Hook whose only dependency is the return value of the useContext Hook; When the dynamically implanted useEffect Hook is executed, it is determined that the internal state data has changed due to a change in the Context object.

6. The method according to claim 1, characterized in that, The method further includes: If the target component is determined to be a type of component, the step of wrapping it with a wrapper component specifically involves: automatically wrapping the type of component with a preset higher-order component, wherein the higher-order component is a functional component, which internally caches and compares the attribute data and internal state data of the type of component by calling one or more rewritten Hooks.

7. The method according to claim 1, characterized in that, The method further includes: Provide rewritten useMemo Hook or useCallback Hook to replace the corresponding native Hook; For each call to useMemo Hook or useCallback Hook, maintain a corresponding cache to store the previous array of dependencies; By comparing the dependency array in the current rendering cycle with the previous dependency array in the corresponding cache, it is determined whether the Hook needs to be recalculated, and this recalculation is recorded as part of the trigger reason.

8. A system for tracking and analyzing the rendering behavior of user interface components, applied to React components, characterized in that, include: The front-end monitoring module is configured to obtain the instructions for creating the target component in the source code through the compilation tool during the construction phase of the user interface application, and convert the instructions into calls to preset custom functions; When the user interface application is running, in response to the call to the custom function, if the target component is determined to be the preset tracking target, the target component is wrapped by the wrapping component, and when the wrapped component is rendered, rendering data is collected to obtain the attribute data and internal state data at the time of this rendering. The attribution module is configured to determine the triggering cause of the current rendering based on the comparison between the attribute data and internal state data of the current rendering and the corresponding pre-stored data of the target component in the previous rendering. The reporting module is configured to generate structured data records based on the collected rendering data and the determined triggering reason, and report them over the network. The backend server is configured to receive and aggregate the structured data records.

9. A device for tracking and analyzing the rendering behavior of user interface components, characterized in that, include: processor; A memory in which executable instructions of the processor are stored; The processor is configured to perform the steps of the method for tracking and analyzing the rendering behavior of user interface components as described in any one of claims 1 to 7 by executing the executable instructions.

10. A product for tracking and analyzing the rendering behavior of user interface components, characterized in that, The program product includes computer instructions that, when executed by a processor, implement the functionality of the method for tracking and analyzing the rendering behavior of user interface components as described in any one of claims 1 to 7.