Improved Cookie Size Calculation


The Yahoo! User Interface Library (YUI) has a great cookie management system, cookie.js, that handles basic cookie read/write, as well as supporting sub-cookies, which allows multiple pieces of data to be stored in a single cookie. In the article, Augmenting Cookie, I proposed several helpful functions to augment the cookie object, including: getNumberOfCookies, getCookieSize, and isCookiesEnabled. Today’s article revisits the getCookieSize, improving the performance and accuracy of the calculation.

Article updated on Nov. 18, 2015

YUI has been discontinued and there are probably better tools these days in jQuery or other libraries. Also, it is best to avoid cookies when possible since it bloats requests to the server. If possible try using a client-side technology like localStorage.

In the "Augmenting Cookie" article, I used a regular expression to determine the number of non-alpha-numeric characters in a string and then assume that all those characters will be escaped (stored as 3 bytes, instead of 1). So to determine the cookie size, we add 1 byte for every alpha-numeric character and 3 for all other characters. However, further research reveals that the YUI Cookie package uses the encodeURIComponent function to encode all cookies before storing them. So if we take the test string:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456780 ,<.>l/?\";:{[}]|\\+=_-)(*&^%$#@!~`

then it will be stored as 142 bytes:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456780%20%2C%3C.%3E%2F%3F"%22%3B%3A%7B%5B%7D%5D%7C%5C%2B%3D_-)(*%26%5E%25%24%23%40!~%60

This is 16 bytes shorter than what is calculated using the RegExp system, so 8 other characters will be stored as a single byte: -)(*.!~". These characters were added to the regular expression, and now it computes the same length as encodeURIComponent. So we now have an accurate byte size calculation, however, is this faster than just using ecodeURIComponent(yourString).length?

As it turns out, in FireFox running FireBug and using the test string above, the encodeURIComponent is faster, with an average runtime of 0.0141ms. The RegExp method sometimes performed on par with the encodeURIComponent method, but other times it could take as much as 4 times longer to complete the operation, giving an average runtime around 0.0247ms. Therefore, the getByteSize method can be simplified to:

Example 1: New GetByteSize Method

getByteSize: function(s) {
  return encodeURIComponent('' + s).length;
}

And when calculating the size of a cookie, simply pass the key=value to this method.