September  08

Bad ways to loop in JavaScript

Date: September 08, 2009. written by Prashanth Comments»

Hope you might have read my previous article Associate array are bad in Javascript, let me get in one step further beside associate array, what are the bad ways to loop a DOM, array, node list in JavaScript. Some of the Bad ways:

1. for (var i=0; i < arr.length; i++) {}
2. while (x = arr.pop()) {}
3. while (x = arr.pop()) {}
4. for (var i in arr) {} (this is the worst, remember JavaScript is not Python :p)
5. for (var i=0; arr[i]; i++) { var x = arr[i]; }
Better way:
for (var i=0, len=arr.length; i < len; i++) {}

Length of a HTML collection is expensive

Remember every DOM operation that you make is expensive so think of ways you can minimize. When are trying to do DOM operation like looping on a HTML collection with length its live during your looping user might make some change which might change the length of the collection. So, the better way is to avoid the length.

People are so used to JavaScript libraries and try to do array.item(i) rather than doing doing array[i], array[i] is like a hash value so its pretty fast, array.item(i) is a bad way.
for (var i=0, node; node = collection[i++];) {}

September  08

Apple new announcement 9th September

Date: September 08, 2009. written by Prashanth Comments»

There are rumors that apple is going to make some big announcement tomorrow(9th September) about media event and few new products. So, what are the products likely to get something new or a upgrade?

1. iPods
2. iTunes
3. Apple Tablet

More above all these Steve Jobs who recently back to work after battling illness is likely to make his public appearance. There are rumors that he will be giving the key note. Lets us wait for tomorrow.

July  25

Firefox memory leak

Date: July 25, 2009. written by Prashanth Comments»

I am facing this strange memory leak problem when I open any of the google's heavy JavaScript application in firefox.


whenever i open gmail or google reader the memory usage of firefox goes up to 100%. But this doesn't happen either in safari or opera. Is firefox the culprit? Is anyone is facing this problem?

Ok Its not just me or the mac many of them are facing the same problem in almost all the operating systems.


http://www.codinghorror.com/blog/archives/000537.html
Bug Filed
Is Firebug doing this?

July  06

New Mac book

Date: July 06, 2009. written by Prashanth Comments»

Hurry!, I bought a new macbook white poly carbonate.


June  14

Node list is not array

Date: June 14, 2009. written by Prashanth Comments»

Node list is a collection of DOM Nodes. Most of them who code in Firebug tend to consider the node list as array because it looks like any other array. Node list has just two properties length and index. If you want to iterate on that you can use the old school way of incrementing the index or do any of the Enumerable functions by passing node list to call method. Let me show how to do that.

Example:
>>> foo = $$('div.post')
[div.post, div.post, div.post, div.post, div.post]
>>> Array.prototype.splice.call(foo)
>>> foo.each(function(item){console.log(item)})
<div class="post">
<div class="post">
<div class="post">
<div class="post">
<div class="post">
[div.post, div.post, div.post, div.post, div.post]

So what does call do? Call allows you to invoke a function as if it were a method of some other object. On above example foo is a node list its not a array but still I could able to splice that. ECMAScript specifies two methods call and apply. Both does relatively same job except the type of the argument. Apply takes a array as a argument.

June  14

speed up your website

Date: June 14, 2009. written by Prashanth Comments»

I incline this post more towards google app engine or application that runs on python/Django. There are quite a few tools which will analyze your website and suggest the possible idea to improve the performance of your website. I use Yslow. The beauty about yslow is it grades your website and suggest the changes to improve it.


Implementation in python

Combine Files:

If your website has multiple JavaScript or CSS files you can combine them into one.

class Jsmin(webapp.RequestHandler):
 def get(self):
  data = memcache.get(key="js")
  if data is None:
   data = ""
   path = os.path.join(os.path.dirname(__file__), 'js/')
   files = ["prototype_1.6.1.js", "blog_2.1.js"]
   for file in files:
    f = open(path+file,'r')
    data += jsmin(f.read()) + '\n'
   memcache.add(key="js", value=data, time=31536000)
   self.response.headers['Content-Type'] = 'text/javascript'
   self.response.headers['Cache-Control'] = 'public max-age=31536000'
   self.response.out.write(data)

CSS Sprites

CSS Sprites is a good idea to combine all the images into one so that you can save the number of HTTP request back and forth to the server. You can either use GIMP or use sprites generator. Sprites generator takes up the images combine them into one and the beauty is it gives the position so that you can directly copy(Specially if you are a n00b in tools like GIMP which I am :p. So I choose to use csssprites).

Your style will look something like this:
background:url(/images/combine.gif) no-repeat scroll -98px -98px
There are places where you need to do inline images and have a src pointing to your image path in your server. You can base encode those images. You can use data: URL scheme
import base64
f = open('fp.png')
base64.b64encode(f.read())
You can add this in your template:
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH hhx4dbgYKAAA7"

Cache static files

Static file like CSS, JavaScript and Images can be cached on the browser. So that browser doesn't send request back every time when the page is hit. If you are using google app engine you can add a line in your app.yml like this "default_expiration: '365d'". If you are combining files this rules doesn't apply since you will be pointing to a script file. So can set the header like "self.response.headers['Cache-Control'] = 'public max-age=31536000'" this sets the cache expiry to one year from now. So If you are updating these static files you can suffix the files with some unique number ("blog_2.1.js"), usually its better to have version number. When make updations to your static files since browser doesn't request for these files your new code will have no effect. So its important to change the name of these files.

Minify

You can save some size by stripping of the space and newline in your CSS and Javascript. JSMin was written by Crockford it has a python implementation as well. Refer to my JSMin class at the first section of this post.

May  20

Associate array are bad in JavaScript

Date: May 20, 2009. written by Prashanth Comments»

Associate array in javascript: An array is a linear allocation of memory in which elements are accessed by integers that are used to compute offsets. Arrays can be very fast data structures. Unfortunately, JavaScript does not have anything like this kind of array. Instead, JavaScript provides an object that has some array-like characteristics. It converts array subscripts into strings that are used to make properties.

>>foo = new Array()
>>foo[100] = 'bar'
>>foo.length
101

You can call foo as anything you like (Boolean, or Date, or String) all will work. It works because all you are doing is setting properties on an object in JavaScript foo['bar'] and foo.bar is one and same. When you iterate on the foo all you do is iterating on the properties. Remember all data type in JavaScript are object. Use array as a object and don't store key/value pairs.

>> foo['bar'] = 'buz'
>> foo['foobar'] = 'foobarbuz'
>> foo.length
0

May  20

starting javascript

Date: May 20, 2009. written by Prashanth Comments»

My law "When you don't know what you are doing sit back read and then code."

Most of the people start writing JavaScript without learning it( ridicules!). Like much of the language JavaScript also has good and bad parts. If you start doing something without learning it you will end up writing something non-standard or bad practices.

JavaScript despite having few bad parts its has some extra ordinary good parts which makes the language cool, beautiful, elegant, highly expressive language. So, to be a better programmer in JavaScript learn the good things, know the bad things and code the good things avoiding the bad part. Its very important to learn good things when you learn a language because its hard to unlearn the bad things.

Why JavaScript?

JavaScript is THE language of web browser, sun came up java applet gave a try to override JavaScript ended in a failure. Applet is just crap(You are a java lover you will find hard time reading my blog because I bash Java a lot :) and you thing java and JavaScript are one and the same I am gonna kick your ass get lost. Let me write about the name history behind JavaScript in a another post.). I call JavaScript as THE language because you don't have any other option. I see JavaScript is often blamed for browser hang probably because of you are doing extensive DOM operation. This is not the fault with JavaScript, DOM API very awful and JavaScript is unfairly blamed.

Good and Bad:

Good parts of JavaScript are loose typing, dynamic object, include functions and very bad part of JavaScript is using global variables. Some of the other good parts are lexical scoping, lambda(these is not unique, it resembles more of lisp). JavaScript is object oriented and class free. So inheritance happens between objects. Most of them who are from a strong typed languages feel bit hard to get used to it. People ask how would you identify a variable's type. I learned programming using Lisp, Python so I am much used to it and trust it is a good.

May  20

JavaScript comments

Date: May 20, 2009. written by Prashanth Comments»

JavaScript offers two form of comments:

  1. Block comments /* */
  2. Line ending comments //

Comments are pretty important for readability but obsolete comments are worse than no comments. The /* */ form of block comments came from a language called PL/I. PL/I chose those strange pairs as the symbols for comments because they were unlikely to occur in that language's programs, except perhaps in string literals. In JavaScript, those pairs can also occur in regular expression literals, so block comments are not safe for commenting out blocks of code.

/* var bar = 'baz'; var foo = 'foobar'.match(/\w*/g); alert(foo); */

In the above case the block comment close on the match which was not the intention. So better way is to do line ending comment(//).

May  20

Twitter updates in blog

Date: May 20, 2009. written by Prashanth Comments»

You are a twitter hero and like to show twits on your blog or twitter update this post is for you. So how to do it? Its pretty simple if you don't have a private updates. Just make a request to http://twitter.com/statuses/user_timeline/.format. Format can be either xml or json.

>>> from xml.dom import minidom
>>> import urllib2
>>> req = urllib2.Request('http://twitter.com/statuses/user_timeline/google.xml')
>>> response = urllib2.urlopen(req)
>>> xml = response.read()
>>> dom_object = minidom.parseString(xml)
>>> tags = dom_object.getElementsByTagName('text')
>>> for text in tags:
    ... print text.toxml()
... Power to the people! Announcing our first Google PowerMeter partners http://bit.ly/POraB
RT @googlereader Find out about the latest set of Reader tweaks http://bit.ly/155AOM
Making Spock proud: Gmail Labs auto-translates email in 41 languages http://bit.ly/oC1Q6
Congratulations to the class of 2009! Commencement addresses from Googlers http://bit.ly/17PBCb
RT @GoogleAtWork: Don't take a rain check, check for rain - 4 day weather forecast right in Google Calendar: http://bit.ly/7KXjc
Easy go, easy come: Gmail makes it braindead-simple to import mail from your other accounts http://bit.ly/14SSed
Attention video game vets. Remember Galaxy Game? One of our guys does http://bit.ly/g8UyD
RT @kevinmarks - Google I/O Ignite speakers announced: http://bit.ly/P6tbJ #ignite #googleio
RT @googlestudents: Marissa Mayer delivers the commencement address at the Illinois Institute of Technology on May 16 http://bit.ly/14bO3z

If you have private update, set your username and password in HTTP header and get the update or you can use Python twitter. If you are using google app engine for your application, app engine doesn't allow your to have a file cache or extensively use tempfile which is the case with Python twitter. Now all you have to do is roll up your sleeves and disable to file cache and use app engines memcache. I will tell you how to do it.

Download python twitter and open twitter.py, go to the _FetchUrl function you can see a comment "# Open and return the URL immediately" add these line above that comment
url_data = opener.open(url).read() return url_data
and change the line import simplejson to from django.utils import simplejson. Now all set If you want to hit twitter api for each and every hit on your page it will be ridiculous and time taking. So, the solution is memcache.
data = memcache.get("twitter")
if data is not None:
  return data
else:
  api = twitter.Api(username='foobar', password='buz')
  data = api.GetUserTimeline('foobar')[0:5]
  memcache.add("twitter", data, 3600)
  return data
3600 is seconds after which the cache will expire. Mail me if you have some issue with disabling the file cache in python twitter.