0
Planning JavaScript and Ajax for larger teams Christian Heilmann @media Ajax, London, November 2007
Achtung alles Lookenpeepers! <ul><li>Dies Machine is nicht fur gefingerpoken und mittengraben.  </li></ul><ul><li>Is easy ...
<ul><li>Do not fiddle with other people’s knobs unless you know what you are doing. </li></ul>
<ul><li>Spoilers: </li></ul><ul><ul><li>Some of the following advice will seem very basic to you. </li></ul></ul><ul><ul><...
<ul><li>There is one main fatal mistake any developer can make: </li></ul>
<ul><li>There is one main fatal mistake any developer can make: </li></ul><ul><li>Make assumptions </li></ul>
<ul><li>“ I don’t need to tell people that, they know already.” </li></ul>
<ul><li>“ Surely this has been done already, and by people better than me.” </li></ul>
<ul><li>“ This works right now, there won’t be a need to change it.” </li></ul>
<ul><li>“ This never worked in the past, it won’t work now.” </li></ul>
<ul><li>“ We hack that now, and will get time later to fix it.” </li></ul>
<ul><li>“ This is a minor issue only for this instance, no need to file a bug.” </li></ul>
<ul><li>All these mistakes are yours to make.  </li></ul>
<ul><li>Sometimes they need to be made in order to prove a new point or prove an issue and its solution. </li></ul>
<ul><li>However, avoiding them means you help all of us working together. </li></ul>
<ul><li>No more heroes! </li></ul>
<ul><li>A good developer is not a very gifted and impressive developer. </li></ul>
<ul><li>It is a developer that can work with others and works for the next developer to take over. </li></ul>
<ul><li>People will move from product to product or leave the company. </li></ul>
<ul><li>Web products are never finished.  </li></ul>
<ul><li>Don’t leave a mess behind; work as if you won’t see the code ever again. </li></ul>
<ul><li>Mistakes we make: </li></ul>
<ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting t...
<ul><li>This should be a no-brainer by now but we still do it.  </li></ul>
<ul><li>Separation means: </li></ul><ul><ul><li>Working in parallel (to an extend) </li></ul></ul><ul><ul><li>Re-skinning ...
<ul><li>Not separating means: </li></ul><ul><ul><li>Harder maintenance  </li></ul></ul><ul><ul><li>Larger and slower sites...
<ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting t...
<ul><li>The last thing to trust is the browser.  </li></ul>
<ul><li>They all have shifty eyes and will steal your loose change when you don’t look. </li></ul>
<ul><li>Testing for a browser name and assuming it can do certain things is a bad plan. </li></ul>
<ul><li>Browsers come in all kind of setups and with all kind of extensions.  </li></ul>
<ul><li>Assume the browser will fail and keep poking it until it tells you all is OK. </li></ul>
<ul><li>Making assumptions: </li></ul><ul><li>function showMessage(elm, message){ </li></ul><ul><li>elm.firstChild.nodeVal...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){  </li></ul><ul><li>var elm = docu...
<ul><li>Bit overkill, isn’t it? </li></ul>
<ul><ul><li>Add tests for the browser early (init method) </li></ul></ul><ul><ul><li>Use library functions that do the tes...
<ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting  ...
<ul><li>HTML markup of the document is never set in stone.  </li></ul>
<ul><li>Don’t rely on it.  </li></ul>
<ul><li>document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue =...
<ul><li>document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue =...
<ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting t...
<ul><li>Assuming your script is the only one included in the document: </li></ul>
<ul><li>Assuming your script is the only one included in the document: </li></ul><ul><li>hasfail = true; </li></ul>
<ul><li>Namespace your scripts, follow a naming convention and don’t leave any global variables or methods.  </li></ul>
<ul><li>That way your script will run even if it has to work alongside bad code. </li></ul>
<ul><li>Bad code will be added to your documents, most of the time in the form of advertisements or tracking code. </li></ul>
<ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting t...
<ul><li>Things will fail, plan for it! </li></ul><ul><ul><li>JavaScript will not be available. </li></ul></ul><ul><ul><li>...
<ul><li><a href=&quot;javascript:ajaxmagic('panda')&quot;> </li></ul><ul><li>Show results for 'panda' </li></ul><ul><li></...
<ul><li><a href=&quot;javascript:ajaxmagic('panda')&quot;> </li></ul><ul><li>Show results for 'panda' </li></ul><ul><li></...
<ul><li><a href=&quot;search.php?term=panda&quot; id=&quot;searchlink&quot;> </li></ul><ul><li>Show results for 'panda‘ </...
<ul><li>Re-use the backend script </li></ul><ul><li>function ajaxmagic(e){ </li></ul><ul><li>var t = YE.getTarget(e); </li...
<ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting t...
<ul><li>Each of us has a little hacker inside who wants to get out. </li></ul>
<ul><li>This little hacker wants to make things as fast, small and cool as possible.  </li></ul>
<ul><li>This little hacker is also very competitive and doesn’t trust reused code or libraries. </li></ul>
 
<ul><li>Our job is not to give in to it when we produce production code.  </li></ul>
<ul><li>Production code does not need to be optimized from the start. </li></ul>
<ul><li>It needs to be understandable and maintainable. </li></ul>
<ul><ul><li>use library code, even if it appears huge (a lot of the size is a myth) </li></ul></ul><ul><ul><li>Use comment...
Enough bad. Give us some tips!
<ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentati...
<ul><li>Try to avoid traps that make your code hungry: </li></ul><ul><ul><li>Cut down on DOM interaction  </li></ul></ul><...
<ul><ul><li>Use shortcut notations in JavaScript. </li></ul></ul>
<ul><li>var links = new Array(); </li></ul><ul><li>links[0]='http://icant.co.uk'; </li></ul><ul><li>links[1]='http://wait-...
<ul><li>var links = new Array(); </li></ul><ul><li>links[0]='http://icant.co.uk'; </li></ul><ul><li>links[1]='http://wait-...
<ul><li>var contact = new Object(); </li></ul><ul><li>contact.name = 'Christian'; </li></ul><ul><li>contact.surName = 'Hei...
<ul><li>var contact = new Object(); </li></ul><ul><li>contact.name = 'Christian'; </li></ul><ul><li>contact.surName = 'Hei...
<ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood =...
<ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood =...
<ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood =...
<ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood =...
<ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood =...
<ul><li>if(obj.getClass()===' full '){ </li></ul><ul><li>var x = screen.left; </li></ul><ul><li>} else { </li></ul><ul><li...
<ul><li>if(obj.getClass()===' full '){ </li></ul><ul><li>var x = screen.left; </li></ul><ul><li>} else { </li></ul><ul><li...
<ul><li>var cat; </li></ul><ul><li>if(canHasCheeseburger){ </li></ul><ul><li>cat = canHasCheeseburger; </li></ul><ul><li>}...
<ul><li>var cat; </li></ul><ul><li>if(canHasCheeseburger){ </li></ul><ul><li>cat = canHasCheeseburger; </li></ul><ul><li>}...
<ul><li>var cat; </li></ul><ul><li>if(canHasCheeseburger){ </li></ul><ul><li>cat = canHasCheeseburger; </li></ul><ul><li>}...
<ul><li>var massive.name.with.long.namespace = { </li></ul><ul><li>...private stuff... </li></ul><ul><li>return{ </li></ul...
<ul><li>var massive.name.with.long.namespace = { </li></ul><ul><li>var pub = {}; </li></ul><ul><li>...private stuff... </l...
<ul><li>var massive.name.with.long.namespace = { </li></ul><ul><li>function init(){ </li></ul><ul><li>show(); </li></ul><u...
<ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentati...
<ul><ul><li>Production code is not live code.  </li></ul></ul><ul><ul><li>That doesn’t happen on the back-end and it shoul...
<ul><li>Build process: </li></ul><ul><ul><li>Validation (Tidy, JSLint) </li></ul></ul><ul><ul><li>Minification (JSMin, CSS...
<ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentati...
<ul><li>Following a code standard means you can: </li></ul><ul><ul><li>Assess quality of code  </li></ul></ul><ul><ul><li>...
<ul><li>What code standard? </li></ul>
<ul><li>Whatever the team agrees on and feels comfortable with. </li></ul>
<ul><li>Document it and other teams can validate what you have done. </li></ul>
<ul><li>In the perfect world, we’ll all follow the same code standard. </li></ul>
<ul><li>Let’s meet again in a year! :-) </li></ul>
<ul><li>Comments are good, but they are not documentation. </li></ul>
<ul><li>Write documentation in peer review - as the developer you are too close to the subject. </li></ul>
<ul><li>Plan and ask for time to document what you have done. </li></ul>
<ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentati...
<ul><li>Conduct Code reviews </li></ul><ul><ul><li>You find problems and solutions you can share in the team. </li></ul></...
<ul><ul><li>If you keep finding the same problem and different solutions for it, find a generic solution and re-use that o...
<ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentati...
<ul><li>Whenever you write some code, don’t think that your implementation will be the end of it.  </li></ul>
<ul><li>Make sure that your code can be extended by other people and try to build it as modular as possible. </li></ul>
<ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentati...
<ul><li>Not everybody maintaining your code will be as good as you are. </li></ul>
<ul><li>Trying to find where to change what in a piece of code is terribly frustrating.  </li></ul>
<ul><li>Separate out as much of the look and feel as you can. </li></ul>
<ul><li>Also separate out labels that are likely to change and the names of CSS classes and IDs in use.  </li></ul>
<ul><li>So how do you plan JavaScript and Ajax for larger teams? </li></ul>
<ul><li>Get the team to talk and agree on what works best. </li></ul>
<ul><li>Involve Design and Engineering in the process and explain the rationale of your plan. </li></ul>
<ul><li>Communication and sharing information is better than any architectural blueprint you or I could come up with. </li...
<ul><li>THANKS! </li></ul><ul><li>Christian  </li></ul><ul><li>Heilmann </li></ul><ul><li>http://wait-till-i.com </li></ul...
Upcoming SlideShare
Loading in...5
×

Planning JavaScript for Larger Teams - Draft & Handout version

6,325

Published on

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

Published in: Technology, Business
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,325
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
98
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "Planning JavaScript for Larger Teams - Draft & Handout version"

  1. 1. Planning JavaScript and Ajax for larger teams Christian Heilmann @media Ajax, London, November 2007
  2. 2. Achtung alles Lookenpeepers! <ul><li>Dies Machine is nicht fur gefingerpoken und mittengraben. </li></ul><ul><li>Is easy schnappen der springenwerk, blowenfusen und poppencorken mit spitzensparken. </li></ul><ul><li>Is nicht fur gewerken by das dummkopfen. </li></ul><ul><li>Das rubbernecken sightseeren keepen Cottenpickenen hands in das pockets - relaxen und Watch Das Blinken Lights.  </li></ul>
  3. 3. <ul><li>Do not fiddle with other people’s knobs unless you know what you are doing. </li></ul>
  4. 4. <ul><li>Spoilers: </li></ul><ul><ul><li>Some of the following advice will seem very basic to you. </li></ul></ul><ul><ul><li>This is not based on me thinking you need this. </li></ul></ul><ul><ul><li>It is meant as a reminder. Next time you encounter these problems you won’t have to think about them. </li></ul></ul><ul><li>… and Harry Potter dies, but comes back using a magic stone which is a third of the Deathly Hallows. </li></ul>
  5. 5. <ul><li>There is one main fatal mistake any developer can make: </li></ul>
  6. 6. <ul><li>There is one main fatal mistake any developer can make: </li></ul><ul><li>Make assumptions </li></ul>
  7. 7. <ul><li>“ I don’t need to tell people that, they know already.” </li></ul>
  8. 8. <ul><li>“ Surely this has been done already, and by people better than me.” </li></ul>
  9. 9. <ul><li>“ This works right now, there won’t be a need to change it.” </li></ul>
  10. 10. <ul><li>“ This never worked in the past, it won’t work now.” </li></ul>
  11. 11. <ul><li>“ We hack that now, and will get time later to fix it.” </li></ul>
  12. 12. <ul><li>“ This is a minor issue only for this instance, no need to file a bug.” </li></ul>
  13. 13. <ul><li>All these mistakes are yours to make. </li></ul>
  14. 14. <ul><li>Sometimes they need to be made in order to prove a new point or prove an issue and its solution. </li></ul>
  15. 15. <ul><li>However, avoiding them means you help all of us working together. </li></ul>
  16. 16. <ul><li>No more heroes! </li></ul>
  17. 17. <ul><li>A good developer is not a very gifted and impressive developer. </li></ul>
  18. 18. <ul><li>It is a developer that can work with others and works for the next developer to take over. </li></ul>
  19. 19. <ul><li>People will move from product to product or leave the company. </li></ul>
  20. 20. <ul><li>Web products are never finished. </li></ul>
  21. 21. <ul><li>Don’t leave a mess behind; work as if you won’t see the code ever again. </li></ul>
  22. 22. <ul><li>Mistakes we make: </li></ul>
  23. 23. <ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting the markup. </li></ul><ul><li>Not planning for inclusion. </li></ul><ul><li>Not planning for failure. </li></ul><ul><li>Premature optimization. </li></ul>
  24. 24. <ul><li>This should be a no-brainer by now but we still do it. </li></ul>
  25. 25. <ul><li>Separation means: </li></ul><ul><ul><li>Working in parallel (to an extend) </li></ul></ul><ul><ul><li>Re-skinning an application by changing the style sheet </li></ul></ul><ul><ul><li>Caching, Minimizing, Optimizing for speed and delivery. </li></ul></ul>
  26. 26. <ul><li>Not separating means: </li></ul><ul><ul><li>Harder maintenance </li></ul></ul><ul><ul><li>Larger and slower sites </li></ul></ul><ul><ul><li>Several sources for bugs without an easy way to track them. </li></ul></ul>
  27. 27. <ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting the markup. </li></ul><ul><li>Not planning for inclusion. </li></ul><ul><li>Not planning for failure. </li></ul><ul><li>Premature optimization. </li></ul>
  28. 28. <ul><li>The last thing to trust is the browser. </li></ul>
  29. 29. <ul><li>They all have shifty eyes and will steal your loose change when you don’t look. </li></ul>
  30. 30. <ul><li>Testing for a browser name and assuming it can do certain things is a bad plan. </li></ul>
  31. 31. <ul><li>Browsers come in all kind of setups and with all kind of extensions. </li></ul>
  32. 32. <ul><li>Assume the browser will fail and keep poking it until it tells you all is OK. </li></ul>
  33. 33. <ul><li>Making assumptions: </li></ul><ul><li>function showMessage(elm, message){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} </li></ul>
  34. 34. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  35. 35. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  36. 36. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  37. 37. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  38. 38. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  39. 39. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  40. 40. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  41. 41. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  42. 42. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  43. 43. <ul><li>function showMessage(id,message){ </li></ul><ul><li>if(document.getElementById){ </li></ul><ul><li>var elm = document.getElementById(id); </li></ul><ul><li>if(elm){ </li></ul><ul><li>if(elm.firstChild){ </li></ul><ul><li>if(elm.firstChild.nodeType === 3){ </li></ul><ul><li>elm.firstChild.nodeValue = message; </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.insertBefore(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} else { </li></ul><ul><li>var t = document.createTextNode(message); </li></ul><ul><li>elm.appendChild(t,elm.firstChild); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  44. 44. <ul><li>Bit overkill, isn’t it? </li></ul>
  45. 45. <ul><ul><li>Add tests for the browser early (init method) </li></ul></ul><ul><ul><li>Use library functions that do the testing for you. </li></ul></ul>
  46. 46. <ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting the markup. </li></ul><ul><li>Not planning for inclusion. </li></ul><ul><li>Not planning for failure. </li></ul><ul><li>Premature optimization. </li></ul>
  47. 47. <ul><li>HTML markup of the document is never set in stone. </li></ul>
  48. 48. <ul><li>Don’t rely on it. </li></ul>
  49. 49. <ul><li>document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline'; </li></ul>
  50. 50. <ul><li>document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline'; </li></ul>
  51. 51. <ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting the markup. </li></ul><ul><li>Not planning for inclusion. </li></ul><ul><li>Not planning for failure. </li></ul><ul><li>Premature optimization. </li></ul>
  52. 52. <ul><li>Assuming your script is the only one included in the document: </li></ul>
  53. 53. <ul><li>Assuming your script is the only one included in the document: </li></ul><ul><li>hasfail = true; </li></ul>
  54. 54. <ul><li>Namespace your scripts, follow a naming convention and don’t leave any global variables or methods. </li></ul>
  55. 55. <ul><li>That way your script will run even if it has to work alongside bad code. </li></ul>
  56. 56. <ul><li>Bad code will be added to your documents, most of the time in the form of advertisements or tracking code. </li></ul>
  57. 57. <ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting the markup. </li></ul><ul><li>Not planning for inclusion. </li></ul><ul><li>Not planning for failure. </li></ul><ul><li>Premature optimization. </li></ul>
  58. 58. <ul><li>Things will fail, plan for it! </li></ul><ul><ul><li>JavaScript will not be available. </li></ul></ul><ul><ul><li>Ajax connections will take too long or return wrong data. </li></ul></ul><ul><ul><li>Plan for a fallback option (redirect to a static page, show an error message) </li></ul></ul>
  59. 59. <ul><li><a href=&quot;javascript:ajaxmagic('panda')&quot;> </li></ul><ul><li>Show results for 'panda' </li></ul><ul><li></a> </li></ul>
  60. 60. <ul><li><a href=&quot;javascript:ajaxmagic('panda')&quot;> </li></ul><ul><li>Show results for 'panda' </li></ul><ul><li></a> </li></ul>
  61. 61. <ul><li><a href=&quot;search.php?term=panda&quot; id=&quot;searchlink&quot;> </li></ul><ul><li>Show results for 'panda‘ </li></ul><ul><li></a> </li></ul><ul><li>var YE = YAHOO.util.Event; </li></ul><ul><li>YE.on('searchlink','click',ajaxmagic); </li></ul><ul><li>function ajaxmagic(e){ </li></ul><ul><li>var t = YE.getTarget(e); </li></ul><ul><li>var url = t.href.split('=')[1]; </li></ul><ul><li>ajaxcode(url); </li></ul><ul><li>YE.preventDefault(e); </li></ul><ul><li>} </li></ul>
  62. 62. <ul><li>Re-use the backend script </li></ul><ul><li>function ajaxmagic(e){ </li></ul><ul><li>var t = YE.getTarget(e); </li></ul><ul><li>var url = t.href + &output=json'; </li></ul><ul><li>ajaxcode(url); </li></ul><ul><li>YE.preventDefault(e); </li></ul><ul><li>} </li></ul>
  63. 63. <ul><li>Mixing structure, presentation and behaviour. </li></ul><ul><li>Trusting the browser. </li></ul><ul><li>Trusting the markup. </li></ul><ul><li>Not planning for inclusion. </li></ul><ul><li>Not planning for failure. </li></ul><ul><li>Premature optimization . </li></ul>
  64. 64. <ul><li>Each of us has a little hacker inside who wants to get out. </li></ul>
  65. 65. <ul><li>This little hacker wants to make things as fast, small and cool as possible. </li></ul>
  66. 66. <ul><li>This little hacker is also very competitive and doesn’t trust reused code or libraries. </li></ul>
  67. 68. <ul><li>Our job is not to give in to it when we produce production code. </li></ul>
  68. 69. <ul><li>Production code does not need to be optimized from the start. </li></ul>
  69. 70. <ul><li>It needs to be understandable and maintainable. </li></ul>
  70. 71. <ul><ul><li>use library code, even if it appears huge (a lot of the size is a myth) </li></ul></ul><ul><ul><li>Use comments to explain what is going on </li></ul></ul><ul><ul><li>Use explanatory variable and method names </li></ul></ul><ul><ul><li>Don’t reinvent the wheel even if you consider yours superior. </li></ul></ul>
  71. 72. Enough bad. Give us some tips!
  72. 73. <ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentation process. </li></ul><ul><li>Review and reuse code. </li></ul><ul><li>Plan for extension. </li></ul><ul><li>Think maintenance </li></ul>
  73. 74. <ul><li>Try to avoid traps that make your code hungry: </li></ul><ul><ul><li>Cut down on DOM interaction </li></ul></ul><ul><ul><li>Minimize the amount of loops </li></ul></ul><ul><ul><li>Build tool methods to deal with reoccurring problems </li></ul></ul>
  74. 75. <ul><ul><li>Use shortcut notations in JavaScript. </li></ul></ul>
  75. 76. <ul><li>var links = new Array(); </li></ul><ul><li>links[0]='http://icant.co.uk'; </li></ul><ul><li>links[1]='http://wait-till-i.com'; </li></ul><ul><li>links[2]='http://onlinetools.org'; </li></ul>
  76. 77. <ul><li>var links = new Array(); </li></ul><ul><li>links[0]='http://icant.co.uk'; </li></ul><ul><li>links[1]='http://wait-till-i.com'; </li></ul><ul><li>links[2]='http://onlinetools.org'; </li></ul><ul><li>var links = [ </li></ul><ul><li>'http://icant.co.uk', 'http://wait-till-i.com', 'http://onlinetools.org‘ </li></ul><ul><li>]; </li></ul>
  77. 78. <ul><li>var contact = new Object(); </li></ul><ul><li>contact.name = 'Christian'; </li></ul><ul><li>contact.surName = 'Heilmann'; </li></ul><ul><li>contact.age = 32; </li></ul><ul><li>contact.hair = 'slightly red'; </li></ul>
  78. 79. <ul><li>var contact = new Object(); </li></ul><ul><li>contact.name = 'Christian'; </li></ul><ul><li>contact.surName = 'Heilmann'; </li></ul><ul><li>contact.age = 32; </li></ul><ul><li>contact.hair = 'slightly red'; </li></ul><ul><li>var contact = { </li></ul><ul><li>name:'Christian', </li></ul><ul><li>surName:'Heilmann', </li></ul><ul><li>age:32, </li></ul><ul><li>hair:'slightly red' </li></ul><ul><li>}; </li></ul>
  79. 80. <ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood = 'sad'; </li></ul><ul><li>} </li></ul>
  80. 81. <ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood = 'sad'; </li></ul><ul><li>} </li></ul><ul><li>cat.mood = hasCheeseburger?'happy':'sad'; </li></ul>
  81. 82. <ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood = 'sad'; </li></ul><ul><li>} </li></ul><ul><li>cat.mood = hasCheeseburger?'happy':'sad'; </li></ul>condition
  82. 83. <ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood = 'sad'; </li></ul><ul><li>} </li></ul><ul><li>cat.mood = hasCheeseburger?'happy':'sad'; </li></ul>true case
  83. 84. <ul><li>if(hasCheeseburger){ </li></ul><ul><li>cat.mood = 'happy'; </li></ul><ul><li>} else { </li></ul><ul><li>cat.mood = 'sad'; </li></ul><ul><li>} </li></ul><ul><li>cat.mood = hasCheeseburger?'happy':'sad'; </li></ul>false case
  84. 85. <ul><li>if(obj.getClass()===' full '){ </li></ul><ul><li>var x = screen.left; </li></ul><ul><li>} else { </li></ul><ul><li>var x = current; </li></ul><ul><li>} </li></ul>
  85. 86. <ul><li>if(obj.getClass()===' full '){ </li></ul><ul><li>var x = screen.left; </li></ul><ul><li>} else { </li></ul><ul><li>var x = current; </li></ul><ul><li>} </li></ul><ul><li>var x = (obj.hasClass()=== ' full ') ? screen.left : current; </li></ul>
  86. 87. <ul><li>var cat; </li></ul><ul><li>if(canHasCheeseburger){ </li></ul><ul><li>cat = canHasCheeseburger; </li></ul><ul><li>}; </li></ul><ul><li>if(garfield){ </li></ul><ul><li>cat = garfield; </li></ul><ul><li>}; </li></ul>
  87. 88. <ul><li>var cat; </li></ul><ul><li>if(canHasCheeseburger){ </li></ul><ul><li>cat = canHasCheeseburger; </li></ul><ul><li>}; </li></ul><ul><li>if(garfield){ </li></ul><ul><li>cat = garfield; </li></ul><ul><li>}; </li></ul><ul><li>var cat = canHasCheeseburger || garfield; </li></ul>
  88. 89. <ul><li>var cat; </li></ul><ul><li>if(canHasCheeseburger){ </li></ul><ul><li>cat = canHasCheeseburger; </li></ul><ul><li>}; </li></ul><ul><li>if(garfield){ </li></ul><ul><li>cat = garfield; </li></ul><ul><li>}; </li></ul><ul><li>var cat = canHasCheeseburger || garfield; </li></ul>one or the other, defining a fallback
  89. 90. <ul><li>var massive.name.with.long.namespace = { </li></ul><ul><li>...private stuff... </li></ul><ul><li>return{ </li></ul><ul><li>init:function(){ </li></ul><ul><li>massive.name.with.long.namespace.show(); </li></ul><ul><li>}, </li></ul><ul><li>show:function(){ </li></ul><ul><li>massive.name.with.long.namespace.test(); </li></ul><ul><li>}, </li></ul><ul><li>test:function(){ </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>}(); </li></ul>
  90. 91. <ul><li>var massive.name.with.long.namespace = { </li></ul><ul><li>var pub = {}; </li></ul><ul><li>...private stuff... </li></ul><ul><li>pub. init = function(){ </li></ul><ul><li>pub. show(); </li></ul><ul><li>}; </li></ul><ul><li>pub. show = function(){ </li></ul><ul><li>pub. test(); </li></ul><ul><li>}; </li></ul><ul><li>pub. test = function(){ </li></ul><ul><li>}; </li></ul><ul><li>return pub; </li></ul><ul><li>}(); </li></ul><ul><li>massive.name.with.long.namespace.init(); </li></ul>
  91. 92. <ul><li>var massive.name.with.long.namespace = { </li></ul><ul><li>function init(){ </li></ul><ul><li>show(); </li></ul><ul><li>}; </li></ul><ul><li>function show(){ </li></ul><ul><li>test(); </li></ul><ul><li>}; </li></ul><ul><li>function test(){ </li></ul><ul><li>}; </li></ul><ul><li>return { </li></ul><ul><li>init:init; </li></ul><ul><li>show:show; </li></ul><ul><li>test:test; </li></ul><ul><li>}; </li></ul><ul><li>}(); </li></ul><ul><li>massive.name.with.long.namespace.init(); </li></ul>
  92. 93. <ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentation process. </li></ul><ul><li>Review and reuse code. </li></ul><ul><li>Plan for extension. </li></ul><ul><li>Think maintenance </li></ul>
  93. 94. <ul><ul><li>Production code is not live code. </li></ul></ul><ul><ul><li>That doesn’t happen on the back-end and it shouldn’t happen on the front-end. </li></ul></ul><ul><ul><li>Live code is there for machines, production code is there for humans. </li></ul></ul>
  94. 95. <ul><li>Build process: </li></ul><ul><ul><li>Validation (Tidy, JSLint) </li></ul></ul><ul><ul><li>Minification (JSMin, CSS minifier) </li></ul></ul><ul><ul><li>Consolidation (one CSS and one JS instead of dozens) </li></ul></ul><ul><ul><li>Tagging as “live code” – do not edit! </li></ul></ul>
  95. 96. <ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentation process. </li></ul><ul><li>Review and reuse code. </li></ul><ul><li>Plan for extension. </li></ul><ul><li>Think maintenance </li></ul>
  96. 97. <ul><li>Following a code standard means you can: </li></ul><ul><ul><li>Assess quality of code </li></ul></ul><ul><ul><li>Find bugs easily and create reproducible bug reports </li></ul></ul><ul><ul><li>Have quick handover from developer to developer </li></ul></ul><ul><ul><li>Have reliable version control </li></ul></ul>
  97. 98. <ul><li>What code standard? </li></ul>
  98. 99. <ul><li>Whatever the team agrees on and feels comfortable with. </li></ul>
  99. 100. <ul><li>Document it and other teams can validate what you have done. </li></ul>
  100. 101. <ul><li>In the perfect world, we’ll all follow the same code standard. </li></ul>
  101. 102. <ul><li>Let’s meet again in a year! :-) </li></ul>
  102. 103. <ul><li>Comments are good, but they are not documentation. </li></ul>
  103. 104. <ul><li>Write documentation in peer review - as the developer you are too close to the subject. </li></ul>
  104. 105. <ul><li>Plan and ask for time to document what you have done. </li></ul>
  105. 106. <ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentation process. </li></ul><ul><li>Review and reuse code. </li></ul><ul><li>Plan for extension. </li></ul><ul><li>Think maintenance </li></ul>
  106. 107. <ul><li>Conduct Code reviews </li></ul><ul><ul><li>You find problems and solutions you can share in the team. </li></ul></ul><ul><ul><li>You find out who knows what well and who needs training in what </li></ul></ul><ul><ul><li>You share the knowledge throughout the team = no Divas. </li></ul></ul>
  107. 108. <ul><ul><li>If you keep finding the same problem and different solutions for it, find a generic solution and re-use that one. </li></ul></ul><ul><ul><li>Look at what other people have done (libraries). </li></ul></ul><ul><ul><li>Bounce your solutions off other development teams. </li></ul></ul>
  108. 109. <ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentation process. </li></ul><ul><li>Review and reuse your code. </li></ul><ul><li>Plan for extension. </li></ul><ul><li>Think maintenance </li></ul>
  109. 110. <ul><li>Whenever you write some code, don’t think that your implementation will be the end of it. </li></ul>
  110. 111. <ul><li>Make sure that your code can be extended by other people and try to build it as modular as possible. </li></ul>
  111. 112. <ul><li>Follow a diet plan. </li></ul><ul><li>Have a build process. </li></ul><ul><li>Have a code standard and documentation process. </li></ul><ul><li>Review and reuse your code. </li></ul><ul><li>Plan for extension. </li></ul><ul><li>Think maintenance </li></ul>
  112. 113. <ul><li>Not everybody maintaining your code will be as good as you are. </li></ul>
  113. 114. <ul><li>Trying to find where to change what in a piece of code is terribly frustrating. </li></ul>
  114. 115. <ul><li>Separate out as much of the look and feel as you can. </li></ul>
  115. 116. <ul><li>Also separate out labels that are likely to change and the names of CSS classes and IDs in use. </li></ul>
  116. 117. <ul><li>So how do you plan JavaScript and Ajax for larger teams? </li></ul>
  117. 118. <ul><li>Get the team to talk and agree on what works best. </li></ul>
  118. 119. <ul><li>Involve Design and Engineering in the process and explain the rationale of your plan. </li></ul>
  119. 120. <ul><li>Communication and sharing information is better than any architectural blueprint you or I could come up with. </li></ul>
  120. 121. <ul><li>THANKS! </li></ul><ul><li>Christian </li></ul><ul><li>Heilmann </li></ul><ul><li>http://wait-till-i.com </li></ul><ul><li>[email_address] </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×