Skip to content

Best practices

Kunal Nagpal edited this page Apr 24, 2016 · 13 revisions

Note: The guidelines provided below contain a mixture of points specific to this project (GPL), and some others that are generic to web development as a whole.

Version control:

  • Ensure that you run git pull within a terminal instance on the project directory frequently, ideally once every time before you start work on a new feature, to minimize the probability of encountering merge conflicts.

  • Ensure that every commit you push to the GitHub repository comes with a meaningful commit message. This allows your peers to conduct swifter code reviews, and improves overall understanding. The recommended format for a commit message is:

Short one-liner commit summary, including functionality added, bugs fixed, other adjustments made.

Broader commit explanation, up to one paragraph. (Optional)

You are not required to mention which files were altered during the course of your commit, as Git does that for you by default.

  • Avoid altering too many files, making too many changes, or any such similar actions within one commit. Split workflow into smaller quanta, keep your commits short and sweet. This is not applicable for refactoring actions, which occur on a project-wide scope.

  • To all extents possible, push a commit as soon as you create it. Hoarding commits locally is a bad idea.

  • Ensure that all tests are passing before you push your commit to GitHub (work needed).

Front end development:

HTML:

  • Avoid using deprecated tags, as they will run out of browser support in the near future. Full list here

  • Adhere to code formatting specifications, so as to maintain uniformity. To keep productivity high, find the code formatting keyboard shortcuts for your IDE of choice.

  • Avoid splitting html tags across several lines unless absolutely necessary.

  • Be on the lookout for unclosed tags, mismatched tags, and so on.

  • Whilst using AngularJS, append data- to all ng- attributes, so as to maintain HTML5 compliance.

<div ng-if=""></div>

✔️

<div data-ng-if=""></div>

CSS:

  • Enable file watching within your IDE of choice, so as to keep CSS files minified. Use these minified equivalents in all style sheet references, for self defined CSS in particular. The same applies to externally loaded libraries.

  • Avoid inline styling (with the style attribute on html tags) at all costs.

  • Split the entire CSS across your website into sheets such that, each sheet contains all the styling for one particular page. Common segments like background colour, font, and navbar styling, et cetera should go in one file to be referenced across all pages. This keeps the CSS requests to a bare minimum, allowing the user's browser to render the pages quickly, even on phones.

  • To avoid FOUC, refer all stylesheets in the head section only. If you explicitly wish to refer all static assets after the <body></body>, use pre-loaders to allow all content to load, while your users wait.

  • Instead of serving CSS stylesheets (libraries in particular) directly from the server, switch to a CDN service, like cdnjs , Cloudflare, or even Google CDN.

JavaScript:

  • Avoid using functions like map, filter, reduce, and the like for front end array operations, as they are significantly computationally expensive as compared to regular loops.

  • Reference all JavaScript sheets after the body tag closes, like so: (NOT applicable for Google Analytics scripts, which must be loaded as the last unit in <head></head>)

<body>
...
</body>
<script type="text/javascript" src="my cdn javscript source"></script>

This prevents the page render being blocked by the JavaScript resources, resulting in lower load times.

  • Declare all variables with the var directive.

  • Just like CSS stylesheets, ensure that all JavaScript references (libraries in particular) have been delegated to a CDN service.

  • Avoid performing computationally intense calculations, repetitive operations or HTML generation operations on the front end, as they reduce the application usability. All such tasks are to be performed on the back end, so as to reduce front end tasks to just rendering, nothing more. To inject HTML into a view, use EJS partials

  • Lastly, use a minification tool for JavaScript, in case the sheets are being referenced from within the application itself. The same applies to externally loaded libraries.

Images:

  • Ensure that all images used are properly sized and compressed, preferably via TinyPNG.

  • The process of compression on one particular image may have to be applied multiple times, so as to shave away all the excess kilobytes off the image.

  • Once the image has been compressed, have it uploaded to the project's associated Cloudinary account.

  • Whist referencing images within HTML, specify both dimensions explicitly, else the browser will have to do more work calculating the missing dimension.

  • Additionally, do not use the PNG format if the image does not require transparency. Stick with JPEG in all such cases.

  • Lastly, use image sprites to handle logos and all other such small / medium sized images, so that the entire set of logos / icons can be loaded in one go. For more details, check this issue.

Back end development:

  • If your code throws exceptions, ensure that those exceptions are handled by the pre-defined error handler, or one that you have built, in app.js. Unhandled exceptions will lead to an application crash, and bring the site down for anyone who wants to use it. (This only applies to Node.js, as it does not use OS level threads to handle concurrent requests)

  • Confine to the ES6 standard of JavaScript. Hence, functions like map, filter, and reduce can be used on the back end, but only in their asynchronous form. See the next point for more details.

  • Every synchronous request made within a Node.js application is blocking, which means that it disbars the application server from handling any other requests made within the time window of that task's completion. From a user's perspective, this gets translated into latency and sluggishness. Many libraries offer synchronous alternatives, do not use them. For instance:

var bcrypt = require('bcrypt'); // bcryptjs on Windows
var salt = bcrypt.genSaltSync(10);
var passwordHash = bcrypt.hashSync('password', salt);

✔️

var hash;
var bcrypt = require('bcrypt'); // ensure that the postinstall script completes for this to work on Windows
bcrypt.hash('password', 10, function(err, result) {
    if(err) {
        console.error(err.message):
    }
    else {
        hash = result;
    }
});
  • Additionally, in situations where array traversal is required, such that the order of element processing is irrelevant, the library async may be used.

Miscellaneous:

  • Make exhaustive use of keyboard shortcuts: This often gets lost as a huge understatement, but learning how to use keyboard shortcuts can and will improve your productivity, keeping your hand movements streamlined and focused. Checkout the exhaustive list for various IDEs here.