Maintainable Javascript carsonified

150
Maintainable JavaScript Chris&an Heilmann Carsonfied online conference, September 2010

Transcript of Maintainable Javascript carsonified

Page 1: Maintainable Javascript carsonified

Maintainable JavaScript

Chris&an HeilmannCarsonfied online conference, September 2010

Page 2: Maintainable Javascript carsonified

JavaScript is awesome!

Page 3: Maintainable Javascript carsonified

Nowadays writing JavaScript is wonderfully easy.

Page 4: Maintainable Javascript carsonified

Libraries patch the support holes in browsers.

Page 5: Maintainable Javascript carsonified

Pure JavaScript environments allow us to really play with the language.

Page 6: Maintainable Javascript carsonified

JavaScript is dead easy to learn and the first steps are already very rewarding.

Page 7: Maintainable Javascript carsonified

This is also the problem of JavaScript.

Page 8: Maintainable Javascript carsonified

The web is not a closed environment where we can dictate the technologies people use.

Page 9: Maintainable Javascript carsonified

Some of the things I will talk about today will seem outdated or overly cautious.

Page 10: Maintainable Javascript carsonified

The reason is that I want to build a web that works.

Page 11: Maintainable Javascript carsonified

For far too long we have built a mess that barely functions and is hard to change.

Page 12: Maintainable Javascript carsonified

So here are a few ideas and concepts you should follow if you write JavaScript.

Page 13: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 14: Maintainable Javascript carsonified

Libraries fix browsers and make the complex simple.

Page 15: Maintainable Javascript carsonified

They make web development predictable.

Page 16: Maintainable Javascript carsonified

Building without libraries means constant catch-up with the browser market.

Page 17: Maintainable Javascript carsonified

Do not mix and match libraries though.

Page 18: Maintainable Javascript carsonified

Stick with one and use it to its strengths.

Page 19: Maintainable Javascript carsonified

If the library totally re-invents JS as we know it, this is fine.

Page 20: Maintainable Javascript carsonified

But: writing in an abstraction syntax is not writing JavaScript.

Page 21: Maintainable Javascript carsonified

Quick two-liners do not replace architecting and planning.

Page 22: Maintainable Javascript carsonified

Professional libraries come as a pick and mix solution.

Page 23: Maintainable Javascript carsonified

Include what you need and when you need it - not the kitchen sink approach.

Page 24: Maintainable Javascript carsonified

One big danger of libraries is to tie the markup and your scripts far too close to each other.

Page 25: Maintainable Javascript carsonified

Small looking loops can actually be very slow.

Page 26: Maintainable Javascript carsonified

Long CSS selectors are dangerous.

Page 27: Maintainable Javascript carsonified

Pick your plugins by how well they are documented, how well supported and how easy they are to extend.

Page 28: Maintainable Javascript carsonified

Not by how flashy they are.

Page 29: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 30: Maintainable Javascript carsonified

This is old news.

Page 31: Maintainable Javascript carsonified

Take each technology on the web and use it for what it was meant to.

Page 32: Maintainable Javascript carsonified

HTML that works without JavaScript should not be aded using JavaScript.

Page 33: Maintainable Javascript carsonified

HTML that only makes sense when JavaScript is available should be added with JavaScript.

Page 34: Maintainable Javascript carsonified

Instructions that describe functionality that is dependent on JS should also be added by it.

Page 35: Maintainable Javascript carsonified

Text, classes and ID names are very much prone to change.

Page 36: Maintainable Javascript carsonified

So don’t spread them all over your scripts but keep them in one place for maintenance.

Page 37: Maintainable Javascript carsonified

Public configuration objects are a great idea.

Page 38: Maintainable Javascript carsonified

Most underused element:

<button>

Page 39: Maintainable Javascript carsonified

Buttons by definition are there to trigger script functionality - so use them instead of links.

Page 40: Maintainable Javascript carsonified

Links should point to a real resource - a url, a server endpoint or an anchor.

Page 41: Maintainable Javascript carsonified

Empty links, void(0) # and other hacks don’t make any sense.

Page 42: Maintainable Javascript carsonified

Styling should be done in CSS, not in your JavaScript.

Page 43: Maintainable Javascript carsonified

Calculated positions are of course the exception to that rule.

Page 44: Maintainable Javascript carsonified

Adding and removing classes makes sure designers have a handle and you don’t have to worry.

Page 45: Maintainable Javascript carsonified

By adding a class to a parent element you can swiftly hide a lot of elements you’d otherwise have to loop over.

Page 46: Maintainable Javascript carsonified

Adding a “js” class to the body means CSS designers can define two views easily.

Page 47: Maintainable Javascript carsonified

Make maintainers not have to know JS or change yours!

Page 48: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 49: Maintainable Javascript carsonified

Using libraries means using a lot of anonymous functions.

Page 50: Maintainable Javascript carsonified

Most of the time at the end of a massive chain of methods or for every click().

Page 51: Maintainable Javascript carsonified

Naming and calling these methods makes more sense as you create a single space to maintain.

Page 52: Maintainable Javascript carsonified

Never think your script is done and you thought of all use cases.

Page 53: Maintainable Javascript carsonified

This is why we have dozens of lightbox plugins in jQuery all doing almost the same thing.

Page 54: Maintainable Javascript carsonified

Instead of building a “one size fits all” solution, split it up into small solutions that do one thing and allow for mixing and matching.

Page 55: Maintainable Javascript carsonified

Think about firing off custom events at interesting moments.

Page 56: Maintainable Javascript carsonified

This allows people who want to extend your solution to do so without having to touch the main code.

Page 57: Maintainable Javascript carsonified

Don’t limit anything to a fixed size or amount. Instead make it a variable in the configuration object.

Page 58: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 59: Maintainable Javascript carsonified

Documentation is what we rely on when we get lost.

Page 60: Maintainable Javascript carsonified

People think documentation replaces good code examples.

Page 61: Maintainable Javascript carsonified

The issue is that as developers, we almost never start with the documentation.

Page 62: Maintainable Javascript carsonified

Instead we dive into the code and mess about with it.

Page 63: Maintainable Javascript carsonified

We read the documentation when we get stuck.

Page 64: Maintainable Javascript carsonified

Which is why code comments and descriptive variable and function names make your code easy to maintain.

Page 65: Maintainable Javascript carsonified

Comment the special case, not the obvious.

Page 66: Maintainable Javascript carsonified

Keep function and variable names short and to the point.

Page 67: Maintainable Javascript carsonified

Your documentation should explain applying and extending the code, not the code itself.

Page 68: Maintainable Javascript carsonified

Don’t worry about the size of comments - a good process deals with that.

Page 69: Maintainable Javascript carsonified

GitHub and Google Code is the new View-Source, so add value, not only solutions.

Page 70: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 71: Maintainable Javascript carsonified

You can find a lot of great performance tricks on the web when it comes to JS.

Page 72: Maintainable Javascript carsonified

Read those with the use case in mind.

Page 73: Maintainable Javascript carsonified

Tricks necessary to make Google Mail on mobiles run smooth are edge cases.

Page 74: Maintainable Javascript carsonified

Performance is a specialist topic and can be handled a lot in build processes.

Page 75: Maintainable Javascript carsonified

If a performance change means re-educating a whole team of developers it is probably not worth it.

Page 76: Maintainable Javascript carsonified

Scripts can convert and change code written in a predictable fashion.

Page 77: Maintainable Javascript carsonified

Hacks and shortcuts need to be fixed by humans.

Page 78: Maintainable Javascript carsonified

The performance of JS itself is not really the issue you should be concentrating on.

Page 79: Maintainable Javascript carsonified

Slowness of the DOM and reflow of the interface is where users get hurt.

Page 80: Maintainable Javascript carsonified

So use DOM access sparingly.

Page 81: Maintainable Javascript carsonified

Assemble HTML as as string and use innerHTML once instead of adding to it.

Page 82: Maintainable Javascript carsonified

Use Event Delegation instead of hundreds of event handlers.

Page 83: Maintainable Javascript carsonified

Store information in JS objects instead of HTML attributes.

Page 84: Maintainable Javascript carsonified

Make your code easy to understand and clean and add a performance review and refactoring step at the end.

Page 85: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 86: Maintainable Javascript carsonified

Double maintenance of code is a bad idea.

Page 87: Maintainable Javascript carsonified

Validation rules might get out of sync.

Page 88: Maintainable Javascript carsonified

This is always the killer argument of enemies of progressive enhancement.

Page 89: Maintainable Javascript carsonified

I spend a lot of time doing form validation in JavaScript - why should I repeat the same on the server side?

Page 90: Maintainable Javascript carsonified

Because there is no security in JavaScript!

Page 91: Maintainable Javascript carsonified

If all you do is validate in JS, attackers will have a field day with your server.

Page 92: Maintainable Javascript carsonified

Besides, there is no need to repeat validation rules.

Page 93: Maintainable Javascript carsonified
Page 94: Maintainable Javascript carsonified
Page 95: Maintainable Javascript carsonified

That way you validate on the server and you can use the same rules for your JS...

Page 96: Maintainable Javascript carsonified
Page 97: Maintainable Javascript carsonified

Form validation scripts are annoying.

Page 98: Maintainable Javascript carsonified

You need to access the right parts, read and write from the DOM, change styles and and and...

Page 99: Maintainable Javascript carsonified

You can leave it all to the server and still save your users a full page reload.

Page 100: Maintainable Javascript carsonified

Request type switching is the answer.

Page 101: Maintainable Javascript carsonified

JavaScript libraries add a special footprint to the server request when calling content via Ajax.

Page 102: Maintainable Javascript carsonified
Page 103: Maintainable Javascript carsonified

(so should your own Ajax solutions, btw)

Page 104: Maintainable Javascript carsonified

You can use this to send content to Ajax requests and other content to normal requests.

Page 105: Maintainable Javascript carsonified
Page 106: Maintainable Javascript carsonified

You can use this to render a form completely server side and just send a string back for each request.

http://github.com/codepo8/validationdemo

Page 107: Maintainable Javascript carsonified
Page 108: Maintainable Javascript carsonified

Filter inputs for nasties and include the rules.

Page 109: Maintainable Javascript carsonified

If the form has not been submitted, include the form code.

Page 110: Maintainable Javascript carsonified

Otherwise loop through the rules and check the data that was sent against them.

this is like /pattern/.test($(name).value)

Page 111: Maintainable Javascript carsonified

If there was an error - show the form again. Otherwise say thanks.

Page 112: Maintainable Javascript carsonified

The form itself is a simple HTML form doing all the dynamic rendering with PHP...

Page 113: Maintainable Javascript carsonified
Page 114: Maintainable Javascript carsonified

Check for the error array and if there is an error, show it. Otherwise show a * to indicate required field.

Page 115: Maintainable Javascript carsonified

Check if the form was sent via Ajax - if not, render the form element.

Page 116: Maintainable Javascript carsonified

If there was an error, say so. At the field show the error or the * SPAN.

Page 117: Maintainable Javascript carsonified

And all you then need to do in JavaScript is to override the form submission.

Page 118: Maintainable Javascript carsonified

And instead replace the innerHTML of the form on every submit.

Page 119: Maintainable Javascript carsonified

An example using YUI3...

Page 120: Maintainable Javascript carsonified

Load the IO and Node module.Define the configuration for the Ajax call.

On submission of the form load the validate.php file with the config and don’t send off the form.

Page 121: Maintainable Javascript carsonified

If the Ajax call was a success, replace the innerHTML of the form with the HTML returned from validate.php

Page 122: Maintainable Javascript carsonified

In addition to that, focus on the first element with an error message - this helps with assistive technology.

Page 123: Maintainable Javascript carsonified

If the Ajax call failed, send the form.

Page 124: Maintainable Javascript carsonified

Subscribe to the Ajax events.

Page 125: Maintainable Javascript carsonified

Writing lots of HTML with JavaScript is painful.

Page 126: Maintainable Javascript carsonified

So if you can avoid it, avoid it :)

Page 127: Maintainable Javascript carsonified

You can take this concept further.

Page 128: Maintainable Javascript carsonified

Make the backend render HTML to use with include() in PHP and load the same with Ajax.

Page 130: Maintainable Javascript carsonified

Using Node.js you can move that later on to a pure JavaScript solution.

Page 132: Maintainable Javascript carsonified

★ Using, not abusing libraries

★ Separation of concerns

★ Building for extensibility

★ Documenting your work

★ Planning for performance

★ Avoiding double maintenance

★ Live code vs. development code

Page 133: Maintainable Javascript carsonified

Live code is not development code.

Page 134: Maintainable Javascript carsonified

If you really get to a high traffic level with your scripts you should have a build process.

Page 135: Maintainable Javascript carsonified

A build process should do a few things for you.

Page 136: Maintainable Javascript carsonified

★ Remove comments★ Remove whitespace★ Bundle lots of files into one★ Pack the code★ Version, add the author and

date.★ Validate + Lint

Page 138: Maintainable Javascript carsonified

Some examples of great practices in the wild.

Page 139: Maintainable Javascript carsonified

Give browsers what they can do and use what they do better!

Page 140: Maintainable Javascript carsonified
Page 141: Maintainable Javascript carsonified

Easing the use of web fonts for better typography.

Page 143: Maintainable Javascript carsonified

Simply adding a link doesn’t give you feedback though...

Page 144: Maintainable Javascript carsonified

Using JS to load the fonts on the other hand does.

Page 145: Maintainable Javascript carsonified
Page 146: Maintainable Javascript carsonified

http://code.google.com/apis/webfonts/docs/webfont_loader.html

Classes added to the root element by the Google WebFont loader

.wf-inactive

.wf-active

.wf-tangerine-n4-inactive

.wf-tangerine-n7-active

.wf-droidsans-n4-inactive[...]

n4 - normal i4 - italicn7 - bold i7 - bold italic

Page 147: Maintainable Javascript carsonified

http://code.google.com/apis/webfonts/docs/webfont_loader.html

<style type="text/css"> .wf-inactive p { font-family: serif; font-size:12px; } .wf-active p { font-family: 'Tangerine', serif; font-size:20px; } .wf-inactive h1 { font-family: serif; font-size: 16px } .wf-active h1 { font-family: 'Cantarell', serif; font-size: 35px }</style>

Page 148: Maintainable Javascript carsonified

WebFontConfig = { google: { families: [ 'Tangerine', 'Cantarell' ] }, typekit: { id: 'myKitId' }, loading: function() { }, fontloading: function(family, info) {}, fontactive: function(family, info) {}, fontinactive: function(family, info) {}, active: function() {}, inactive: function() {}};

Page 149: Maintainable Javascript carsonified

And that’s that. A lot about writing maintainable JavaScript is to avoid writing it yourself :)

Page 150: Maintainable Javascript carsonified

Christian Heilmann http://wait-till-i.com http://developer-evangelism.com http://twitter.com/codepo8

Thanks!