Problem statement
Our front-end and CDN architecture is facing formidable challenges. Close to 50% of our users are now using mobile devices in a wide range of specifications and form factors. Bandwidth conditions range from barely-connected 2G to gigabit fiber to the home. Use cases range from a quick definition look-up to immersive browsing with rich media and data-driven visualizations.
In response to the wide range of requirements, we have created a mobile site using MediaWiki's skin system, some content post-processing, and user agent based redirects. This site is now serving a sizeable chunk of our overall traffic, but it is ultimately still a fairly static server-side HTML skin. Its scaling relies on Varnish caching layers serving the vast majority of anonymous requests. These caching layers are fairly complex and inflexible. Significant customization of responses by user, device, or bandwidth conditions are typically not feasible without disabling edge caching altogether. This means that such customizations are currently limited to authenticated users, at the price of disabled caching and thus significantly higher request latencies.
Our native apps side-step a lot of these issues. They are pure API consumers, and perform most customizations in the client. This makes it a lot simpler to experiment with new ideas in the client, while still benefiting from caching of fairly static API responses. However, the vast majority of our users are using the web, and don't yet benefit from the same levels of performance and customization.
Proposed solution
This task proposes to leverage recent developments in the web platform to bring app-like levels of performance, customization and functionality to the general web experience. New browser features like ServiceWorkers have recently made it feasible to apply the API-driven front-end strategy to the web, without incurring the complexities and performance penalties of traditional single-page applications. While some of these web platform features are fairly cutting edge (ex: ~61% support for ServiceWorkers), they are generally designed to work as progressive enhancements, with server-side fall-backs facilitated by the convergence of client-side and server-side technologies around JavaScript. By gradually moving the bulk of per-request customization to clients, we should be able to use freed-up server-side resources to provide the same level of customization for the long tail of older clients, at latencies comparable to or better than those seen by authenticated users right now.
If proposal T106099 comes to be, and we have "page composition service" in production, we can extend its use case from the Wikipedia.org to also apply to MediaWiki-powered page views.
Before we can this, however, we need to make significant changes to MediaWiki core.
Dependencies
Concrete steps:
- Refine page component interfaces & dependency metadata: T105845: RFC: Page components / content widgets
- Define a high-performance async / streaming composition system on top of components: T106099: RFC: Page composition using service workers and server-side JS fall-back
- Set up a server-side ServiceWorker environment that allows running the same code server-side: T116126: Provide server-side ServiceWorker interfaces
- Create a page component API / "null skin" to enable use of existing UI code as components: T114596: [RFC] Method for bare page retrieval (e.g. render only / no skin)
- Replicate the mobile web user experience, with an eye towards demonstrating performance and flexibility potential.
- Gather performance and compatibility data.
- Assess what it would take to make this production-worthy.
- Summarize data and experience, and inform the longer-term API and front-end strategy; discuss it at the Developer Summit in early January.
Potential benefits
- Performance
- Authenticated views aren't currently cacheable, which means that editors are getting worse performance than anonymous users. An API-driven front-end lets us cache general content separately from per-user data, which means that authenticated views can be fully cached, bringing performance on par with anonymous users.
- Potentially reduce first-view-in-session latency for returning visitors by keeping offline copies of static assets.
- Potential for full offline support.
- Through improved caching, reduce load on the app server cluster from cache misses, reducing hardware needs and environmental impact.
- Composition can be implemented efficiently as string concatenation, without a need for expensive DOM parsing and -manipulation.
- Potential to initialize VE without re-loading content.
- Architecture
- Introduce a clean API separation between data and UI/UX layer. This will drive API and content / data representation improvements, reduce complexity in the data layer, and accelerate front-end innovation from WMF & others.
- Reduce code and test duplication by using the same JavaScript code for client-side & server-side content composition.
- Clean no-JavaScript fall-back to server-side rendering without code duplication.
- Reduce complexity in caching layers by separating per-user from per-page data.
- Avoid complexity and performance issues of single-page apps.
- Allows gradual testing of Parsoid HTML for page views, possibly as a beta feature.
- Design / product
- Potential to support more user customization and dynamically updated content elements without incurring cache fragmentation and increased latency.
- Quicker iteration on the client, using technology front-end engineers are familiar with.
- Further reading
- "Fast and Resilient Web Apps" presentation by Ilya Grigorik, including interesting data on connectivity challenges, failed navigations & regional differences.
- https://corporate.tuenti.com/en/dev/blog/a-faster-tuenti-lessons-learned-in-client-side-scalability
- https://office.wikimedia.org/wiki/User:Gwicke/Reorg_discussion
See also
- T105845: RFC: Page components / content widgets
- T106099: RFC: Page composition using service workers and server-side JS fall-back
- T99088: [RFC] Evolving our content platform: Content adaptability, structured data and caching
- T88301: RFC: Clean frontend - backend separation; make all frontends API consumers