Author Archives: Peter

FrankenJS – Franconias first JavaScript user group

A few months ago my friend Dominik and me decided to found the first JavaScript user group for the northern part of Bavaria. At this time we had no clue about the JavaScript-community and interests in this region.

After some weeks of planning and organizing we kicked off the first event at Coworking in Nuremberg, with great talks about BaconJS and GruntJS, self 3D-printed key chains and an awesome audience: 23 people!

3D-printed key chains by @schlotzz.

3D-printed key chains by @schlotzz.

We received a lot of positive feedback and are glad to announce the next meetup at the 2nd of December. So feel free to join us and let’s have a nice pre-XMAS event. It will definitely not be the last JS meetup!

FrankenJS JavaScript Meetup – 02. December 2014 – 7pm – Coworking Nürnberg.

From January 2015 the meetup will take place each month and we are happy about anybody who want to join or contribute to the user group. Everybody is warmly welcome.

Find more information at the Website, follow us on Twitter and join the Meetup.

BTW: we are always looking for people who wanna give a talk :) Please send us the topic and a short description to servus@frankenjs.org.

Safe random numbers in JavaScript

Generating random numbers in JavaScript is really easy. Try to google them; I am pretty sure the most results will show Math.random().

Basically generating a random number in JavaScript looks like this:

Add a bit more randomness to your number by making it a natural number and adding the current time since 1970/01/01 in milliseconds.

As you can see we cast the natural number to a string before adding the current timestamp. It’s more a string concat instead of a mathematical adding. But it makes the result more unique.

In general the result of our random number is good enough to use them as a unique number in the client.

However we have a unique result – it’s not really secure. Math.random() is not desined for cryptographically use. If you want to create more secure numbers you should try window.crypto.

window.crypto is implemented by the most modern browsers. But you should always use feature detection and support a fallback if it’s not supported by the users client.

Yep, the result is always returned as a string. Remove the .toString()/” if you need a proper JavaScript number or cast the result at the end.

Versioning with Local Storage

Local Storage is a HTML5 feature, which comes with most modern browsers. It is a great tool to store client side data. Getting and setting data is very fast and with a good concept, you could save some HTTP requests or run the application offline. Though you should keep in mind that using Local Storage depends on a good data management which keeps the data consistent and prevents from memory exceeding. If you are new into Local Storage, you should notice Mozillas DOM Storage guide before continuing to read.

The first thing you should remember is that Local Storage underlies the same origin policy (SOP). The local data will be stored just for the current domain. This security policy prevents from third party access and helps to not get in conflict with other data. As you already know, the data will be stored as key-value-pairs. So let’s have a look on how the example data could look like.

Imagine we create a very simple mail client, which pre-fills the form and buffers all outgoing mails if the user goes offline. Local Storage is good to deal with offline apps.

Eventually we are going to decide to change the API interface to v2, which is not compatible with v1 anymore. In this case we have to change the api_endpoint setting.

 

The problem

But what would happen if API v2 would not be stable enough? What if our backend throws critical exceptions? In this case we have to roll back to version 1. But some of our customer app-clients are still updated to use the unstable version 2. In this case we just have one option: Fixing the issue in production.

Hence we should use version-controlled data.

To solve the problem, we have to link the data-key with the correct version; so only exclusive keys which make sense to be version-controlled. The buffered_emails property will be shared over all versions. So we’ll keep it global. Okay, let’s start at version 1.

Don’t wonder about the version syntax. 100 means 1.0.0. I’ll explain the reason later.

That’s the key! We just have to integrate the version within the data-key. We could roll out as many client versions as we want to. Just the number of version would be increased. Switching a version becomes very easy.

How to handle different versions?

First of all, we have to add a version prefix to the data-keys, who identifies each entry. The current version must be deployed in addition to map the correct key.

The JSON below is just a concept for how the version-control can be managed.

The _versions key is prefixed with an underscore, to prevent key-conflicts. But it’s just a concept. You can name the property as you want.

Each version must be defined within _versions and must contain all mapped keys. This is quite important because it is impossible to iterate over all Local Storage entries. This guarantees to identify all related keys.

The buffered_emails property remains still “global”.

Limitations

Now we have a great way to manage each version within our client-side app. However Local Storage comes with another limitation: limited disk space.

The W3C recommends a five megabyte storage and the most browsers follow them.

A good way to reduce unneeded data is to drop old versions from your Local Storage. As you remember, we just keep version controlled data to support the option of software-roll-backs. Though our software should be well tested and stable enough to prevent these issues. Hence it should suffice to keep about three versions stored.

Dropping deprecated versions

The simple script below describes how versions can be dropped. The last three versions are still kept.

As you remember we stored the version 1.0.0 as 100 and 2.0.0 as 200. The reason is because we can cast the version to an integer and sort it. This makes dropping old data easier. You can add any numeric version you want:

Major.Minor.Bugfix / 5.15.63 would take 51563.

You should delete deprecated versions before releasing a new one.

Quota Exceeded Error

Even dropping old versions to save disk space can not always prevent memory-exceeding. In case of exceeding quota the browser will throw a QUOTA_EXCEEDED_ERR exception.

It is very hard to identify which key or version caused the error. In case of this error, I would recommend to delete all data.

Removing all data is the safest way to fix the issue. However you should try to avoid this bug due to limiting versions and data. ~5MB are not much of data but definitely enough for your app-client.

Additional notes

There are some things you should be aware of.

Local Storage can only persist values with type of string. If you try to store any other type, your browser will cast the value to string and stores them anyway. Storing an object results in “[object Object]”. If you have to store complex data, it’s highly recommended to use JSON.

If you will get the QUOTA_EXCEEDED_ERR over and over, you have to deal with detailed data-analyzation instead of clearing the storage.

If you have to support old browsers like IE7, using Local Storage is a non option and can be a pain in the ass. Please have a look at the related caniuse.com article. The common fall back is based on cookies.

Conclusion

This article is just a concept for managing client-side data with Local Storage. The scripts and data schemas are examples.

Performance optimization due to event limiting

Speed matters. Browser engines become faster and faster and nearly each month, there are new published benchmarks, to demonstrate the power of JavaScript. However, sometimes we have to reduce events, to keep good performance. Therefore I decided to introduce two very useful UnderscoreJS functions: throttle and debounce.

But in which cases do we have to reduce events? The common cases for limiting events, are user interactions.

  • Touch and mousemove events
  • Window resize event
  • The scroll event
  • Autocompletion while typing (keyup/keydown)

These events can be fired about hundred times per second (per event listener!). At each time, your code would be invoked and slows down your CPU performance. Furthermore the user can not recognize these fast operations, especially DOM manipulations.

Okay, let’s solve the problem and have a look at the differences between throttle and debounce.

Throttle breaks down your operation to a fix interval, which will be invoked as long the user performs the action. So, the operation won’t be called at each event, but in an defined interval.

Have a look at this simple example, to understand how the code works in production.

Using throttle is a good way to fix speed issues. In case of DOM manipulations, I personally prefer setting up throttle with 41 milliseconds, to get ~24 frames per second, which guarantees a fluent DOM animation.

Comparing to throttle, debounce helps you to identify the end of operations. This is useful, if you want to call any code, after the user entered any search term oder stopped resizing the window, etc.

Let’s see how to realize an auto-search:

Here you can find another short example, to see how it works.

Conclusion

These two functions give you a powerful tool to optimize slow JavaScript eventing issues. In case of window resize, it’s strongly recommended to evaluate CSS solutions, to solve the issue. Using CSS is always faster.