All Projects → pkamenarsky → Replica

pkamenarsky / Replica

Licence: bsd-3-clause
A remote virtual DOM library for Haskell

Programming Languages

haskell
3896 projects

Projects that are alternatives of or similar to Replica

Ioing
Implement the solutions of performance improvement and componentization for your SPA (single page application) products with this Progressive Web App Development Engine.
Stars: ✭ 224 (+130.93%)
Mutual labels:  virtual-dom, spa
Award
⚙基于react的服务端渲染框架
Stars: ✭ 91 (-6.19%)
Mutual labels:  spa
Nuxt Chat App
Frontend of real-time chat application built using nuxtjs, socket.io. Check the backend at https://github.com/binbytes/chat-app-server.
Stars: ✭ 77 (-20.62%)
Mutual labels:  spa
Preact Redux Isomorphic
preact-redux-isomorphic PWA SPA SSR best practices and libraries in under 80kB page size (for live demo click the link below)
Stars: ✭ 85 (-12.37%)
Mutual labels:  spa
Aspnetcorespa
Asp.Net 5.0 & Angular 11 SPA Fullstack application with plenty of examples. Live demo:
Stars: ✭ 1,211 (+1148.45%)
Mutual labels:  spa
Soma Fm Player
This is a Vue.js web application for streaming radio stations from Somafm.com. This app uses the public SomaFM JSON channels API endpoint to pull in a list of stations and makes it easy to switch between stations. This app also uses Three.js and the HTML5 Web Audio Context API to sample audio data and create a visualizer effect for the selected station.
Stars: ✭ 86 (-11.34%)
Mutual labels:  spa
Laravel Vue Starter
Well Documented Laravel Starter App From Development to Production. For Full Blown RESTFUL API and SPA with Beautiful UI Using Buefy / ElementUi For Reusable Vue Components
Stars: ✭ 76 (-21.65%)
Mutual labels:  spa
Self Learning Materials For Blazor Jp
C# で Single Page Web アプリを開発するフレームワーク「Blazor」の WebAssembly 版 (client-side 版) の自習教材です。
Stars: ✭ 93 (-4.12%)
Mutual labels:  spa
Running Time
Sample Single Page Application using Laravel & Vue.js + Vuex + Vue-Router
Stars: ✭ 90 (-7.22%)
Mutual labels:  spa
Operator
1.8kb drop-in "PJAX" solution for fluid, smooth transitions between pages.
Stars: ✭ 84 (-13.4%)
Mutual labels:  spa
Tupl
The Unnamed Persistence Library
Stars: ✭ 83 (-14.43%)
Mutual labels:  replication
Neo
Create blazing fast multithreaded Web Apps
Stars: ✭ 1,219 (+1156.7%)
Mutual labels:  virtual-dom
Routegen
Define your API and SPA routes in one place. Use them anywhere. Only 1.3kb.
Stars: ✭ 86 (-11.34%)
Mutual labels:  spa
Repmgr
A lightweight replication manager for PostgreSQL (Postgres) - latest version 5.2.1 (2020-12-07)
Stars: ✭ 1,207 (+1144.33%)
Mutual labels:  replication
Wizdm
The ultimate SPA boilerplate
Stars: ✭ 91 (-6.19%)
Mutual labels:  spa
Vue Horizontal
An ultra simple pure vue horizontal layout for modern responsive web with zero dependencies. (SPA/SSG/SSR)
Stars: ✭ 75 (-22.68%)
Mutual labels:  spa
Plus Small Screen Client
本库已经合并进入 https://github.com/slimkit/plus 中,仅提供 2.1 及以前版本下载使用!
Stars: ✭ 83 (-14.43%)
Mutual labels:  spa
Testgres
Testing framework for PostgreSQL and its extensions
Stars: ✭ 85 (-12.37%)
Mutual labels:  replication
Dataformsjs
🌟 DataFormsJS 🌟 A minimal JavaScript Framework and standalone React and Web Components for rapid development of high quality websites and single page applications.
Stars: ✭ 95 (-2.06%)
Mutual labels:  spa
Drc
MySQL active-active replication solution.
Stars: ✭ 92 (-5.15%)
Mutual labels:  replication

Replica

CircleCI

Remote logo

Replica is a remote virtual DOM library for Haskell. In contrast to traditional virtual DOM implementations, a remote virtual DOM runs on the server and is replicated to the client, which just acts as a dumb terminal.

Remote DOM

Quick start

To see it in action, check out the list of Replica frameworks

Motivation

SPAs written in frameworks such as React or Vue often require setting up projects in different languages with their respective build tooling; thinking about protocols between server and client; designing data types for communication (whether explicitly or implicitly) and coming up with a way to keep everything in sync reliably. More often than not this results in copious amounts of boilerplate and support code completely unrelated to the task at hand.

A change on the backend has to be propagated through the server code and protocol or API long before the affected UI components can be adjusted. Conversely, changes in the UI specification or requirements depend upon long-winded thought experiments in data flow before the required modifications on the backend can be pinned down. Prototyping speed slows down and maintenance costs go up.

And so, one often finds oneself longing for the Olden Days of server-side HTML rendering, where all the data was readily available at our fingertips without protocols or different ecosystems to deal with. However, this comes at the cost of losing out on designing UIs declaratively in the spirit of Elm or React and of course on the interactivity displayed by code running directly on the client side.

Remote virtual DOM

Replica seeks the middle ground – it runs a virtual DOM remotely on the server while pushing only minimal diffs to the client, which in turn sends events triggered by the user back to the backend. This offers all the advantages of generating a complete UI on the server, while still providing the interactivity of more traditional SPAs running entirely on the client.

A word about data volume – currently, the data format is not optimised for size at all; that said, it should be comparable to a finely hand-tuned protocol, since only the most minimal changeset is sent over the wire (save for a small-ish constant overhead because of the ceremony caused by the recursive tree nature of the data). In contrast, many APIs are constructed to send the whole requested dataset on every change, so Replica's diffs might fare favourably here. To that point, designing a protocol with minimal data volumes in mind is however also very likely to increase the volume of the aforementioned incidental boilerplate and support code.

Preventing common errors

There is also the additional burden of thinking about sensitive data – a simple select * from users would also send the (hopefully) hashed user passwords back to the client, even though they are not displayed anywhere in the UI. Thinking hard about scrubbing records before throwing something over the wire is laborious and error prone, and humans make mistakes.

With a remote VDOM, all code runs on the backend – no need to come up with ways to share functionality between server and client, to validate forms twice or authenticate API requests.

That is not to say that Replica itself (or its programming model) is more secure than any other program exposed to a network, but a certain class of common errors stemming from the split between back- and frontend are presumably more difficult to make.

Bundle sizes

Megabyte-sized code bundles including hundreds of dependencies can certainly take a bit to download, however parsing and compiling JavaScript is often just as slow. With a remote VDOM, no code at all is shipped to the client (except for the JS driver), only diffs and assets like CSS, images, or fonts. Although there's no support for server-side HTML rendering yet, once implemented it will be just as easy to push everything at once (without having to wait for the driver to establish a WebSocket connection and request an initial DOM update), reducing the time to first render even further.

Testing

Since there is no dependency on a browser environment, simulating UI interactions is just a matter of getting hold of the VDOM and firing a synthesized event on a particular node. QuickChecking components or even metamorphic testing are certainly some interesting avenues to explore in the context of UI testing.

Client side prediction

Replica runs over a WebSocket connection. A virtual DOM wired up with events which might lead to change needs to react to every such event – be it a mouse click or a key stroke. Normally, even on an average connection, some lag between a click on a button and showing the updated UI is fine; not so when it comes to typing. Even a lag of ~50ms becomes noticeable, since the virtual DOM is a complete and accurate representation of the UI displayed to the user and the values of text input elements need to be replicated as well.

Game developers have had to deal with the problem of client side prediction at least since the days of Quake and so the solution space is well understood. For the time being, Replica's algorithm is simple – every event → DOM patch roundtrip increases a frame number on the server and every such patch is tagged with said frame number. Additionally, every input element wired with an event listener keeps its value in a capped queue in the browser DOM for a given number of frames (currently 20). Finally, when the DOM is patched, the input value is not touched if the server value matches any of the previous frame values stored on the client.

Even with a simple scheme like this, the user experience is indistinguishable from code running directly on the client, for the majority of cases, for even higher lag values of ~100–200ms. Rare edge cases do show, but those can be mitigated against in the future by employing more sophisticated client-side prediction algorithms.

Caveats

Since DOM diffing runs on the server, Replica is more resource intensive than a comparable backend implementation which just returns data without diffing. It's not recommended to use it for high-traffic user-facing applications. It might however be the perfect fit for internal tooling where in many cases prototyping and maintenance costs trump hardware prices by a wide margin.

Additionally, events such as onMouseMove are discouraged, even though they are supported in principle. This is because there might be better ways to provide high interactivity in the future – for example, by implemeting a custom, highly optimised onMouseDrag event – than bombarding the server with a torrent of movement events.

There's no support for animations and lifecycle events yet, but the implementation would be relatively straightforward.

Building

Install TypeScript and Stack. Then:

cd js && tsc --project tsconfig.json && cd ..
stack build --test

The TypeScript step must be executed whenever js/client.ts changes.

Integration with UI frameworks

Replica aims to be framework-agnostic. It has a simple API and hooking into it should be as uncomplicated as possible.

The easiest way to run Replica is to call Network.Wai.Handler.Replica.app. This takes care of distributing a complete index.html together with the JavaScript driver to the client. Everything should work out of the box.

For finer grained integration, there's Network.Wai.Handler.Replica.websocketApp, which just handles the WebSocket part of the connection; the root js/index.html and js/dist/client.js must be distributed separately.

Replica.VDOM.diff and Replica.VDOM.fireEvent allow for complete control over the remote virtual DOM.

List of Replica frameworks

Roadmap

  • Hackage documentation
  • Initial server-side rendering
  • SVG support (@seagreen)
  • Better diffing algorithm
  • Lifecycle events and animation hooks
  • onMouseDrag event
  • Nix derivation
  • QuickCheck component framework

Bugs and features

Comments, bug reports and feature PRs very much welcome.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].