Skip to content

Huangphoux/the_datastar_way

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Datastar Way

The ideal (not dogmatic) way of using Datastar to build real-time, collaborative web apps, as well as simple websites using this mental model, without losing any performance.

Additional Infos
  • Credit me (Huangphoux) if you use any part of this.
  • All linked sources are of my own picking. I don't get paid to write any of this.
  • If you're productive with React or htmx, keep using it.
  • The shift in thinking from htmx to Datastar is as big as from React to htmx.
  • There are other hypermedia libraries, as well as a comparision between some of them.
  1. Hypermedia System

    • Respond with HTML instead of JSON.
    • Use data-on to generalize hypermedia controls: data-on:click="@get('/endpoint')"
      • Any element can make HTTP requests: data-on
      • Any event can trigger HTTP requests: click
      • Use Backend Actions to send any type of requests: @get('/endpoint')
  2. Fat Morphing

    • Respond with the entire modified page.
    • The morphing algorithm will convert the old page into the new modified one.
  3. SSE: open an long-lived connection to stream reponses to the client.

  4. Brotli: compress the whole stream with tunable memory.

Without much adjustments (differentiating users by session IDs), by doing this way, multiplayer is the default behavior.

data-on: the only attribute that you would need

Additional Infos
  • The string evaluated by data-on attributes are Datastar expressions, you can do more than using only Backend Actions.
    • data-on:click="confirm('Are you sure?') && @delete('/examples/delete_row/0')"
  • Be sure to use request indicators, as they are an important UX aspect of any distributed apps: data-indicator:_fetching, data-attr:disabled="$_fetching"

Fat Morphing

  • Suitable for collaborative app: all users see the same updated page
  • Behave similarly to htmx's hx-boost, but Datastar morphs and retains elements, instead of swapping the whole <body> like htmx.
  • Yes, you're doing MPA (Multi-Page Application). It's hypermedia-driven. Did you read the book?

Fat

  • Send the entire modified page instead of small, specific fragments.
  • Reduce the amount of endpoints needed to handle fragment updates.
Additional Infos
  • Be sure to use Event Bubbling
  • Use data-on:pointerdown/mousedown rather than data-on:click → No need to wait for pointerup/mouseup

Morphing

You don't actually need to know how the algorithm works under the hood if you respond with the whole page anyways.

Additional Infos
  • It can also be called "Patching": Create, Update and Delete elements
  • There are other algorithms as well: Morphlex (the introductory article), and Datastar's TypeScript port of Idiomorph.
  • The algorithm retains unchanged elements, but the way we respond with the whole page is immediate.

How to do Fat Morphing optimally

This is one way of doing Fat Morphing, Datastar can do polling just fine.

Optimal Fat Morphing

CQRS

  • To do Fat Morphing optimally, we should limit the number of endpoints that can change the view, since we don't need to send small fragments.
  • CQRS stands for Command Query Responsibility Segregation, meaning separating the Commands and the Queries of data apart.
  • Commands: Create, Update and Delete
    • HTTP equivalence: POST, PUT, PATCH, DELETE
    • These are all actions that change the data. These should not directly update the view.
      • Queries already take care of that responsibility.
      • Instead of patching elements, they can patch signals.
  • Queries: Read
    • HTTP equivalence: GET
    • This action can retrieve data and watch for data changes to compute the view
    • Work Sharing, or Caching: make sure the query runs only once if multiple users are requesting the same view.

Event-Driven Architecture

  • Queries watch for data changes by watching for new Command.
  • Whenever there's a new Command, the Queries retrieve the modified data.
  • Use the Publish-Subscribe pattern to implement Event-Driven Architecture
  • By using CQRS, our app becomes the purest view=function(state)
  • A function turning state into view: present data using HTML, then compute it as a page ⇒ Data drives views
  • All data stored and processed on the back end
  • On every data change, the page gets re-computed
  • Each page only needs one single function to compute the page

SSE

Suitable for real-time apps: updates can be sent in a stream that get compressed for its whole duration

Brotli

  • A lossless data compression algorithm.
  • Specifically created to compress HTTP stream.
  • Compressing a stream of data is better.
    • There would be a lot of duplications in the stream.
    • Compression reduces those duplications effectively by forward and backward referencing.
    • Compression ratio is much larger over streams than when compressing a single HTML/JSON response.
  • Tunable context window
    • The memory shared between the server and the client, stores the past and future data.
    • You should increase it from the default 32 kB to reduce network and CPU usage on the client.
  • A demonstration of Brotli's effective compression by Anders Murphy.
Stats and comparison for nerds

Stats

  • Here are some anecdotal statistics, provided by members of the Datastar Discord server.
    • Screenshot by winkler1. A screenshot by user "winkler1.", showing compression efficiency: original stream size 26 MB, compressed to 190 kB. Stream duration 1.2 minutes, latency 11 ms.
      • Compressed 26 MB down to 190 kB, over 1.2 minutes.
      • Compression reduced size by 137 times.
    • Testimony provided by jeffmarco
      • Compressed 6 MB down to 14 kB, over 30 seconds.
      • Compression reduced size by 429 times.

Comparison with gzip

  • Gzip can't look ahead effectively and can't look back at all.
  • Non-adjustable 32 kB context window.
  • Not built with streaming support in mind.
  • Worse than Brotli 4 to 6 times over a stream.
    • Using gzip for streaming is still better than regular request-response.
  • A comparison between gzip and Brotli, done by Anders Murphy. A comparison between gzip and Brotli, done by Anders Murphy, which shows how Brotli compresses 2 times better than gzip out of the box.
    • Over the same size SSE streams, out of the box, Brotli compresses 2 times better than gzip.
    • With tunable memory, you can get 3 times (or more!) better compression.

Notes

Here are some notes regarding using Datastar that aren't important to be included in this document.

About

How to build new web apps the Datastar way

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published