🦊 Firefox Nightly 🔥 now supports WebSocket Inspection! It has been a really exciting summer working to support WebSocket Inspection for Firefox as this is a feature that many developers have been requesting over the years.
I am very thankful for this opportunity as I was given ownership to implement the WebSocket Inspector from scratch until it is production-ready. Throughout the process, I got to learn from different experts in the team, gaining the knowledge needed to deliver success for the project. They include:
- Knowing how Firefox Developer Tools communicate with the browser through the Remote Debugging Protocol (RDP)
- Extending the React/Redux architecture of the Network Panel in Firefox Developer Tools
- Working with DOM elements and modern APIs e.g. Intersection Observer
- Improving web performance through lazy loading and debouncing
- Using best UI/UX practices
- Writing tests
- Adhering to coding standards
- Familiarizing with the Mozilla development workflow (Bug tracking through Bugzilla, submitting/reviewing patches through Phabricator, running tests through the TryServer)
- Working in geographically distributed teams across different timezones
Shoutout to my mentor @janodvarko for the guidance given and everyone in the Firefox Developer Tools team who has supported this project through feedback and code reviews!
This section summarizes what has been achieved over this summer and my retrospection of the work done. For more detailed discussion as well as the technical aspects involved, refer to the relevant bug numbers/Phabricator patches.
These bugs form the core of the project, forming the minimum viable product (MVP) required for developers to inspect WebSocket traffic.
The patch for this bug achieves the following:
- Intercept WebSocket traffic received by the browser by implementing an actor
- Setup the frontend infrastructure to receive WebSocket traffic
- Emit events and data from the backend actor to the frontend infrastructure
This is the first patch I've worked on for this project and it is one of the most challenging ones. This is because it involves good working knowledge of RDP and the current Firefox Developer Tools codebase. I overcame this challenge by asking a lot of clarifying questions, reading the documentation and debugging the codebase to figure out how an actor is implemented and how data and events are sent from the backend actor to the frontend infrastructure.
The patch for this bug achieves the following:
- Builds the React/Redux architecture that reacts to new events and data sent from the backend actor
- Builds a simple UI in a new panel to show events and data sent from the backend actor
As I have some experience with React/Redux and the codebase, this patch was manageable.
The patch for this bug is an extension of the previous patch. It is more involved and allowed me to gain experience in building a more complex UI while ensuring state management and UX is handled properly at the same time. To improve the performance of the WebSocket Inspector, lazy loading is also considered wherever possible.
The patch for this bug attempts to show both raw data and formatted JSON data in the form of a tree. My increased familiarity with the codebase at this point allowed me to identify parts of the codebase that can be refactored to a new React component so that functionalities can be shared to achieve what we want.
These bugs improve the UI/UX of the WebSocket Inspector, allowing developers to boost their productivity while inspecting WebSocket traffic.
The patch for this bug builds a toolbar that allows developers to filter and clear WebSocket messages from Firefox Developer Tools.
Apart from extending the React/Redux architecture to support the respective functionalities, I wrote selectors when retrieving certain data from the Redux store. Selectors perform memoization, therefore using them improves performance.
Also, I get to understand more about the codebase that handles network requests as some interactions in the WebSocket Inspector are affected by them.
The patch for this bug shows summary statistics including the total number of displayed messages, the total size of displayed messages and total elapsed time between the first and last displayed message. This patch was manageable to implement as it uses the knowledge gained from other patches.
The patch for this bug hides some columns by default. Developers can choose to unhide them through a context menu and the preferences will be saved automatically. This patch was manageable and I got to learn how Firefox Developer Tools handle Firefox preferences through the use of Redux middleware.
The patch for this bug limits the payload that is rendered in the WebSocket Inspector by setting a limit via Firefox preferences. This is done to improve performance as rendering a large payload may be unnecessary and takes up a lot of memory. This patch was manageable to implement.
The patch for this bug limits the number of displayed frames in the WebSocket panel by setting a limit via Firefox preferences. Users can choose to keep future messages or change the limit. This is also done to improve performance as rendering many messages may be unnecessary and takes up a lot of memory.
This patch was manageable to implement but the UX is slightly challenging to get it right. I took part in some UX discussion with the team before implementing this.
The patch for this bug sends WebSocket messages in batches by leveraging how the existing codebase uses debouncing for network requests. I got to experience how debouncing helps to improve performance and UX in an involved setting.
Some thoughts have been placed to use react-virtualized in the future to enjoy the benefits of virtual scrolling.
The patch for this bug uses the Intersection Observer API to achieve the effect of scroll to bottom. It was fun learning about this cutting-edge API and using it in production. I also got to explore extending the functionalities of an existing component to retrieve the DOM reference of an element.
The patch for this bug uses the Redux middleware to capture telemetry on how many times WebSocket messages are selected. This patch was manageable as I have handled the Redux middleware in one of the previous patches.
The patch for this bug allows developers to copy WebSocket messages directly through a context menu. I got to learn about some in-built libraries that the codebase has e.g. the clipboard and used them to achieve the result.
The patch for this bug allows WebSocket messages sent using the Socket.IO protocol to be parsed in a JSON format and shown in the WebSocket Inspector. I got to research on existing open-source parsers, reference relevant parts and include it inside the codebase. The process was enjoyable as I got to read up on how external libraries parse custom WebSocket messages.
The patch for this bug allows WebSocket messages sent using the SockJS protocol to be parsed in a JSON format and shown in the WebSocket inspector. The process and experience was similar to the other protocol parsers.
Bug 1566756 - Support for MQTT protocol (pending review)
The patch for this bug allows WebSocket messages sent using the MQTT protocol to be parsed in a JSON format and shown in the WebSocket inspector. The process and experience was similar to the other protocol parsers.
The patch for this bug allows developers to use keyboard navigation to select different WebSocket messages. This patch was manageable to implement.
Bug 1575465 - Messages panel: WebSocket messages in HAR exports (pending review)
The patch for this bug allows developers to view WebSocket messages in HAR exports. This feature is similar to what Chrome Developer Tools has now.
This patch was manageable and I got to learn more about the codebase that handles HAR. I also got to practice flattening a JavaScript data structure to help in simplifying future operations.
These bugs provide test coverage for features built for the WebSocket Inspector, ensuring that we catch regressions over time.
Bug 1575582 - Implement DAMP test for WS Monitor (pending review)
These bugs provide fixes for the feedback given by users and the team when using the WebSocket Inspector. They also include improvements such as code refactoring and improving code quality.
Bug 1571786 - Warning: Failed prop type: Invalid prop visibleColumns
of type array
supplied to FrameListItem
, expected object
(merged)
Bug 1574623 - When switching to Messages panel with many messages, the table isn't scrolled down (merged)
There is still room for improvement for the WebSocket Inspector. The plan is as follows:
The goal is to support this feature that the Chrome Developer Tools has now.
I've done some research and it is achievable by depending on a library that Bug 1566756 - Support for MQTT protocol uses.
All related bugs are filed and referenced in this meta bug. Work can be picked up from this meta bug once triaging and prioritization has been performed.
I love open source and have been contributing to open source since 2018 as I enjoy learning from awesome people while contributing my expertise back to the community.
It has been an awesome summer contributing to Mozilla Firefox Developer Tools. Although it is officially the end of Google Summer of Code 2019, it is not the end of my open source journey and I hope to bring more impactful open source contributions in the near future!
There will be a more detailed post about WebSocket Inspector in the upcoming release of Firefox 70 Beta, so stay tuned! Also, I'll probably write a more elaborate post about my GSoC experience and the project if people are interested :)