Building the Open Targets Platform Interface using React
In the final section of the four-part series discussing the Open Targets Platform’s codebase, we delve into the User Interface. The Open Targets Platform UI presents, in a meaningful and accessible way, the rich data produced by the ETL that is served through the GraphQL API.
For the newly redesigned Open Targets platform, we developed the UI from scratch using React. Since Angular.js is no longer maintained, the front-end team had a choice between going with the newer version of Angular 2+ or React. We chose to implement the UI with React because it has become the dominant UI tool for building highly interactive user interfaces and also because transitioning from Angular 1.x to Angular 2+ was as big of a change as going from Angular 1.x to React.
Given that the Open Targets Platform is a data intensive application, the data is served through a GraphQL API. This allows the UI to only request the data that it needs and avoid over fetching. We use Apollo Client, which is a library that provides us with an in-memory cache. It stores the data from GraphQL queries and helps avoid making new calls to the GraphQL API, improving the latency of the UI.
We use the Material-UI component library which provides us with a set of common UI React components. This helps us build the UI and iterate fast. We modify the components with custom CSS to fit our needs.
To keep page load times low, we split the code of several visualisation components with heavy JavaScript bundles. This allows us to lazy load JavaScript code only when it is needed. We also use React.memo where appropriate to prevent unnecessary re-rendering of React components as well as useMemo for memoizing the results of expensive computations.
Throughout the UI, we present the data with tables. In tables with limited data, we are able to load all the rows at once without a major performance hit. However, for tables with a large number of rows, we make use of server side paging to only request a portion of the rows to display in the UI. This helps reduce the memory footprint of the UI.
Future plans
We have many plans that we want to explore to keep improving the UI and our development process. We are currently experimenting with automatically generating TypeScript types from GraphQL queries. This will help us prevent introducing bugs when interacting with the GraphQL API since some deeply nested fields are optional and could be null.
As the UI grows, we want to experiment with route-based code splitting or server side rendering to improve even more the page load times. Finally, now that the UI is in a more stable state, we will be adding unit and integration tests.
Feel free to take a look at the frontend code and contribute here.