Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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

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

  • Login to see the comments

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>

×