Planning JavaScript for Larger Teams - Draft & Handout version

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    4 Favorites & 2 Groups

    Planning JavaScript for Larger Teams - Draft & Handout version - Presentation Transcript

    1. Planning JavaScript and Ajax for larger teams Christian Heilmann @media Ajax, London, November 2007
    2. 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. 
      • Do not fiddle with other people’s knobs unless you know what you are doing.
      • 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.
      • There is one main fatal mistake any developer can make:
      • There is one main fatal mistake any developer can make:
      • Make assumptions
      • “ I don’t need to tell people that, they know already.”
      • “ Surely this has been done already, and by people better than me.”
      • “ This works right now, there won’t be a need to change it.”
      • “ This never worked in the past, it won’t work now.”
      • “ We hack that now, and will get time later to fix it.”
      • “ This is a minor issue only for this instance, no need to file a bug.”
      • All these mistakes are yours to make.
      • Sometimes they need to be made in order to prove a new point or prove an issue and its solution.
      • However, avoiding them means you help all of us working together.
      • No more heroes!
      • A good developer is not a very gifted and impressive developer.
      • It is a developer that can work with others and works for the next developer to take over.
      • People will move from product to product or leave the company.
      • Web products are never finished.
      • Don’t leave a mess behind; work as if you won’t see the code ever again.
      • Mistakes we make:
      • Mixing structure, presentation and behaviour.
      • Trusting the browser.
      • Trusting the markup.
      • Not planning for inclusion.
      • Not planning for failure.
      • Premature optimization.
      • This should be a no-brainer by now but we still do it.
      • Separation means:
        • Working in parallel (to an extend)
        • Re-skinning an application by changing the style sheet
        • Caching, Minimizing, Optimizing for speed and delivery.
      • Not separating means:
        • Harder maintenance
        • Larger and slower sites
        • Several sources for bugs without an easy way to track them.
      • Mixing structure, presentation and behaviour.
      • Trusting the browser.
      • Trusting the markup.
      • Not planning for inclusion.
      • Not planning for failure.
      • Premature optimization.
      • The last thing to trust is the browser.
      • They all have shifty eyes and will steal your loose change when you don’t look.
      • Testing for a browser name and assuming it can do certain things is a bad plan.
      • Browsers come in all kind of setups and with all kind of extensions.
      • Assume the browser will fail and keep poking it until it tells you all is OK.
      • Making assumptions:
      • function showMessage(elm, message){
      • elm.firstChild.nodeValue = message;
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • 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);
      • }
      • }
      • }
      • }
      • Bit overkill, isn’t it?
        • Add tests for the browser early (init method)
        • Use library functions that do the testing for you.
      • Mixing structure, presentation and behaviour.
      • Trusting the browser.
      • Trusting the markup.
      • Not planning for inclusion.
      • Not planning for failure.
      • Premature optimization.
      • HTML markup of the document is never set in stone.
      • Don’t rely on it.
      • document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline';
      • document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline';
      • Mixing structure, presentation and behaviour.
      • Trusting the browser.
      • Trusting the markup.
      • Not planning for inclusion.
      • Not planning for failure.
      • Premature optimization.
      • Assuming your script is the only one included in the document:
      • Assuming your script is the only one included in the document:
      • hasfail = true;
      • Namespace your scripts, follow a naming convention and don’t leave any global variables or methods.
      • That way your script will run even if it has to work alongside bad code.
      • Bad code will be added to your documents, most of the time in the form of advertisements or tracking code.
      • Mixing structure, presentation and behaviour.
      • Trusting the browser.
      • Trusting the markup.
      • Not planning for inclusion.
      • Not planning for failure.
      • Premature optimization.
      • 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)
      • <a href=&quot;javascript:ajaxmagic('panda')&quot;>
      • Show results for 'panda'
      • </a>
      • <a href=&quot;javascript:ajaxmagic('panda')&quot;>
      • Show results for 'panda'
      • </a>
      • <a href=&quot;search.php?term=panda&quot; id=&quot;searchlink&quot;>
      • 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);
      • }
      • Re-use the backend script
      • function ajaxmagic(e){
      • var t = YE.getTarget(e);
      • var url = t.href + &output=json';
      • ajaxcode(url);
      • YE.preventDefault(e);
      • }
      • Mixing structure, presentation and behaviour.
      • Trusting the browser.
      • Trusting the markup.
      • Not planning for inclusion.
      • Not planning for failure.
      • Premature optimization .
      • Each of us has a little hacker inside who wants to get out.
      • This little hacker wants to make things as fast, small and cool as possible.
      • This little hacker is also very competitive and doesn’t trust reused code or libraries.
    3.  
      • Our job is not to give in to it when we produce production code.
      • Production code does not need to be optimized from the start.
      • It needs to be understandable and maintainable.
        • 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.
    4. Enough bad. Give us some tips!
      • Follow a diet plan.
      • Have a build process.
      • Have a code standard and documentation process.
      • Review and reuse code.
      • Plan for extension.
      • Think maintenance
      • 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
        • Use shortcut notations in JavaScript.
      • var links = new Array();
      • links[0]='http://icant.co.uk';
      • links[1]='http://wait-till-i.com';
      • links[2]='http://onlinetools.org';
      • 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‘
      • ];
      • var contact = new Object();
      • contact.name = 'Christian';
      • contact.surName = 'Heilmann';
      • contact.age = 32;
      • contact.hair = 'slightly red';
      • 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'
      • };
      • if(hasCheeseburger){
      • cat.mood = 'happy';
      • } else {
      • cat.mood = 'sad';
      • }
      • if(hasCheeseburger){
      • cat.mood = 'happy';
      • } else {
      • cat.mood = 'sad';
      • }
      • cat.mood = hasCheeseburger?'happy':'sad';
      • if(hasCheeseburger){
      • cat.mood = 'happy';
      • } else {
      • cat.mood = 'sad';
      • }
      • cat.mood = hasCheeseburger?'happy':'sad';
      condition
      • if(hasCheeseburger){
      • cat.mood = 'happy';
      • } else {
      • cat.mood = 'sad';
      • }
      • cat.mood = hasCheeseburger?'happy':'sad';
      true case
      • if(hasCheeseburger){
      • cat.mood = 'happy';
      • } else {
      • cat.mood = 'sad';
      • }
      • cat.mood = hasCheeseburger?'happy':'sad';
      false case
      • if(obj.getClass()===' full '){
      • var x = screen.left;
      • } else {
      • var x = current;
      • }
      • if(obj.getClass()===' full '){
      • var x = screen.left;
      • } else {
      • var x = current;
      • }
      • var x = (obj.hasClass()=== ' full ') ? screen.left : current;
      • var cat;
      • if(canHasCheeseburger){
      • cat = canHasCheeseburger;
      • };
      • if(garfield){
      • cat = garfield;
      • };
      • var cat;
      • if(canHasCheeseburger){
      • cat = canHasCheeseburger;
      • };
      • if(garfield){
      • cat = garfield;
      • };
      • var cat = canHasCheeseburger || garfield;
      • var cat;
      • if(canHasCheeseburger){
      • cat = canHasCheeseburger;
      • };
      • if(garfield){
      • cat = garfield;
      • };
      • var cat = canHasCheeseburger || garfield;
      one or the other, defining a fallback
      • 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(){
      • }
      • }
      • }();
      • 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();
      • 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();
      • Follow a diet plan.
      • Have a build process.
      • Have a code standard and documentation process.
      • Review and reuse code.
      • Plan for extension.
      • Think maintenance
        • 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.
      • 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!
      • Follow a diet plan.
      • Have a build process.
      • Have a code standard and documentation process.
      • Review and reuse code.
      • Plan for extension.
      • Think maintenance
      • 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
      • What code standard?
      • Whatever the team agrees on and feels comfortable with.
      • Document it and other teams can validate what you have done.
      • In the perfect world, we’ll all follow the same code standard.
      • Let’s meet again in a year! :-)
      • Comments are good, but they are not documentation.
      • Write documentation in peer review - as the developer you are too close to the subject.
      • Plan and ask for time to document what you have done.
      • Follow a diet plan.
      • Have a build process.
      • Have a code standard and documentation process.
      • Review and reuse code.
      • Plan for extension.
      • Think maintenance
      • 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.
        • 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.
      • Follow a diet plan.
      • Have a build process.
      • Have a code standard and documentation process.
      • Review and reuse your code.
      • Plan for extension.
      • Think maintenance
      • Whenever you write some code, don’t think that your implementation will be the end of it.
      • Make sure that your code can be extended by other people and try to build it as modular as possible.
      • Follow a diet plan.
      • Have a build process.
      • Have a code standard and documentation process.
      • Review and reuse your code.
      • Plan for extension.
      • Think maintenance
      • Not everybody maintaining your code will be as good as you are.
      • Trying to find where to change what in a piece of code is terribly frustrating.
      • Separate out as much of the look and feel as you can.
      • Also separate out labels that are likely to change and the names of CSS classes and IDs in use.
      • So how do you plan JavaScript and Ajax for larger teams?
      • Get the team to talk and agree on what works best.
      • Involve Design and Engineering in the process and explain the rationale of your plan.
      • Communication and sharing information is better than any architectural blueprint you or I could come up with.
      • THANKS!
      • Christian
      • Heilmann
      • http://wait-till-i.com
      • [email_address]

    Christian HeilmannChristian Heilmann, 2 years ago

    custom

    4687 views, 4 favs, 9 embeds more stats

    This is the original draft of my talk at @mediaAjax more

    More Info

    CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

    Go to text version
    • Total Views 4687
      • 4200 on SlideShare
      • 487 from embeds
    • Comments 0
    • Favorites 4
    • Downloads 72
    Most viewed embeds
    • 432 views on http://www.wait-till-i.com
    • 40 views on http://icant.co.uk
    • 3 views on http://www.netvibes.com
    • 3 views on http://www.yuiworld.pe.kr
    • 3 views on http://static.slideshare.net

    more

    All embeds
    • 432 views on http://www.wait-till-i.com
    • 40 views on http://icant.co.uk
    • 3 views on http://www.netvibes.com
    • 3 views on http://www.yuiworld.pe.kr
    • 3 views on http://static.slideshare.net
    • 3 views on http://www.yuiworld.kr
    • 1 views on http://127.0.0.1:8795
    • 1 views on http://www.partecipa.org
    • 1 views on http://192.168.10.100

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as innappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel

    Categories