Coming from a JAVA / ABAP background into Javascript and UI5, one thing i struggled a bit with was the single threaded way of running your code in JS. Which basically means that if you have a “heavy” script running, then your user interface will be unresponsive until the script has finished, leaving a poor user experience for your end user, or even worse getting that annoying popup:

http://i1.wp.com/ejohn.org/files/chrome-dialog.gif

I had a look at some resources and while there is most likely other ways of doing what i will teach you in this blog. I do hope you can see the benefits of using this technology for your work in the future.

So what am i talking about?

Let me introduce  you to HTML5 Web Workers

/wp-content/uploads/2016/03/13496315673_17b33a6030_o_901775.jpg

I know, i know, i know. This is Emmet from the LEGO movie! but i really wanted a hardhat in this blog and have a profound love for LEGO. But anyhow that is now done and dusted, so let’s get on with the interesting stuff.

So the web workers definition is:

“A web worker is a JavaScript running in the background, without affecting the performance of the page.”


Specifically speaking it is just a JS file that we can interact with throughout our application. However it does have some limitations as you don’t have access to the DOM or any UI5 libraries per standard as it runs in another thread. So you need to push data etc to the web worker to handle your requests.


So what does that mean for us as developers; Well, that means that as earlier mentioned you can you the web worker to run a long running script in the background and still have the user to be able to interact with your UI5 app, also you could use the web worker to send multiple asynchronous requests to the backend to update your odata models or even generating your views before your users invoke them.

Obviously this can have a tremendous impact on the user experience as the user will have no lag, when navigating back and forth throughout your app.

In my example i have developed an odata service that uses the EPM sales orders and item details. I have used a Webide template for a worklist as i wanted just a simple multiview application. In short i cut all the corners i could to get to work on the web worker. And while my example might not be the most useful, because the actual loading of the details for a single entity doesn’t take more than less than a second for me, i do think that it  proves my point.

In my example the user gets the initial list of 20 sales orders, as soon as that  list is retrieved from the backend, then the web worker starts to push requests for the details part of the sales orders and updates a JSON model as soon as a response  have been given. If the user clicks on a sales order, that hasn’t been loaded yet, then it is simply just retrieved from the backend as normal.

Not all browsers supports the web worker, but it is pretty much standard in all major newer browsers, eg IE10, Chrome, Safari and Firefox. Check out the link above for more specific details.

But you can do an easy check to see if you an use the web worker or not in a browsing session.

if(typeof(Worker) !== “undefined”) {

If this check is complete, then we can initialize our web worker

var w = new Worker(“../demo_workers.js”);

Afterwards you can post messages to the webworker and pass data along to it as well.

So in my example i have used a map reduce to create an array with the url strings for the item details.

I also add in a command to be able to handle multiple commands and also the length of the array to be able to handle multiple updates in the worker.

w.postMessage(“initial~” +jsonArray.toString() +”~” +jsonArray1.length);

To be able to recieve a message either from the web worker or in the web worker you use the function onmessage.

So in my web worker i have a self.onmessage function

self.onmessage = function(msg) {

    var msgArray = msg.data.split(“~”);

    // Get the lenght of the jsonArray1 from the worklist controller, to know where to start.

    count = msgArray[2];

    if (msgArray[0] === “initial”) {

        sendWorkerArrBuff(msgArray[1]);

    }

};

And in my controller i have a onmessage as well receiving data from the web worker either to update my jsonmodel or to let the user know that everything has been cached.

w.onmessage = function(entry) {

                    if (entry.data === “Done”){

                        sap.m.MessageToast.show(“All Done”);

                        //w.postMessage(“next:” +this.getView().getModel().sServiceUrl);

                    }

                    else{

                    var newEntry = entry.data;

                    jsonArray1.push(newEntry);

                    jsonModel.setData({modelData : jsonArray1});

                    sap.ui.getCore().setModel(jsonModel, ‘OrderDetails’);

                    }

                };

The last bit is just that i send requests to the backend retrieving the necessary data.

While my example isn’t the best, i do hope it gives a clear understanding of what you can use the web worker for. Imagine a scenario where you would have multiple nested odata requests from one list and needed to generate multiple views, this would leave the user with many small delays. this can be avoided with using the web worker to structure your communication with the backend instead of using asyncrounous requests in a controller.

So in short the important things here are the following commands:

  • if(typeof(Worker) !== “undefined”) = true, then it is ok to use the web worker
  • postmessage = send message from and to a web worker
  • onmessage = receive messages from or in a web worker.

I have published my example on github,

GitHub – kovboyjder/sapui5_WebWorker

i haven’t uploaded the EPM odata service as that is pretty basic stuff. You can have a look at this blog to do something similar to mine if you want to redo my example

Association and Navigation in OData Service – SAP Netweaver Gateway

This video shows how it works in action

Please share your comments on this blog if you have any criticism or questions.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply