-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathjavascript.html
More file actions
418 lines (399 loc) · 20 KB
/
Copy pathjavascript.html
File metadata and controls
418 lines (399 loc) · 20 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
<!DOCTYPE html>
<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js non-ie"> <!--<![endif]-->
<head>
<link href="css/main.css" media="screen" rel="stylesheet" />
<meta charset="utf-8" />
<meta content="" name="keywords"/>
<meta content="" name="description"/>
<title>Interactive Development Best Practices</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<script src="js/modernizr.js"></script>
<script src="js/curl.js"></script>
<script>
define.amd.jQuery = true;
curl(
{
baseUrl: "js",
paths: {
"jquery" : "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min"
}
},
[
"jquery",
"jquery.easing.1.3",
"domReady!",
"rainbow",
"main"
]
);
</script>
</head>
<body>
<div class="main-container">
<header>
<hgroup>
<h1>Interactive Development Best Practices</h1>
<h2><time datetime="20012-04-29">April 29, 2012</time></h2>
</hgroup>
<p>
Documenting best practices for interactive development is an exhaustive task, and is one that, if done effectively, would fill the pages of
several books. The purpose of this guide is not to provide an all-encompassing list of best practices, but to highlight many of the most
important components of a stable, high performance web page.
</p>
</header>
<nav>
<h1>Navigate This Document</h1>
<ul>
<li>
<a class="top-level" href="index.html" title="HTML">HTML</a>
<ul class="second-level">
<li><a href="#doctype" title="Doctype">Doctype</a></li>
<li>
<a href="#HTML5" title="HTML5">HTML5</a>
<ul>
<li><a href="#HTML5-shim" title="Making HTML5 Work">Making HTML5 Work</a></li>
<li><a href="#laymans-HTML5" title="The Layman's HTML5">The Layman's HTML5</a></li>
</ul>
</li>
<li><a href="#XHTML-syntax" title="XHTML Syntax">XHTML Syntax</a></li>
<li><a href="#validation" title="HTML Validation">HTML Validation</a></li>
<li><a href="#deprecated" title="Avoid Deprecated Elements">Avoid Deprecated Elements</a></li>
<li>
<a href="#semantics" title="Semantics">Semantics</a>
<ul>
<li><a href="#document-outline" title="Document Outline">Document Outline</a></li>
<li><a href="#header-tags" title="Header Tags in HTML5 and XHTML">Header Tags in HTML5 and XHTML</a></li>
<li><a href="#tables-for-data" title="Use Tables for Tabular Data">Use Tables for Tabular Data</a></li>
<li><a href="#avoid-unnecessary-elements" title="Avoid Unnecessary Elements">Avoid Unnecessary Elements</a></li>
</ul>
</li>
<li><a href="#unnecessary-classes" title="Avoid Unnecessary Classes and IDs">Avoid Unnecessary Classes and IDs</a></li>
<li><a href="#image-tags" title="Image Tags">Image Tags</a></li>
<li><a href="#miscellaneous-guidelines" title="Miscellaneous Guidelines">Miscellaneous Guidelines</a></li>
</ul>
</li>
<li>
<a class="top-level" href="images.html" title="Images">Images</a>
<ul class="second-level">
<li><a href="#image-size" title="Image Size">Image Size</a></li>
<li><a href="#image-format" title="Image Formats">Image Formats</a></li>
<li><a href="#CSS-sprites" title="Leverage CSS Sprites">Leverage CSS Sprites</a></li>
</ul>
</li>
<li>
<a class="top-level" href="css.html" title="CSS">CSS</a>
<ul class="second-level">
<li><a href="#inline-styles" title="Inline Styles">Inline Styles</a></li>
<li><a href="#external-css" title="Place All CSS Within the <head>">Place All CSS Within the <code><head></code></a></li>
<li><a href="#combine-stylesheets" title="Combine CSS Files">Combine CSS Files</a></li>
<li><a href="#link-vs-import" title="Use <link> to Include CSS, Not @import">Use <code><link></code> to Include CSS, Not <code>@import</code></a></li>
<li><a href="#reset" title="Use a CSS Reset">Use a CSS Reset</a></li>
<li><a href="#font-sizes" title="Specifying Font Sizes">Specifying Font Sizes</a></li>
<li><a href="#writing-good-selectors" title="Writing Good Selectors">Writing Good Selectors</a></li>
<li><a href="#shorthand" title="Shorthand">Shorthand</a></li>
</ul>
</li>
<li class="active">
<a class="top-level" href="#javascript" title="JavaScript">JavaScript</a>
<ul class="second-level">
<li><a href="#use-external-js" title="Restrict JavaScript to External Files">Restrict JavaScript to External Files</a></li>
<li>
<a href="#place-external-js" title="Placement of External JavaScript Files">Placement of External JavaScript Files</a>
<ul>
<li><a href="#end-of-page" title="Include JavaScript near the end of the page">Include JavaScript near the end of the page</a></li>
<li><a href="#js-loader" title="Use a JavaScript loader">Use a JavaScript loader</a></li>
</ul>
</li>
<li><a href="#use-jquery" title="Use jQuery">Use jQuery</a></li>
<li><a href="#organize-code" title="Organize Your Code">Organize Your Code</a></li>
<li><a href="#general-js" title="General Coding Practices">General Coding Practices</a></li>
</ul>
</li>
<li>
<a class="top-level" href="about.html" title="About">About</a>
<ul class="second-level">
<li><a href="#summary" title="Purpose">Purpose</a></li>
<li><a href="#goals" title="Goals">Goals</a></li>
<li><a href="#contributors" title="Contributors">Contributors</a></li>
</ul>
</li>
</ul>
</nav>
<section id="javascript">
<h1>JavaScript</h1>
<ul class="recs">
<li>
<h2 id="use-external-js">Restrict JavaScript to External Files</h2>
<p>
Avoiding inline JavaScript is even more critical than avoiding inline CSS. Including code within <code><script></code>
elements is sometimes permissible for certain rare use cases, but keep in mind that this has a negative impact on SEO, and increases
the filesize of the HTML without the benefit of caching or compression.
</p>
<p>
JavaScript event attributes (such as <code>onclick</code> or <code>onload</code>) and JavaScript included within the <code>href</code> attribute of an anchor tag
should <strong>never</strong> be used.
</p>
<p>
A full discussion of this topic can be found
<a href="http://robertnyman.com/2008/11/20/why-inline-css-and-javascript-code-is-such-a-bad-thing/" target="_blank" title="Read about why to avoid inline JavaScript">here</a>.
</p>
<p>
It should be noted that HTML comments within <code><script></code> elements are no longer necessary. None of the browsers
that required this hack are still in use. Similarly, the <code>type</code> attribute and the practice of enclosing JavaScript
within a CDATA section, required in HTML4 and XHTML, are no longer necessary in HTML5.
</p>
</li>
<li>
<h2 id="place-external-js">Placement of External JavaScript Files</h2>
<p>
JavaScript downloads are said to be <em>blocking</em>, because nothing after the JavaScript include in the HTML can be parsed until
the JavaScript has finished downloading and executing. This can have a huge impact on the performance of a web page, and there are
a couple of common ways of dealing with it.
</p>
<h3 id="end-of-page">Include JavaScript near the end of the page</h3>
<p>
The most common method of dealing with JavaScript blocking is to include JavaScript at the end of your HTML document, just prior to the
closing <code></body></code> tag. This also helps to ensure that the DOM elements of the page have already been loaded prior to
JavaScript execution (so technically, you can omit event handlers that watch for the page to be loaded or for the DOM to be ready when
including scripts in this fashion).
</p>
<p>
If there is code that needs to execute prior to DOM elements being rendered (such as code that modifies the <code>class</code> attribute of
the <code>html</code> element, it may still be loaded in the <code>head</code> of the document.
</p>
<p>
When including JavaScript with <code><script></code> elements at the bottom of the page, it is important to minimize the number
of different JavaScript files being loaded. This becomes less important when using a script loader.
</p>
<h3 id="js-loader">Use a JavaScript loader</h3>
<p>
A recent trend in the web development world is to load JavaScript files asynchronously. The <code>async</code> and <code>defer</code>
attributes (described <a href="https://developer.mozilla.org/en/HTML/Element/script#Attributes" title="Mozilla Developer Network">here</a>)
are meant to provide this functionality, but there are issues with both that prevent them from being a total solution.
</p>
<p>
Until such a time as browsers can provide asynchronous loading and dependency management natively (expect this with
<a href="https://mail.mozilla.org/pipermail/es-discuss/2008-August/006837.html" title="ECMAScript Harmony">ES Harmony</a>),
it is necessary to use a script loader. A good script loader can end up being the only JavaScript that you include in the
traditional fashion, with all other files being called in through the loader's API. For an approach that combines the benefits
of a script loader with the built-in advantages of <code>async</code> and <code>defer</code>, check out
<a href="http://unscriptable.com/2011/09/21/what-is-the-fastest-way-to-load-amd-modules" title="Unscriptable">this article</a>.
</p>
<p>
Script loaders provide many benefits; they can:
</p>
<ul>
<li>
<p>
Load scripts like images, which load separately from the page rendering process (i.e., are non-blocking)
</p>
</li>
<li>
<p>
Provide dependency management, so that scripts can be loaded in parallel, but executed <em>in order</em> (huge performance gains here)
</p>
</li>
<li>
<p>
Provide callback functions to script loads, ready functions that can execute on a script-by-script basis, and much more
</p>
</li>
</ul>
<p>
A comparison of some of the more popular script loaders can be found in this
<a href="https://spreadsheets.google.com/ccc?key=0Aqln2akPWiMIdERkY3J2OXdOUVJDTkNSQ2ZsV3hoWVE&hl=en#gid=2" target="_blank" title="Comparison of script loaders">Google spreadsheet</a>.
Note that this spreadsheet is no longer maintained.
</p>
<p>
This page uses curl.js to load JavaScript in the fastest way possible (and even allows us to load scripts in the <code><head></code>
of the document). One advantage to curl.js is that it follows the CommonJS AMD (asynchronous module definition) specification. This increases
the portability of application code and ensures a consistent interface that even translates well into the realm of the server (with Node.js).
</p>
<figure>
<figcaption class="code-label">Using curl.js looks like this</figcaption>
<pre><code data-language="javascript"><script src="js/curl.js"></script>
<script>
define.amd.jQuery = true;
curl(
{
baseUrl: "js",
paths: {
"jquery":"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min"
}
},
[
"jquery",
"jquery.easing.1.3",
"syntax-highlighter",
"main"
]
);
</script> </code></pre>
</figure>
</li>
<li>
<h2 id="use-jquery">Use jQuery</h2>
<p>
In depth knowledge of the JavaScript language and the ability to perform common tasks without a JavaScript library is strongly
encouraged. That said, it isn't realistic or efficient to start from scratch for every project, and JavaScript libraries are
invaluable for their ability to simplify common functionality, like DOM manipulation and AJAX requests.
</p>
<p>
There is no such thing as a "best" JavaScript library, but given that jQuery is currently the most popular, it is recommended for use
in new web pages and applications. This increases the likelihood that other developers will be comfortable working with the code that
you write.
</p>
<p>
If there is already a different JavaScript framework in place for your project (Mootools, Dojo, YUI3, etc), you should make every
effort to work within the API provided by that framework and <strong>do not</strong> include jQuery or another such library unless
it is absolutely necessary to complete your work. Libraries are very similar in terms of the types of functionality they offer,
and they are very large in file size. Including more than one is a wasteful use of your users' bandwidth.
</p>
<p>
When including jQuery (or another library), you may want to consider linking to a file on a content delivery network,
like the one provided by Google: <a href="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" target="_blank" title="Google CDN version of jQuery">http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js</a>.
Using a CDN provides a number of benefits: the file usually originates from a server near to the user geographically, will download concurrently with
other scripts (because it's coming from a different domain), and often benefits from caching, since multiple web sites all point to the same URI.
</p>
</li>
<li>
<h2 id="organize-code">Organize Your Code</h2>
<p>
Putting thought into the structure and organization of your JavaScript enables you to write code that
is easier to maintain, more reusable, easier to read, and less likely to cause collisions with other scripts.
There are almost as many ways to effectively organize code as there are developers, but several tried and true
patterns have emerged over the years:
</p>
<ul>
<li>
<p>
<a href="http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth" target="_blank" title="Ben Cherry - Module pattern">Module pattern</a>
</p>
<li>
<p>
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD">Asynchronous Module Definition (AMD)</a>
</p>
</li>
<li>
<p>
<a href="http://www.wait-till-i.com/2006/02/16/show-love-to-the-object-literal/" target="_blank" title="Chris Heilmann - Object literal">Object literal</a>
(basically, the singleton pattern at its simplest)
</p>
</li>
<li>
<p>
Inheritance patterns encourage code reuse and organization; there are several different ways of accomplishing inheritance in JavaScript, but developers are
encouraged to use one of the following:
</p>
<ul>
<li>
<p>
JavaScript is a class-free, prototypal language, but it has sufficient expressive power to simulate a classical system;
<a href="http://javascript.crockford.com/inheritance.html" target="_blank" title="Douglas Crockford - Pseudo-classical inheritance">Pseudo-classical inheritance</a>
can be a useful pattern to follow for developers who are familiar with conventional object-oriented languages like C++ and Java
</p>
</li>
<li>
<p>
<a href="http://javascript.crockford.com/prototypal.html" target="_blank" title="Douglas Crockford - Prototypal inheritance">Prototypal inheritance</a> better
lends itself to the features of the JavaScript language, and is more memory efficient in some situations; Prototypal inheritance is a little strange,
and may be difficult to get used to if you're used to a conventional object-oriented language
</p>
<p>
An example prototypal inheritance implementation with some helpful utility functions can be found
<a href="toolkit/prototypal_inheritance.js" target="_blank" title="Example prototypal inheritance script">here</a>; Note that two of the utility functions are
ES5
<a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/" target="_blank" title="Remy Sharp - Polyfills">polyfills</a>, which are intended to
provide ECMAScript 5 functionality in ECMAScript 3 browsers
</p>
</li>
</ul>
</li>
</ul>
</li>
<li>
<h2 id="general-js">General Coding Practices</h2>
<ul>
<li>
<p>
Use a code quality tool like <a href="http://www.jslint.com/" target="_blank" title="JSLint">JSLint</a>; JSLint is also integrated into some code authoring
tools, such as the Aptana IDE
</p>
</li>
<li>
<p>
Don't use <code>document.write()</code>
</p>
</li>
<li>
<p>
Comment your code thoroughly; the use of a standardized documentation format (such as YUI Doc, ScriptDoc, or Natural Docs) is
recommended
</p>
</li>
<li>
<p>
Declare variables at the top of their containing function
</p>
</li>
<li>
<p>
Don't use
<a href="https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words" target="_blank" title="MDC - Reserved words">reserved words</a>
for variables, functions, or object property names
</p>
</li>
<li>
<p>
Always use <code>var</code> statements when declaring variables, and never use the <code>var</code> statement when assigning
to a variable that has previously been declared
</p>
</li>
<li>
<p>
When commenting out code rather than providing documentation, favor single line comments over multi-line comments;
Some regular expressions may inadvertently end a multi-line comment, so single line comments are safer
</p>
<figure>
<figcaption class="code-label">Multi-line comment</figcaption>
<pre><code data-language="javascript">/**
* Multi-line comments should be used for documentation.
* This format is used by ScriptDoc.
* @param {String} fooId The unique identifier for the foo.
* @return {Object} Returns the current foo.
*/
function getFoo(fooID){
} </code></pre>
</figure>
<figure>
<figcaption class="code-label">Single line comments</figcaption>
<pre><code data-language="javascript">// function getFoo(fooID){
// console.log("Single line comments should be used to comment out code");
// } </code></pre>
</figure>
</li>
<li>
<p>
Strive to create functions which can be generalized, take parameters, and return values;
This allows for substantial code reuse and, when combined with includes or external scripts,
can reduce the overhead when scripts need to change
</p>
<p>
For example, instead of hard coding a pop-window with window size, options, and url, consider
creating a function which takes size, url, and options as variables
</p>
</li>
<li>
Minimize the use of global variables (see
<a class="jumper" href="#organize-code" title="Jump to "Organize Your Code", below">Organize Your Code</a>, above)
</li>
</ul>
</li>
</ul>
</section>
</div>
</body>
</html>