Speed-up UI with separation of rendering and state

When using touch events with JavaScript on mobile web – slow response is visible. Solution: Update state, but render HTML only by constant timer.

Why mobile web?

Wanted real time updatesFirst version of Auginte zooming based organizer was designed for Desktops, because I was the main (and usually the only) user. But today, if information sharing is the goal – the most common platform remains mobile phone / tablet.

Instead of creating specialized applications for Android, iPhone, Windows Phone and other platforms – I decided to firstly create mobile web version. So basic functionality could be always accessible for majority of the users. Moreover, popularity of “getting mobile app for every aspect of your life” is also decreasing – at least due to higher and higher battery consumption and privacy concerns.

Problem: Slow single threaded environment

When using Desktop application or even Web browser of Desktop computer – you do not feel any lag, because all responses to input are rendered immediately. Rendering time became a problem for me only with large amounts (E.g. 1000) of objects.

For a long time, I resisted switching to mobile web, because there were already memory and speed issues using Desktop version with large amount of elements (or big pictures). How could it still be usable on limited hardware mobile devices?..

First web based Auginte tool: Touch based interaction is hardDespite the fact, new mobile phones have processing power of not old Desktop computer – keeping all interactivity of moving and zooming for me was still a challenge. Therefor, in first web version of Auginte zooming based organizer only touch start and touch end events were updating the state. There were no update while dragging with your finger, because old touch events were stacked and rendered even seconds after dragging was finished. By the way – you can try it online. Same and even bigger problem was with zooming: distinguishing pinch zoom, rotating and moving with 2 fingers was really error prone, especially when user was not getting immediate feedback.

Solution: skip old updates – keep only newest


In the video you can see updating HTML immediately (left side) versus separated state-HTML update (right side). Main code change was:

ElementsApp.subscribe(ElementsApp.zoom(identity))(_ => render(root))
ElementsApp.subscribe(ElementsApp.zoom(identity))(_ => needUpdate = true)
Async.timer(1000 / updatesPerSecond) {
 if (needUpdate) {
   needUpdate = false
   render(root)
  }
}

In code example, instead of updating HTML immediately (render(root)), variable is used to mark the need for update (needUpdate = true) , so actual HTML rendering is triggered via timer (Async.timer is a wrapper for setInterval). So there are less updates, because only latest state is being used for HTML update.

Example is taken from this commit, so you can reproduce situation in the video using revisions before and after the change. Also, you can try draft version online and compare interactivity with older Web based Auginte tool implementation.

Alternatives: Virtual DOM?

Probably examples with Scala.js + Diode are not so common (therefore not easy to understand), but immediate-state versus timer-update principle is independent from framework or programming language. Mobile web example is easiest to demonstrate, but it is not the first even in Auginte project, not to say about game development industry.

Going back to WEB industry, Virtual DOM is closest to principle being discussed:

When a component’s props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM.

As stated in quotation, React.js is used more to check what to change, not when to change. To make your React.js applications faster, you could implement:

shouldComponentUpdate(nextProps, nextState) {
  // Code to compare with frames per seconds
}

At least for first web based Auginte tool, React.js was not the best solution, because it was solving different problem: when most is the same, only small is changed. In Auginte project: by moving or zooming camera almost all (virtual DOM) elements were updated, so timer based approach showed to be better solution.

Debugging and testing mobile performance

Performance issues are best to test on real devices, unless you have time for sophisticated profiling infrastructure. For example, using Chrome DevTools touch events seemed to work very fast, but on actual mobile device it was lagging.

render vs state: debuggingI could connect Desktop browser with Mobile browser, but in current stage adding 2 elements to show metrics for Frames per second and HTML refresh count was sufficient.

So I saw, how Frames per seconds (fps) were dropping with more touch events being stacked. After optimization, I saw that loading of all old elements from storage took only 1 HTML update – so code was working.

Conclusion

Now I am writing this post, and it seems so obvious – still I spent many iteration to came up with this solution. Simple, but powerful one 🙂

Short-term plans: Event-sourced mobile web

Development effort: Mobile web version of Auginte project, because event-sourced storage is needed for collaboration, historical data and not-blocking UI

Current progress

Draft version is deployed at: es.auginte.com. It includes:

  • Auginte Event-Sourced: Draft Version DeployedSimple write-once storage
  • Real time updates
  • Adding and moving elements
  • Mobile/touch screen support
  • Optimization: Time based UI updates

This is not stable version: data could be removed/corrupted, functionality could be changed without notice.

Meaning – you can play around or do some low-risk workshops, but it is not yet recommended to store some sensitive data.

By the way, feedback is always welcome. Use comments or contact directly.

Why event-sourced version is so important?

There were 3 reasons for me to prioritize development of event-sourced functionality:

  1. Event-based/real-time updates makes collaboration more natural. Wanted real time updatesCollaboration is the main difference between personal knowledge management and group knowledge management. While older versions of Auginte tool were concentrating on personal knowledge management (E.g. perception, memory, cognitive overhead), new versions tries to also include aspects of group knowledge management (E.g. implicit/tacit knowledge, reuse of information).  How do you generate new ideas or come up with a better solution?.. Despite searching in the Internet or brainstorming, you can also leverage expertise from colleagues of different backgrounds. Wikipedia (or MediaWiki as a tool) is one of the best known update-save-refresh tool for information collaboration, but real-time (E.g. face-to-face) communication is more natural. Need to periodically press Refresh distracts participants from the topic being discussed to the use of the tool itself. In my opinion, seeing changes as soon as possible is the key aspect of  knowledge-management-oriented tools.
    • Keeping-up with the context is more easier, if you see intention sooner. For example, knowing the end goal, you can try to guess colleague’s next move. If your guess is different, colleague can be making something wrong, something better than you would have done or something out of the topic. So you can fix problems, when those are still inexpensive or stop to realign, to follow the topic again of ask to use a different terminology.
    • Speed of feedback becomes very visible, when discussion is between people from different backgrounds. The more diverse group is, the better chance of getting better solution. While verbal discussions can be very fast, explanation by example can lead to goal sooner. I think, the speed of how fast you can see changes of examples, makes feedback loop smaller and participants can still be concentrated on the topic, not the pauses of the user interface.
  2. Storing changes as events means not loosing data.Auginte Desktop: Versions to store history
    • Over time context (E.g. trends, goals, priorities) is changing. I used my own Auginte tool for project management of same tool ☺ and now I regret, that did not started from event-sourced storage. To know, how initial idea and market changed, I need to use backups, copies of summaries in same workspaces and some hypothesis to recreate lost data – lots of manual work. Therefore, I want to finish event-sourced version first and patch older/other Auginte versions for backward compatibility (e.g. import/export), so I will not be loosing data any more.
    • Talking about short time changes – users (including myself) are so used to Undo function, that content creation without ability to revert changes, makes user experience not so pleasant or even scary. Making backups was a short-term solution and even saved a few times, after program crashed, but recreation from memory was still time consuming. Moreover, lack of trust in storage was creating bad habit to concentrate on remembering last sentence and not on essence of whole work or topic at hand.
    • Talking about distributed environments, conflicts of changing same data by different users can be a really big work stopper. Concerns of lost data, when solving merge conflicts, waiting for others to store their part – is blocking work for all of participants, especially then there are more than few. Using small messages/sentences was short term solution, because there was lower probability of changes by different users in separate elements. Moreover, popular version control systems (E.g. Git) can merge most of the plain data automatically. One of solution of merging distributed data is just store all changes (event source is just like that). I think, it is better to show one newest state and allow the users to recover conflicting data later, when they have time, because disturbance in knowledge creation is less important, than correct data in every operation.
  3. Separation of read and write events can make user interface more responsive.Timer based update HTML update by latest state User interface that freeze from time to time – is very distractive and makes concentration of the topic very hard. Prototype version of Auginte had long auto-save time, so newer version included database as a storage. Saving only new elements or changes was faster, then storing everything from zero. However, working with larger amount of data (~40000 nodes, 1000 visible elements) even synchronization between database become visible. From technical side: it is very hard to create not-blocking/asynchronous user interface, when it is based on blocking/synchronous storage. Storage is one of the slowest parts of the system, especially when considering distributed environment. I think, basing system on write and read streams could make user interface more responsive, dealing with acknowledgements and visualization of not fully loaded/stored elements separately.

What were other alternatives?

  • Better business model: including platform for reusable knowledge, paid Jira integration plugin, donation button, premium features, etc –  is good to have money, but I think it is better to have product to be proud of, rather than just another alternative to competitors. At least at current stage of the project…
  • Have better communication channels for feedback and collaboration – one person cannot change the world. Well, this blog is a result of better public relation. So small part is already done, but I think is easier to get other attention, when you have something to show, not only to sell hopes of what you could do.
  • Stable product, not project – currently there are ~4 different not-fully-finished versions of Auginte tool. One good product would be better, than many drafts. However these are not different projects, but more like a generations of the same project, where technical/business challenges required almost full rewrites. It is only the matter of time, when those will converge into single product.
  • Context tracking was almost migrated from Prototype to Infinity zooming version, but not fully finished. This

Conclusion

Here you go – this was one of the first blog posts, how and where Auginte project is going. Later there will be more blog posts about technical details, knowledge economy and further plans for Auginte project, so do not forget to subscribe to RSS, Facebook, Twitter or Google+ notifications.

Auginte blog starts its journey

Working software is better, than comprehensive documentation

Therefore, most of the effort was spent to create better software, that write about it. Until now…

Sharing insights as presentations

It takes time and many iterations to make good software, but there are plenty of good ideas, that come along the way.  Those ideas were presented in technical meet-ups:

In all those presentations you can see small logo of:

Auiginte Logo (with background)

Because most of the material for those presentations came, while building Auginte project.

Time for blog posts

Blog have a better format to show progress of the project. Including architectural decisions, vision, small and bigger insights.

Project came to the stage, where comments and external input is more valuable than initial idea.