Jump to content

Design System Team/Projects/Modern user interfaces for all users

From mediawiki.org

Project Overview

[edit]

The Wikimedia Design System Team is developing Codex, a Vue.js-based library that will enable developers to more efficiently and effectively build consistent, accessible and interactive user interfaces (UI). However, Codex components are currently only available when modern JavaScript is available and once JavaScript has loaded, which would exclude users of older browsers. We would like to find a way to make user interfaces built with Codex work for these users as well.

Background

[edit]

This is background information for the "Modern user interfaces for all users" Technical Decision Making Process (TDMP), see T317270.

What server rendering is

[edit]

The reason Codex components are currently only available in modern browsers is that they're implemented as client-side-only JavaScript, meaning the code that renders them executes in the user's browser. That will only happen if the user's browser supports a modern enough version of JavaScript and if the user hasn't disabled JavaScript (or doesn't receive the JavaScript experience for some other reason). And it won't start happening until the JavaScript code has been downloaded, which could take a while on a slow connection.

If we want users of older browsers to be able to view and interact with user interfaces built with Codex, we need to render (a version of) the user interface on the server, so that the UI is already part of the HTML that the user's browser receives. This also helps users of modern browsers see (an initial and non-interactive version of) the UI faster, because they don't have to wait for the JavaScript code to be downloaded and executed. There are inherent limitations to how feature-rich and interactive a UI can be without JavaScript (or before JavaScript arrives), but in many cases a basic experience can be provided.

Possible approaches

[edit]

Below are some approaches we have considered to the server rendering issue. These aren't meant to be universal approaches that we would use in every case: in practice, we'd likely use different approaches for different use cases.

Client-side only: don't render anything on the server

[edit]

The simplest solution to this problem is to decide that we don't want to solve it at all. A user interface could be implemented entirely client-side, in JavaScript that runs on the client, and nothing would need to be rendered on the server. Users of older browsers would see an error message saying they can't use the feature. Users of modern browsers would be able to use the feature, but would initially see a "Please wait" message or some other placeholder before the UI loads.

  • (+) No extra work required to support no-JS or pre-JS environments
  • (-) The UI loads more slowly, and perceived performance is worse
  • (-) The UI can't be used in older browsers at all, or browsers without JavaScript

Server-side only: don't use JavaScript-based interactivity

[edit]

Some user interfaces may not need any interactivity, or can implement the limited interactivity they need in HTML and CSS. In this case, the UI can be rendered entirely on the server, no JavaScript is required, and the browser support and performance issues are moot. Most basic UIs in MediaWiki already work this way.

Codex does not currently support rendering components in PHP, and many components do require JavaScript-based interactivity. However, HTML+CSS-only implementations could be written for a subset of Codex components to support server-side-only interfaces.

  • (+) No performance or browser support issues
  • (-) Only suitable for simple UIs, not for complex/interactive ones
  • (-) Requires duplicate implementation of some Codex components

Progressive enhancement

[edit]

In this approach, the UI is rendered on the server. This UI looks (mostly) like the full UI, but is not interactive. When (and if) JavaScript loads, it enhances the UI by adding interactivity, but doesn't change how the UI looks (or makes only minor changes).

This is how the web worked in the jQuery era, but modern web applications tend to be more complex, and modern web frameworks and libraries tend not to support this method. This method is most suitable for providing smaller amounts of interactivity in simpler UIs.

  • (+) Works in older browsers
  • (+) UI renders quickly, becomes interactive later
  • (-) Interactivity must be defined separately from UI layout
  • (-) Code complexity is difficult to manage when UI is complex and interdependent
  • (-) Not compatible with modern web frameworks/libraries

Separate server and client implementations

[edit]

This is similar to the progressive enhancement approach in that the UI is initially rendered on the server. But instead of enhancing the existing UI, the JavaScript code destroys the server-rendered UI and replaces it with a client-side only UI that looks the same.

This approach essentially combines the server-only and client-only approaches, getting the best and worst of both. The UI is implemented twice, in different languages, and these implementations must be kept in sync for the transition from the server-rendered UI to the client-rendered UI to work correctly, otherwise visible jumps can occur or state information can fail to be preserved.

  • (+) Works in older browsers
  • (+) UI renders quickly, becomes interactive later
  • (+) Interactivity is defined together with UI
  • (-) UI implementation must be duplicated (in JavaScript and PHP)
  • (-) Prone to visible jumps and state management bugs

Vue server-side rendering (SSR)

[edit]

Vue.js is a JavaScript-based UI framework that's primarily designed for client-side use, but it also supports rendering UIs on the server, through a feature it calls server-side rendering (SSR). Similarly to the "separate server and client implementation" approach, the client-side JavaScript takes over once it arrives and makes the UI interactive ("hydrates" it). But crucially, the server and client execute the same code, so no duplication is required.

  • (+) Works in older browsers
  • (+) UI renders quickly, becomes interactive later
  • (+) Interactivity is defined together with UI
  • (+) Code is written once to run in two environments
  • (-) Requires new infrastructure to connect Node.js-based Vue SSR with PHP-based MediaWiki code
  • (-) If that means a Node.js-based HTTP service, fallback behavior is required to handle service downtime
  • (-) May not be available on 3rd-party wikis, necessitating fallback behavior or restrictions on what SSR can be used for

Timeline

[edit]

Project phases come from WMF's Inclusive Product Development playbook.

Phase What? How? Target Start Target Completion Status
Strategize Articulate “why” and “for whom?”

Assess team's capabilities to deliver.

Surface dependencies and risks.

Establish community engagement strategy.

Technical Decision Forum: T317270 September 2022 March 2023 In progress In progress
Discover Better understand the needs and goals of target audience Technical Decision Forum: T317270 September 2022 March 2023 In progress In progress
TODO: Community engagement plan
Define Turn research, insights, etc. into an addressable and achievable scope of work with a concise problem statement. Decide which server rendering methods to use in which cases T322163 November 2022 TBD In progress In progress
Prototype a Vue SSR implementation using V8js T286966 TBD TBD Upcoming
Develop Design and development of solutions and experiments from the DEFINE phase, in preparation for the DELIVER phase. TBD TBD TBD Blocked Blocked
Deliver Deliver and test final code and/or interface. This could be either for delivering a smaller scaled test or final scaled experience to production. TBD TBD TBD Blocked Blocked
Own Monitor and refine based on positive and negative impacts resulting from the product/code delivered. TBD TBD TBD Blocked Blocked

Updates

[edit]

[edit]
  • Project page created

[edit]
  • Technical decision-making process initiated: T317270

How to Engage

[edit]

We welcome and encourage your participation in this initiative. Here are some ways to engage:

  • Add this page to your watchlist
  • Add your questions, concerns, and ideas to the talk page
  • Subscribe to relevant Phabricator tasks, such as: T321356
  • Provide technical input: T322163
  • For Wikimedia Foundation staff: join the #talk-to-design-systems-team Slack channel