Intro
Phoenix LiveView is very attractive for real-time & rich interactive web app. I have worked with LiveView for 2 years and very like it.
For the first project I worked, I make some mistakes by misunderstand about it. After spend time to deep dive into LiveView I can work well with LiveView and see more way to improve & optimize it. Now I share it, hope people can go faster than me.
Phoenix LiveView and how it works and how to optimize it
I take a lit of bit about LiveView and how it works for us can have a same view about LiveView.
LiveView in runtime separated to two phases:
- First phase is regular HTTP get request from client and server response full HTML for client (in case Javascript(JS) is disable user can see some thing, friendly with search engine).
- Second phase is run by JS in client and data pipe between client & server is WebSocket(WS).
As above flow we see LiveView has 2 times spawn process follow two phase that I write.
For first phase, we can improve responsive by ignore unnecessary content. We can use function connected?/1
inside mount event to do that.
Each LiveView it has its process and state(store in socket.assigns) we need avoid to storage big common item in that(imagine your server service some hundred thousands user in same time) better for common things is bring it to other place like ETS table.
State of LiveView is isolated but we can easily add a pipe by Phoenix PubSub or Registry module to share some data for all LiveViews in system.
LiveView has some callbacks to handle events from both client and other process. In case for newbie I just show event flow for major events and ignore some layer, event, loop wait,...
From event flow above we can know mount event is entry point of LiveView process (for both phases). It initialize state and render & other events can use.
Thing to remember in here is doesn't push too much data in mount event because LiveView will render full HTML for this event, if push too much data our LiveView will less responsive & client will take time to load it to UI.
To optimize for a huge data or latency(data need get from somewhere) we can use async
operation. Async will spawn another process to run async task then LiveView can send a fast response to client and update data when it's ready.
To optimize a big data list we can use stream
. It save time for LiveView in first time render & we still can update/insert or delete it in the future (like chat app or list of a lot items). After send to client LiveView process doesn't handle stream data in memory then we can save a lot of memory.
For other things like update to 3rd lib we can use hook, common case is update GPS route to Google map.
And a thing we need to remember is LiveView is server side rendering, LiveView uses a ton of techniques to optimize (see how LiveView optimizes render at Dashbit blogs) it but small thing we still need to remember. That is avoid render big list of DOM in dynamic content(code LiveView will execute every state changed). Bring it to static contend if can!
Conclusion
From above optimization guide LiveView can easy support for a mount of data and still get fast response, rich interactive and real-time features.
So things we need to memory:
- Async operation for fast response to client, data will be pushed later.
- Stream for large list need to update/insert/delete later.
- Using hook for special things.
- Using connected?/1 to ignore things in first phase (regular get request).
Top comments (1)
Very cool!
Sometimes when I need to delay the data load and want to add something more UI friendly I usually send an event on mount to a handle_info and load that there, meanwhile, I show a spinner to the UI.