I just finished a talk at Defrag - a conference in Denver, Colorado - and talking with the attendees always leaves me with great insights and discoveries. This conference was no exception.
My current talk is called "The Race Condition". It's about the multi-threading options in JavaScript, and how to use them. It's advanced stuff - most people don't even start thinking about this kind of development issue until they are dug in to SAP UI5, React, Angular.JS, or any of many other frameworks/libraries. And the reason should be obvious...
JavaScript is single threaded.
At least, that's the prevailing wisdom. What's even more interesting is how fast you can knock that theory apart.
Try out the following GIST, and see what you think:
Thread-test.html GIST
During the Q&A after this session, a great questions came up:
Does this matter when you are using OpenUI5/SAP UI5?
The answer, of course, is obvious. But it's also a deep concern. The SAP UI5 framework does a lot of the work for the developer, helping them whip up a quick application. But it's not entirely optimal, and it's easy to forget the framework isn't everything.
For example:
- Data sorting/filtering. The default way to accomplish this is to use the OData service. Pass the sort or filter parameter as part of the query, and the database or middle tier does all the work.There are two inherent problems here. First, you just dumped MVC design out the window. Data presentation is the Visual tier's job. We have smart browsers, super-fast CPU's, and plenty of memory. Even a 2-3 year old smart phone has runtime power greater than a 10 year old PC.And, to make matters worse, we then introduce network lag. Which means a LOT of this:
And this drives me NUTS. We just offloaded a second of work on the front end to 3-10 seconds of network hold. Oh, yeah, that's efficient.Why did we decide more waiting was the solution?
- Loading additional rows. Another aspect of OData loading is the pagination. The OData server will send out a limited number of top rows, and then the client can ask for more.The default for this is to load the data "as necessary". Except we then get back to the same wait.Why? The client knows exactly where the user is on a list. It knows how far they have scrolled. And it has memory to spare.But, loading additional rows in the background (and then merging them) is hard. So we don't do it. More waiting.
So, I think the idea of background processing should be part of the design process from the beginning. If you are mocking up your application, or using Build, follow these steps:
- Take notes on when a "load icon" will appear on each screen, and then create a total.
- Look at the most common pathways through an application. How long does it take? How many "wait" states occur during that flow from beginning to end?
- Create a "pass 2" list of items to optimize. In the first pass of an application, especially in Agile, it can be best to just build the Least Common Denominator. That's OK, but make sure that the time is there to get back to the waiting.
And here is the most important of all:
Use named functions, and break them up.
Writing all of your code as one big method, and using lots of anonymous inline function definitions may look cool, but it's very fragile. If you separate out all the work in to discrete steps, it's much easier later to wrap them up and move them to an asynchronous process.
Just a few thoughts. Thanks for reading. Feel free to email if you have any other ideas!