Posts Tagged: Javascript

When JavaScript was first introduced, I dismissed it as being not worth my attention. Much later, I took another look at it and discovered that hidden in the browser was an excellent programming language. My initial attitudes were based on the initial positioning of JavaScript by Sun and Netscape. They made many misstatements about JavaScript in order to avoid positioning JavaScript as a competitor to Java. Those misstatements continue to echo in the scores of badly written JavaScript books aimed at the dummies and amateurs market.

When data in cache invalidates?

Here is an interesting statistics on how the cache is used nowadays:

  • 55% of resources don’t specify a max-age value
  • 46% of the resources without any max-age remained unchanged over a 2 week period
  • some of the most popular resources on the Web are only cacheable for an hour or two
  • 40-60% of daily users to your site don’t have your resources in their cache
  • 30% of users have a full cache
  • for users with a full cache, the median time to fill their cache is 4 hours of active browsing

There are a number of reasons why browser could make a conditional request for item that is already in the cache:

  • The cached item is no longer fresh according to Cache-Control or Expires
  • The cached item was delivered with a VARY header
  • The containing page was navigated to via META REFRESH
  • JavaScript in the page called reload on the location object, passing TRUE for bReloadSource
  • The request was for a cross-host HTTPS resource on browser startup
  • The user refreshed the page
Read more!

How to check if browser caching disabled

As you may know there are several ways to “tell” the browser or proxy-server what to cache and what to do not cache. They’re reliable and commonly used across the browsers, but if there is no proxy-cache in the middle and user disabled browser’s cache then your client cache policy will be ignored. In this case you may want to adjust your cache policy and be more effective in cache-less environment.

Before starting our findings, I’d like to outline that I’ll test my approach in IE8, IE9, FF 9 and Chrome 18 browsers. Also we should assume that there is no proxy-caches or reverse proxy-caches on the way to the server. All results in my experiment will be sent to javascript console.

CSS caching and optimizations

So, let’s consider the ways to check browser (or proxy) cache availability. The main idea is simple – load some mutating resource couple times and see whether they (copies) are equal or not. By saying “mutating resource” I mean .css or .js or any other resource which has different content each time user request it from the server. For example, we may have .css file with the following content:

.cachedetect{ width: [incremental number here]px; }

where [incremental number here] will be replaced with some different number each time the resource is requested. Then we will apply .cachedetect style to some div element on the page and measure it’s width by using javascript. And finally we can say whether div’s width was changed after browser downloaded the .css file for the second time.

But having such .css is a bad approach as browsers (except IE9) have implemented optimization to do not load the same .css file twice if it’s address is equal. In other words, such html will lead to only single HTTP request to the server:

<link type="text/css" rel="stylesheet" href="cssdetect.css">
<link type="text/css" rel="stylesheet" href="cssdetect.css">

Amusingly, if first .css request was done from HTML markup, and second one was done from javascript, then even IE9 won’t download it for second time.

Read more!

Javascript: Paradox of NaN

 

One thing I always amusing with Javascript is NaN. Arguably, NaN is a bit quirky in most languages, but it really interesting in Javascript. (For those of you that don’t know, NaN stands for “not a number”). Consider:

typeof NaN === 'number'; // true 
NaN === NaN; // false 
NaN !== NaN; // true
NaN + 1; //NaN
1 < NaN; //false

There are four kinds of operation which return NaN:

  • Operations with a NaN as at least one operand
  • Indeterminate forms

The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞ 
The multiplications 0×∞ and 0×−∞
The power 1^∞
The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.

  • Real operations with complex results:

The square root of a negative number
The logarithm of a negative number
The tangent of an odd multiple of 90 degrees (or π/2 radians)
The inverse sine or cosine of a number which is less than -1 or greater than +1.

  • Invalid Number constructor or invalid number string during parsing operation
Read more!

Substring: Chrome or Firefox?

While working on big and complex web applications you’ll be faced to performance issues sooner or later. Its just a matter of time. So one of my recent issues was related to slowdown of the app in Chrome in one particular case. Chrome is well known for it’s V8-super-duper-fast engine and I was surprised that Firefox works faster in that case.

The case I’m talking about is processing large amount of big strings. Don’t want to dig into app-specific functionality, so let’s go ahead with the only knowledge that we have to do a lot of substring operations on very long strings in JavaScript.

Later I implemented simple test which reflects my real-world-code in order to investigate the difference:

function doTest(){ 
    var chars = []; 
    var n = 1024 * 1024;//number of chars in our string, so it will allocate 1024 * 1024 * 16 bits = 1024 * 1024 * 2 byte = 2048 kB 
    var i = 0; 
    while(i < n) { 
     chars.push(String.fromCharCode(32 + Math.floor(Math.random() * 91))); 
     i++; 
    } 
    var s = chars.join(''); //making the Big string      
    i = 0; 
    var start = (new Date).getTime(); 
    while(i < 10000){ 
      var c = n / 2; //get string of the half size of initial string size 
      var r = s.substring(s.length - c, s.length);//copy from c to the end of the string 
      i++; 
    } 
    var diff = (new Date).getTime() - start; 
    output('Diff: ' + diff);//Chrome - 3606, FF - 2 
} 
function output(s){ 
  document.write('You\'re using ' + BrowserDetect.browser + ' ' + BrowserDetect.version + ' on ' + BrowserDetect.OS + '</br>'); 
  document.write(s); 
}

Note: I’ve used simple BrowserDetect script from quirksmode in my test.

Read more!