- Clone the repo:
https://github.com/kennysghub/fe-log-viewer.git
- Install dependencies:
npm install
- Start App:
npm start
Application is now running on http://localhost:3000
The Log Viewer is a web application built to display and interact with large volumes of log data. It features log fetching and virtualized rendering for optimized performance. Each log can be expanded for inspection.
- LogViewer - Container component for LogEntry components.
- LogEntry - Renders each individual log entry fetched from API.
- useFetch - Custom hook for encapsulating the logic for fetching and parsing log data.
- useVirtualization - Custom hook to optimize the rendering of large datasets.
-
Data Ingestion and Parsing
- useFetch makes a GET request to the endpoint.
- Once headers are received, the Promise resolves to a Response object. The body of the response is a ReadableStream, that can read chunk by chunk.
- Inside a loop, chunks are converted into strings and added to the component's log state.
-
Virtual Rendering
- Only the logs visible in the current viewport plus an overscan area are rendered, reducing the number of nodes injected into the DOM.
- The useVirtualization hook expands log entries by calculating their height, which ensures a smooth scrolling experience with variable-height log entries.
- Expensive calculations such as getVisibleRange are memoized to prevent unnecessary recalculations.
-
Render Lifecycle
- Initial Render - On first load, the LogViewer component renders a minimal set of logs.
- Scroll Events - As the user scrolls, the onScroll callback updates the scrollTop state in the virtualization hook, triggering a recalculation of the visible range.
- Visible Range Update - When the visible range changes, only the newly visible logs are rendered, and logs scrolled out of view are removed from the DOM.
- Log Expansion - When a user expands a log entry, the toggleRow function updates the expandedRows state, triggering a recalculation of total height and visible range. This only affects the rendering of logs around the expanded entry.
The current testing suite contains unit tests for the main components of the application:
- App - Mocks LogViewer component to isolate the App component's rendering.
- LogEntry - Checks if the component renders correctly with given props.
- LogViewer - Mocks custom hooks to control behavior and validates if log entries are rendered correctly.
While the current tests provide a good foundation, these are areas that could be expanded if I had more time:
- Integration tests
- Edge cases
- Performance testing