Discovering Web Workers

So I wanted to learn about Web Workers, since they are (as far as I have come to understand) the only real way of running javascript in a separate thread. The following post is my explanation of the concept as I have percieved it at the time of learning.

Note: I wrote this post in the process of learning, meaning I’m not an expert. Don’t take my word as the truth. They’re just my interpretation of what others have said, and my own tests.

Web Workers

Web Workers allows running scripts “in the background”, in a separate thread from that of the user interface, allowing tasks to be performed without disturbing the user experience. Since javascript is a single threaded language, only able to simulate multithreading by using for example yield() or setInterval(), workers might be the only option for running javascript in separate threads. At least as far as I know.

Some things to know about web workers

  • Workers have a high start-up performance cost
  • Each worker instance consume a high amount of memory
  • Workers are not intened to be used in large numbers at the same time

A worker should not be something you call frequently to perform small tasks, since the cost of calling the worker will exceed the benefit of running it in a separate thread.

So when do you use Web Workers then? Well, if you want to run something that has a high performance cost, without interfering with the user experience, web workers can be a viable option. Uses can include for example perform heavy calculations, or having a “listener” for notifications running in the background.

So how do you do it?

Simple example

First of all, I have a simple html page, with a span to post my results, and buttons to start and stop my worker.

Next, I have a javascript file being loaded to the page. This is not my worker, but the script responsible for calling the worker. I call it foreman.js.

The first thing I want to do is to get my resultSpan element to present the results of the workers. I also create a variable for storing my worker object.

Next I create a function for stopping the worker.

Not all browsers support workers, so a function to check for worker support might be a good idea.

And now to the important parts. We want to be able to call our worker, and create a function for doing just that.

The first thing I do is checking if the browser supports workers. If it doesn’t, I can handle it in different ways. This is good if you don’t want your functionality to break due to compatibility issues.

Then I instantiate a new worker object, referencing the worker javascript file. And yes, the worker code needs to be located in a separate file.

Now when we have the worker object, we need to define what will happen when we get a response from it.  Communication between the foreman and worker will be passed through messages, and we need to declare what to do with those messages. The code below shows 2 ways of doing the same thing.

In the code above, we declare that when we recieve a message from the worker, we will get that message and show it in our resultSpan by setting its innerHTML.

We may also want to handle what happens if an error occurs. In addition to the .onmessage event, we can declare the .onerror event for just this reason.

The last thing is to call the worker. This is done by calling the postMessage function of the worker object.

What will happen now is that the worker javascript will be loaded and executed. The results will depend on what we put in the worker.js file. All we have done in foreman.js is to say that we will present the results of the worker. So let’s take a look at the actual worker: worker.js.

In this simple example, all I want to do is to illustrate a continuous process being run in the background. The worker runs a recursive function every 500 milliseconds and sends the response back to the foreman. The message is being passed by calling the postMessage function. The object put as a parameter in postMessage will be available in event.data in the foreman script. In this case it’s an integer, but it could just as well be a string or JSON object.

Calling specific worker functions

You cannot call a specific function within a worker directly. When the worker is called, it simply runs the file. However, you can implement your own handling by passing function names as parameters.

In my next example, I have another worker file, skilledWorker.js. It contains three functions. I choose to store these in an object called actions, and you will see why later. This is not required however, and there are many ways of implementing support for calling certain functions.

Next, I need to declare what will happen when my worker receives a message.

This says that I should call the function handleMessage and pass my event whenever a message is received. All that’s left is implementing the handleMessage function.

What happens here is that we retrieve the event.data, and get two properties from it, command and parameters. These has to be passed when calling the worker, and I will show how in a bit.

The next piece of code I got a little help from my friend and colleague Anatoly Mironov who has one of the best SharePoint blogs out there.

Since we store our functions in the object called actions, calling “actions[command]” will return the function matching the command string. If no functions matches, the value will simply be undefined. The simple if-statement allows you to check and handle what happens when trying to call a function that doesn’t exist.

The last thing we need to do is to call the worker passing the correct command and parameters.

Passing parameters

Calling a worker with parameters is still done with postMessage(). You can pass either a string or a JSON object. This example will demonstrate how to pass a JSON object. Passed parameters will be available in the worker in event.data. As you saw above, our workers handleMessage function needed the data to contain .command and .parameters. So when calling postMessage() we simply input a JSON object containing these two values.

In the code above, each  line will call the worker, but running different functions, which in turn use different parameters.

In conclusion

Web workers are not very difficult to work with once you understand how they work, and while their use might be limited due to the heavy initial performance cost, being able to running a background thread for large tasks can be quite powerful.

If you want to check the full code I have a GitHub repository for it here: https://github.com/Johesmil/webworkers.

If you want to learn more about Web Workers from people who actually know what they’re talking about, check out the links below. =)

Sources

Web Workers

http://www.htmlgoodies.com/html5/tutorials/introducing-html-5-web-workers-bringing-multi-threading-to-javascript.html
http://www.w3schools.com/html/html5_webworkers.asp
https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers
http://anders.janmyr.com/2013/02/web-workers.html
http://www.html5rocks.com/en/tutorials/workers/basics/

CSS Vertical Align or: How I Learned to Stop Worrying and Love Display: Table

I grew up with it and it’s hard to shake. It follows me around, looking over my shoulder everytime I try to position anything. That deeply ingrained hatred of tables. Nothing was as ugly and disgraceful as using tables to position content (that and maybe using capital letters for your tags).

  • What, are you not using THE BOX MODEL? I can’t work like this.

I sometimes sit and glare longingly at those at the office that don’t have to support the older versions of IE. Imagine the glory and wonder of using Flexbox! To be able to roll around in align-items: center, revel in justify-content and delight in flex width. But, alas. It is not so, using flexbox for corporate oriented (especially SharePoint) styling is still some years off.

But I still have to vertically align things all the time. And that’s the reason for this post. Yes, it is true. I have started to use tables to get things to where I want them. Not actual tables, but virtual ones with div and span elements with display table. And I have come to, maybe not love it, but at least rather like it. It sort of works, if used correctly. There is a learning curve, an especially steep one if your brain is telling you to RUN AWAY. But with some time and determination you too can get there.

The problem to solve

Typically we’re talking about an icon that should be centered vertically to a text of unspecified height. Position: absolute won’t help you here, nor will margin top, since the height varies. What I used to do was use a background image with background-position: center. But these days we have to take retina screens into account. Begone blurry images!

But what about svg?

says you.

Yes, that would also be nice, but legacy systems prevent me from using that (long story, SharePoint is to blame). Also I would like to utilize icon libraries like FontAwesome.

The solution

Use table layout for this!
The wrapping parent gets:

And then every child element gets

And no padding or margin top or bottom on the children, that messes everything up. Both child elements now becomes as high as the highest of them, and the content is placed in the vertical middle. Magic.

Want a clearer picture and try it out yourself? Here’s a plunker where you can do that.

So you tried this and there’s no magic?

The problem with this method is that it’s mad hard to “debug”. It’s insanely difficult to understand what’s wrong when something is off in the aligning. Try to remove all set height, line-height and margins and paddings on the child elements, as well as all other positioning styling (relative or absolute).

Nothing new under the sun

Yes, people have of course used this before, but that doesn’t mean everyone has, or that it isn’t news to someone. After all, until recently I didn’t use it and I spend a fairly large amount of my day arguing with CSS.

Resetting SharePoint Search Configuration Cache

Now it is the second time it happens that the search cannot return any results. This hickup is rare but it happens. To solve it I had to follow these steps:

  1. Stop the Timer Service
  2. Clear the configuration cache
    1. Find in ProgramDataMicrosoftSharePointConfig the folder where the file cache.ini exists
    2. Delete every file from this folder EXCEPT cache.ini
    3. Open cache.ini, delete the content and put ’1′ (without the quotes) in it and save the file
  3. Restart the Timer Service
  4. Index reset
  5. Full crawl

Source: ITIDea. The linked blog post saved my afternoon today. Thank you, Anita Boerboom.

Resetting SharePoint Search Configuration Cache

Now it is the second time it happens that the search cannot return any results. This hickup is rare but it happens. To solve it I had to follow these steps:

  1. Stop the Timer Service
  2. Clear the configuration cache
    1. Find in ProgramDataMicrosoftSharePointConfig the folder where the file cache.ini exists
    2. Delete every file from this folder EXCEPT cache.ini
    3. Open cache.ini, delete the content and put ’1′ (without the quotes) in it and save the file
  3. Restart the Timer Service
  4. Index reset
  5. Full crawl

Source: ITIDea. The linked blog post saved my afternoon today. Thank you, Anita Boerboom.