planning javascript for larger teams - draft & handout version

121
Planning JavaScript and Ajax for larger teams Christian Heilmann @media Ajax, London, November 2007

Upload: christian-heilmann

Post on 25-May-2015

6.315 views

Category:

Technology


2 download

DESCRIPTION

This is the original draft of my talk at @mediaAjax, I discarded it as it is way too much for one hour :) Hopefully it still is of use for you

TRANSCRIPT

Page 1: Planning JavaScript for Larger Teams - Draft & Handout version

Planning JavaScript and Ajax for larger teams

Christian Heilmann@media Ajax, London, November 2007

Page 2: Planning JavaScript for Larger Teams - Draft & Handout version

Achtung alles Lookenpeepers!Dies Machine is nicht fur gefingerpoken

und mittengraben. Is easy schnappen der springenwerk, blowenfusen und poppencorken mit spitzensparken. Is nicht fur gewerken by das dummkopfen. Das rubbernecken sightseeren keepen Cottenpickenen hands in das pockets - relaxen und Watch Das Blinken Lights. 

Page 3: Planning JavaScript for Larger Teams - Draft & Handout version

Do not fiddle with other people’s knobs unless you know what you are doing.

Page 4: Planning JavaScript for Larger Teams - Draft & Handout version

Spoilers:– Some of the following advice will

seem very basic to you.– This is not based on me thinking

you need this.– It is meant as a reminder. Next

time you encounter these problems you won’t have to think about them.

… and Harry Potter dies, but comes back using a magic stone which is a third of the Deathly Hallows.

Page 5: Planning JavaScript for Larger Teams - Draft & Handout version

There is one main fatal mistake any developer

can make:

Page 6: Planning JavaScript for Larger Teams - Draft & Handout version

There is one main fatal mistake any developer

can make:

Make assumptions

Page 7: Planning JavaScript for Larger Teams - Draft & Handout version

“I don’t need to tell people that, they know

already.”

Page 8: Planning JavaScript for Larger Teams - Draft & Handout version

“Surely this has been done already, and by

people better than me.”

Page 9: Planning JavaScript for Larger Teams - Draft & Handout version

“This works right now, there won’t be a need to

change it.”

Page 10: Planning JavaScript for Larger Teams - Draft & Handout version

“This never worked in the past, it won’t work now.”

Page 11: Planning JavaScript for Larger Teams - Draft & Handout version

“We hack that now, and will get time later to fix

it.”

Page 12: Planning JavaScript for Larger Teams - Draft & Handout version

“This is a minor issue only for this instance, no need

to file a bug.”

Page 13: Planning JavaScript for Larger Teams - Draft & Handout version

All these mistakes are yours to make.

Page 14: Planning JavaScript for Larger Teams - Draft & Handout version

Sometimes they need to be made in order to prove a new point or prove an issue and its solution.

Page 15: Planning JavaScript for Larger Teams - Draft & Handout version

However, avoiding them means you help all of us

working together.

Page 16: Planning JavaScript for Larger Teams - Draft & Handout version

No more heroes!

Page 17: Planning JavaScript for Larger Teams - Draft & Handout version

A good developer is not a very gifted and

impressive developer.

Page 18: Planning JavaScript for Larger Teams - Draft & Handout version

It is a developer that can work with others and

works for the next developer to take over.

Page 19: Planning JavaScript for Larger Teams - Draft & Handout version

People will move from product to product or leave the company.

Page 20: Planning JavaScript for Larger Teams - Draft & Handout version

Web products are never finished.

Page 21: Planning JavaScript for Larger Teams - Draft & Handout version

Don’t leave a mess behind; work as if you

won’t see the code ever again.

Page 22: Planning JavaScript for Larger Teams - Draft & Handout version

Mistakes we make:

Page 23: Planning JavaScript for Larger Teams - Draft & Handout version

1. Mixing structure, presentation and behaviour.

2. Trusting the browser.3. Trusting the markup.4. Not planning for inclusion.5. Not planning for failure.6. Premature optimization.

Page 24: Planning JavaScript for Larger Teams - Draft & Handout version

This should be a no-brainer by now but we

still do it.

Page 25: Planning JavaScript for Larger Teams - Draft & Handout version

Separation means:

–Working in parallel (to an extend)

–Re-skinning an application by changing the style sheet

–Caching, Minimizing, Optimizing for speed and delivery.

Page 26: Planning JavaScript for Larger Teams - Draft & Handout version

Not separating means:

–Harder maintenance –Larger and slower sites –Several sources for bugs without an easy way to track them.

Page 27: Planning JavaScript for Larger Teams - Draft & Handout version

1. Mixing structure, presentation and behaviour.

2. Trusting the browser.3. Trusting the markup.4. Not planning for inclusion.5. Not planning for failure.6. Premature optimization.

Page 28: Planning JavaScript for Larger Teams - Draft & Handout version

The last thing to trust is the browser.

Page 29: Planning JavaScript for Larger Teams - Draft & Handout version

They all have shifty eyes and will steal your loose change when you don’t

look.

Page 30: Planning JavaScript for Larger Teams - Draft & Handout version

Testing for a browser name and assuming it

can do certain things is a bad plan.

Page 31: Planning JavaScript for Larger Teams - Draft & Handout version

Browsers come in all kind of setups and with all kind of extensions.

Page 32: Planning JavaScript for Larger Teams - Draft & Handout version

Assume the browser will fail and keep poking it

until it tells you all is OK.

Page 33: Planning JavaScript for Larger Teams - Draft & Handout version

Making assumptions:

function showMessage(elm, message){

elm.firstChild.nodeValue = message;

}

Page 34: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 35: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 36: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 37: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 38: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 39: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 40: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 41: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 42: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 43: Planning JavaScript for Larger Teams - Draft & Handout version

function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } }}

Page 44: Planning JavaScript for Larger Teams - Draft & Handout version

Bit overkill, isn’t it?

Page 45: Planning JavaScript for Larger Teams - Draft & Handout version

–Add tests for the browser early (init method)

–Use library functions that do the testing for you.

Page 46: Planning JavaScript for Larger Teams - Draft & Handout version

1. Mixing structure, presentation and behaviour.

2. Trusting the browser.3. Trusting the markup.4. Not planning for inclusion.5. Not planning for failure.6. Premature optimization.

Page 47: Planning JavaScript for Larger Teams - Draft & Handout version

HTML markup of the document is never set in

stone.

Page 48: Planning JavaScript for Larger Teams - Draft & Handout version

Don’t rely on it.

Page 49: Planning JavaScript for Larger Teams - Draft & Handout version

document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline';

Page 50: Planning JavaScript for Larger Teams - Draft & Handout version

document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline';

Page 51: Planning JavaScript for Larger Teams - Draft & Handout version

1. Mixing structure, presentation and behaviour.

2. Trusting the browser.3. Trusting the markup.4. Not planning for inclusion.5. Not planning for failure.6. Premature optimization.

Page 52: Planning JavaScript for Larger Teams - Draft & Handout version

Assuming your script is the only one included in

the document:

Page 53: Planning JavaScript for Larger Teams - Draft & Handout version

Assuming your script is the only one included in

the document:

hasfail = true;

Page 54: Planning JavaScript for Larger Teams - Draft & Handout version

Namespace your scripts, follow a naming

convention and don’t leave any global variables

or methods.

Page 55: Planning JavaScript for Larger Teams - Draft & Handout version

That way your script will run even if it has to work

alongside bad code.

Page 56: Planning JavaScript for Larger Teams - Draft & Handout version

Bad code will be added to your documents, most of the time in the form of

advertisements or tracking code.

Page 57: Planning JavaScript for Larger Teams - Draft & Handout version

1. Mixing structure, presentation and behaviour.

2. Trusting the browser.3. Trusting the markup.4. Not planning for inclusion.5. Not planning for failure.6. Premature optimization.

Page 58: Planning JavaScript for Larger Teams - Draft & Handout version

Things will fail, plan for it!

– JavaScript will not be available.–Ajax connections will take too long or return wrong data.

–Plan for a fallback option (redirect to a static page, show an error message)

Page 59: Planning JavaScript for Larger Teams - Draft & Handout version

<a href="javascript:ajaxmagic('panda')">

Show results for 'panda'

</a>

Page 60: Planning JavaScript for Larger Teams - Draft & Handout version

<a href="javascript:ajaxmagic('panda')">

Show results for 'panda'

</a>

Page 61: Planning JavaScript for Larger Teams - Draft & Handout version

<a href="search.php?term=panda" id="searchlink">

Show results for 'panda‘

</a>

var YE = YAHOO.util.Event;

YE.on('searchlink','click',ajaxmagic);

function ajaxmagic(e){

var t = YE.getTarget(e);

var url = t.href.split('=')[1];

ajaxcode(url);

YE.preventDefault(e);

}

Page 62: Planning JavaScript for Larger Teams - Draft & Handout version

Re-use the backend script

function ajaxmagic(e){

var t = YE.getTarget(e);

var url = t.href + &output=json';

ajaxcode(url);

YE.preventDefault(e);

}

Page 63: Planning JavaScript for Larger Teams - Draft & Handout version

1. Mixing structure, presentation and behaviour.

2. Trusting the browser.3. Trusting the markup.4. Not planning for inclusion.5. Not planning for failure.6. Premature optimization.

Page 64: Planning JavaScript for Larger Teams - Draft & Handout version

Each of us has a little hacker inside who wants

to get out.

Page 65: Planning JavaScript for Larger Teams - Draft & Handout version

This little hacker wants to make things as fast, small

and cool as possible.

Page 66: Planning JavaScript for Larger Teams - Draft & Handout version

This little hacker is also very competitive and doesn’t trust reused

code or libraries.

Page 67: Planning JavaScript for Larger Teams - Draft & Handout version
Page 68: Planning JavaScript for Larger Teams - Draft & Handout version

Our job is not to give in to it when we produce production code.

Page 69: Planning JavaScript for Larger Teams - Draft & Handout version

Production code does not need to be optimized

from the start.

Page 70: Planning JavaScript for Larger Teams - Draft & Handout version

It needs to be understandable and

maintainable.

Page 71: Planning JavaScript for Larger Teams - Draft & Handout version

–use library code, even if it appears huge (a lot of the size is a myth)

–Use comments to explain what is going on

–Use explanatory variable and method names

–Don’t reinvent the wheel even if you consider yours superior.

Page 72: Planning JavaScript for Larger Teams - Draft & Handout version

Enough bad. Give us some tips!

Page 73: Planning JavaScript for Larger Teams - Draft & Handout version

1. Follow a diet plan.2. Have a build process.3. Have a code standard and

documentation process.4. Review and reuse code.5. Plan for extension.6. Think maintenance

Page 74: Planning JavaScript for Larger Teams - Draft & Handout version

Try to avoid traps that make your code hungry:

–Cut down on DOM interaction –Minimize the amount of loops –Build tool methods to deal with reoccurring problems

Page 75: Planning JavaScript for Larger Teams - Draft & Handout version

Use shortcut notations in JavaScript.

Page 76: Planning JavaScript for Larger Teams - Draft & Handout version

var links = new Array();

links[0]='http://icant.co.uk';

links[1]='http://wait-till-i.com';

links[2]='http://onlinetools.org';

Page 77: Planning JavaScript for Larger Teams - Draft & Handout version

var links = new Array();

links[0]='http://icant.co.uk';

links[1]='http://wait-till-i.com';

links[2]='http://onlinetools.org';

var links = [

'http://icant.co.uk', 'http://wait-till-i.com', 'http://onlinetools.org‘

];

Page 78: Planning JavaScript for Larger Teams - Draft & Handout version

var contact = new Object();

contact.name = 'Christian';

contact.surName = 'Heilmann';

contact.age = 32;

contact.hair = 'slightly red';

Page 79: Planning JavaScript for Larger Teams - Draft & Handout version

var contact = new Object();contact.name = 'Christian';contact.surName = 'Heilmann';contact.age = 32;contact.hair = 'slightly red';

var contact = {name:'Christian',surName:'Heilmann',age:32,hair:'slightly red'

};

Page 80: Planning JavaScript for Larger Teams - Draft & Handout version

if(hasCheeseburger){cat.mood = 'happy';

} else {cat.mood = 'sad';

}

Page 81: Planning JavaScript for Larger Teams - Draft & Handout version

if(hasCheeseburger){cat.mood = 'happy';

} else {cat.mood = 'sad';

}

cat.mood = hasCheeseburger?'happy':'sad';

Page 82: Planning JavaScript for Larger Teams - Draft & Handout version

if(hasCheeseburger){cat.mood = 'happy';

} else {cat.mood = 'sad';

}

cat.mood = hasCheeseburger?'happy':'sad';

condition

Page 83: Planning JavaScript for Larger Teams - Draft & Handout version

if(hasCheeseburger){cat.mood = 'happy';

} else {cat.mood = 'sad';

}

cat.mood = hasCheeseburger?'happy':'sad';

true case

Page 84: Planning JavaScript for Larger Teams - Draft & Handout version

if(hasCheeseburger){cat.mood = 'happy';

} else {cat.mood = 'sad';

}

cat.mood = hasCheeseburger?'happy':'sad';

false case

Page 85: Planning JavaScript for Larger Teams - Draft & Handout version

if(obj.getClass()==='full'){var x = screen.left;

} else {var x = current;

}

Page 86: Planning JavaScript for Larger Teams - Draft & Handout version

if(obj.getClass()==='full'){var x = screen.left;

} else {var x = current;

}

var x = (obj.hasClass()==='full') ? screen.left : current;

Page 87: Planning JavaScript for Larger Teams - Draft & Handout version

var cat;

if(canHasCheeseburger){

cat = canHasCheeseburger;

};

if(garfield){

cat = garfield;

};

Page 88: Planning JavaScript for Larger Teams - Draft & Handout version

var cat;

if(canHasCheeseburger){

cat = canHasCheeseburger;

};

if(garfield){

cat = garfield;

};

var cat = canHasCheeseburger || garfield;

Page 89: Planning JavaScript for Larger Teams - Draft & Handout version

var cat;

if(canHasCheeseburger){

cat = canHasCheeseburger;

};

if(garfield){

cat = garfield;

};

var cat = canHasCheeseburger || garfield;

one or the other, defining a fallback

Page 90: Planning JavaScript for Larger Teams - Draft & Handout version

var massive.name.with.long.namespace = { ...private stuff... return{ init:function(){ massive.name.with.long.namespace.show();

}, show:function(){ massive.name.with.long.namespace.test();

}, test:function(){ } }}();

Page 91: Planning JavaScript for Larger Teams - Draft & Handout version

var massive.name.with.long.namespace = { var pub = {};...private stuff...pub.init = function(){

pub.show();};pub.show = function(){

pub.test();};pub.test = function(){};return pub;

}();massive.name.with.long.namespace.init();

Page 92: Planning JavaScript for Larger Teams - Draft & Handout version

var massive.name.with.long.namespace = {function init(){

show();};function show(){

test();};function test(){};return {

init:init;show:show;test:test;

};}();massive.name.with.long.namespace.init();

Page 93: Planning JavaScript for Larger Teams - Draft & Handout version

1. Follow a diet plan.2. Have a build process.3. Have a code standard and

documentation process.4. Review and reuse code.5. Plan for extension.6. Think maintenance

Page 94: Planning JavaScript for Larger Teams - Draft & Handout version

–Production code is not live code.

–That doesn’t happen on the back-end and it shouldn’t happen on the front-end.

–Live code is there for machines, production code is there for humans.

Page 95: Planning JavaScript for Larger Teams - Draft & Handout version

Build process:–Validation (Tidy, JSLint)–Minification (JSMin, CSS minifier)

–Consolidation (one CSS and one JS instead of dozens)

–Tagging as “live code” – do not edit!

Page 96: Planning JavaScript for Larger Teams - Draft & Handout version

1. Follow a diet plan.2. Have a build process.3. Have a code standard and

documentation process.4. Review and reuse code.5. Plan for extension.6. Think maintenance

Page 97: Planning JavaScript for Larger Teams - Draft & Handout version

Following a code standard means you can:–Assess quality of code –Find bugs easily and create reproducible bug reports

–Have quick handover from developer to developer

–Have reliable version control

Page 98: Planning JavaScript for Larger Teams - Draft & Handout version

What code standard?

Page 99: Planning JavaScript for Larger Teams - Draft & Handout version

Whatever the team agrees on and feels comfortable with.

Page 100: Planning JavaScript for Larger Teams - Draft & Handout version

Document it and other teams can validate what

you have done.

Page 101: Planning JavaScript for Larger Teams - Draft & Handout version

In the perfect world, we’ll all follow the same code

standard.

Page 102: Planning JavaScript for Larger Teams - Draft & Handout version

Let’s meet again in a year! :-)

Page 103: Planning JavaScript for Larger Teams - Draft & Handout version

Comments are good, but they are not

documentation.

Page 104: Planning JavaScript for Larger Teams - Draft & Handout version

Write documentation in peer review - as the

developer you are too close to the subject.

Page 105: Planning JavaScript for Larger Teams - Draft & Handout version

Plan and ask for time to document what you have

done.

Page 106: Planning JavaScript for Larger Teams - Draft & Handout version

1. Follow a diet plan.2. Have a build process.3. Have a code standard and

documentation process.4. Review and reuse code.5. Plan for extension.6. Think maintenance

Page 107: Planning JavaScript for Larger Teams - Draft & Handout version

Conduct Code reviews–You find problems and solutions you can share in the team.

–You find out who knows what well and who needs training in what

–You share the knowledge throughout the team = no Divas.

Page 108: Planning JavaScript for Larger Teams - Draft & Handout version

– If you keep finding the same problem and different solutions for it, find a generic solution and re-use that one.

–Look at what other people have done (libraries).

–Bounce your solutions off other development teams.

Page 109: Planning JavaScript for Larger Teams - Draft & Handout version

1. Follow a diet plan.2. Have a build process.3. Have a code standard and

documentation process.4. Review and reuse your code.5. Plan for extension.6. Think maintenance

Page 110: Planning JavaScript for Larger Teams - Draft & Handout version

Whenever you write some code, don’t think that

your implementation will be the end of it.

Page 111: Planning JavaScript for Larger Teams - Draft & Handout version

Make sure that your code can be extended by

other people and try to build it as modular as

possible.

Page 112: Planning JavaScript for Larger Teams - Draft & Handout version

1. Follow a diet plan.2. Have a build process.3. Have a code standard and

documentation process.4. Review and reuse your code.5. Plan for extension.6. Think maintenance

Page 113: Planning JavaScript for Larger Teams - Draft & Handout version

Not everybody maintaining your code will be as good as you

are.

Page 114: Planning JavaScript for Larger Teams - Draft & Handout version

Trying to find where to change what in a piece of

code is terribly frustrating.

Page 115: Planning JavaScript for Larger Teams - Draft & Handout version

Separate out as much of the look and feel as you

can.

Page 116: Planning JavaScript for Larger Teams - Draft & Handout version

Also separate out labels that are likely to change and the names of CSS classes and IDs in use.

Page 117: Planning JavaScript for Larger Teams - Draft & Handout version

So how do you plan JavaScript and Ajax for

larger teams?

Page 118: Planning JavaScript for Larger Teams - Draft & Handout version

Get the team to talk and agree on what works

best.

Page 119: Planning JavaScript for Larger Teams - Draft & Handout version

Involve Design and Engineering in the

process and explain the rationale of your plan.

Page 120: Planning JavaScript for Larger Teams - Draft & Handout version

Communication and sharing information is

better than any architectural blueprint you or I could come up

with.

Page 121: Planning JavaScript for Larger Teams - Draft & Handout version

THANKS!

Christian Heilmann

http://[email protected]