Skip to content

Instantly share code, notes, and snippets.

@njmcode
Last active March 30, 2017 11:08
Show Gist options
  • Save njmcode/d46c18a46f167ac121363d08e605867b to your computer and use it in GitHub Desktop.
Save njmcode/d46c18a46f167ac121363d08e605867b to your computer and use it in GitHub Desktop.
Recap, resources and examples for my March 2017 talk at UUJ IMD.

Web Development/UX Grab Bag

A recap and some supplementary resources to accompany my recent chat/rant, the expertly-titled Assorted Tips And Tricks (For Web Stuff), given at UUJ IMD in March 2017.

Garish synthwave-inspired slides here: https://goo.gl/nAxjyk

Although aimed at final year students, hopefully anyone involved in development, design and/or UX work for the browser will find this stuff useful.

This document is WIP; more content coming soon.

Things I use

A non-exhaustive and highly opinionated list of tools, frameworks, libraries and services I use regularly, with some extra detail in places.

The basics

ES6 is one of the latest stable versions of JavaScript, and gives you some nice new language features and constructs to improve your code.

// variables can now be constants (can't be re-assigned)
const someValue = 10
someValue = 20 // throws a TypeError

// String templating
console.log(`There is a value of ${someValue} in the variable`)
// --> There is a value of 10 in the variable

// Shorthand for functions
// This is equivalent to:
// function subtract (a, b) { return a - b }
const subtract = (a, b) => a - b
subtract (10, 2) // 8

// Shorthand for defining objects
const a = 1
const b = 2
const myObject = { a, b } // { a: 1, b: 2 }

// Object spreading - merge an object into a new one
const c = 3
const myNewObject = { ...myObject, c } // { a: 1, b: 2, c: 3 }

// Shorthand for getting object values
const { x, y } = someObject // x = someObject.x, y = someObject.y

// Proper classes, instead of Object.prototype shenanigans in old JS
class Person {
    constructor (fullName, age) {
        this.fullName = fullName
        this.age = age
    }
    speak () {
        console.log(`Hi, I'm ${this.fullName} and I'm ${this.age} years old`) 
    }
}

const neil = new Person('Neil McCallion', 35)
console.log(neil.speak())
// --> Hi, I'm Neil McCallion and I'm 35 years old

if (neil.age > 30) console.log('Neil is too old for this s***')
// --> Neil is too old for this s***

// Easier class inheritance
class Zombie extends Person {
    speak () {
        super.speak()
        console.log('and I will also eat your brains')
    }
}
const claire = new Zombie('Claire Wilgar', 27)
console.log(claire.speak())
// --> Hi, I'm Claire Wilgar and I'm 27 years old
// --> and I will also eat your brains

For browsers that don't yet support all ES6 features, Babel is used to transpile the ES6 code into ES5.

Things like flexbox, transitions, animations etc allow for complex layouts and hardware-accelerated effects without requiring JavaScript.

<div class="container">
    <div class="inner">
        <h2>Flexbox makes layouts easier</h2>
        <p>This text should be vertically and horizontally centred in the container, regardless of height, which is a historically difficult thing to do in CSS.</p>
    </div>
</div>
.container {
    display: flex; 
    align-items: center;
    justify-content: center;
    min-height: 400px;
    background-color: pink;
}
.inner {
    max-width: 300px;
}

As in the markup language, the <section>s and <p>s with which we construct pages ('HTML5' can also refer to the ecosystem of web APIs available in modern browsers). Using appropriate <input> types for things like number, tel, datetime, color etc can really help with accessibility, though browser support can be a bit patchy. ARIA atrributes are also important for users with assistive devices.

<input type="date" value="2017-03-27">
<input type="color" value="#ff0099">
<input type="number" value="10" min="4" max="12" step="2">
<input type="range" min="0" max="200" step="10">

An editor/IDE

It's not a holy war. Use whatever gets the job done and which makes you productive. I like Sublime Text, but I have friends and colleagues who swear by Atom, Brackets, Vim, and many others. The important thing is that you can run a linter in it, that it has syntax highlighting, and that it runs fast on your machine. Try a few and see what feels good to you. And don't get too attached, because some companies may insist you use a different one for various reasons.

Frameworks and libraries

Currently widely-used for building UIs and managing state/logic in frontend web apps. React makes it easier to build re-usable UI components with their own custom properties.

// React 'micro-component' via ES6 arrow functions
const MyProfile = props => (
    <div>
        <img src={props.avatar} />
        <p>{props.name}</p>
        <button onClick={props.handleClick}>View</button>
    </div>
)
...
<MyProfile avatar="avatars/me.png" name="Neil M"
    handleClick={openProfilePage} />

Redux manages data binding and can help define the logical shape of your app (what information is passed around, the state of different components, etc). There is an entire ecosystem of plugins and libraries around React, for everything from URL routing, to Material Design, to custom UI components and much more. None of it is a silver bullet, but the community is large and passionate, and it is a useful tool to have in your arsenal. Just don't make it the only thing you know (this goes for any framework or library, period).

Google's own UI library and application development framework. Is way more 'batteries included' than React (theoretically) and includes pretty much everything you need to build rich web apps. I haven't used it since version 1.5x, but it's on version 2 now, and seems to have a load of new features and improvements. Widely used in the industry so check it out.

A powerful framework for building 2D games and graphics in the browser. Includes classes and helpers for things like moveable objects, controls, collisions, pathfinding, particles, drag-drop, timers, game state, grouping, sound, effects, and much more. Has many great examples on the official site. I use this a lot for game jams, with varying degrees of success. Can take a moment to set up properly, but there are skeleton projects like this one to get you started.

A library for building WebGL experiences in the browser. Provides classes for basic objects, cameras, fog, models/meshes, shader effects, controls, VR, and much more. Widely used for rich advertising and gaming. The official site has some mind-blowing examples.

Build tools and scripts

Working with JavaScript source files can get tricky as the size of your app grows. You may have dependencies between different files that can't easily be resolved, or you may find that the order in which things are loaded can cause breakages in different parts of your app.

JavaScript does have the concept of modules, where each JS source file can define what it depends on (imports) and what other parts of the app can take from it (exports), but support in browsers is still a WIP at time of writing.

Webpack is a module bundler - it reads through all your source files, figures out the imports and exports of each source file, and wraps them up into a JS file(s) which can be loaded in the browser by your app. It can work with JS, CSS, images, and almost any other type of file, so you can be very explicit about what exactly each module in your app depends on. This allows you to write small, clean, modular bits of code in your apps, allowing for better maintainability and re-usability.

Webpack can also perform a vast number of processes on the output, such as minifying JS and CSS to reducer file size, splitting up your files into smaller chunks, reducing duplication, and much, much more. It's a complex tool and is now on version 2 - it plays very well with most popular frameworks, and is a valuable weapon in the modern web dev arsenal.

Node.js provides a JavaScript environment outside of the browser, i.e. on the desktop and the server. It is widely used in web development for creating APIs and web servers (e.g. via Express), to run development tools such as Webpack, linters and other scripts. npm is the official package manager for Node.js and lets you automatically install the libraries and dependencies for your project without having to include those files directly in your project repo.

Testing and debugging

A linter (code analyser) which can be added to your editor and/or run from the terminal. Can be told to adhere to specific common rules, and will automatically flag up style violations, misnamed/missing variables, code that never runs, indentation mix-ups, unclosed blocks, and much much more. Will eliminate so many errors before you even get to publish your code. It's a lifesaver, and will help you to maintain a consistent code style too.

An incredibly powerful development and debugging environment for understanding what's going on in your app. Like seeing into the Matrix. You should get particularly familiar with:

  • Network view - see what's being loaded and when, how big it is, when your app becomes visible on-screen, and how good (or otherwise) it performs when loaded on a bad connection or low-powered CPU.
  • Device mode and remote devices - emulate different viewport sizes and interfaces, and debug Chrome Android on your mobile from the comfort of your own desktop. Essential when building responsively.
  • Paint viewer - shows you when areas of the screen are repainting, which can cause slowdown and janky scrolling if abused. Really helps with making transitions and touch interactions nice and smooth.

A widely-used setup for unit testing (writing code which tests the different parts of your application logic). Runs in the terminal or browser, and will throw errors if the tests fail; great to make sure that your app does what it's supposed to, and that you're not breaking something when making changes.

// Test code describes how we expect the subtract() function to behave
describe('The subtract function', () => {
    it('should subtract the second param from the first', () => {
        expect(subtract(20, 5)).to.eql(15)
    })
})
...
// Oops, we've got our params back to front in the function definition
const subtract = (a, b) => ( b - a )
...
// Test will fail when run: 'expected 15, got -15'

Design, UX and project management

Code collaboration and versioning service. Hugely popular in the open source community.

Vector and raster graphic editor with an emphasis on UX design. Sketch has gained a lot of traction in web design due to developer-friendly features like outputting CSS rules for elements. Sadly Mac-only.

A really great prototyping and design versioning service. Can take designs and make them clickable/interactive - perfect for early prototyping, testing ideas, and mocking up sites for clients. Intergrates nicely with Sketch too.

Project management and issue tracking tools. Trello is nice and clean and great for small teams or lone designers/developers. Jira is massively powerful but is more aimed at enterprise and larger companies.

Other things

I just couldn't do without it. Immediately prototype and test JS, CSS and HTML ideas, share rapid prototypes with colleagues and clients, perform weird experiments, mess around with different web APIs, and get inspired by the incredible daily output from the community. Get one and use it. JSFiddle is an okay alternative for quick tests too.

Quick wins and improvements for web dev

Additions that often take very little effort, but which can really improve the user and developer experience.

Turn your linter on

As mentioned above, using ESLint to maintain a consistent style and automatically spot syntax errors is a major help, and can save you hours hunting down that elusive missing bracket. Get into the habit of having it configured and turned on for all of your JavaScript projects - it shows that you care about consistency and quality.

Add theme and viewport <meta> tags

A recent addition to some browsers is the ability to specify a 'theme colour' which will affect the URL bar and browser chrome on mobile devices. It's a one-line addition to the <head> of your page, and can really make your site or app feel a bit more polished and integrated. It's not dynamically changeable at time of writing, so pick a colour that matches your branding or theming.

<meta name="theme-color" content="#ff0099">

Additionally, you should always set a viewport tag to tell the browser that your site should render according to the logical width of your device screen. Without this, many responsive sites would not display properly.

<meta name="viewport" content="width=device-width, initial-scale=1">

It's also possible to disable the ability for the user to zoom the page, but please don't do this.

Add a web manifest file

A step further than the theme tag, a web manifest file lets you define colours, icons and behaviour for when a user adds your site to their Home screen on supporting devices. You can set icons for different screen sizes, colours and labels for splash screens, and can even set the site to launch fullscreen, lock the screen orientation, and other more app-like features.

manifest.json
{
    "short_name": "njmcode App",
    "name": "njmcode's Awesome Web App",
    "icons": [
        {
            "src": "assets/icons/launch-icon.png",
            "sizes": "96x96",
            "type": "image/png",
        }
    ],
    "display": "standalone",
    "orientation" : "portrait",
    "theme_color": "#ffffff",
    "background_color": "#ff0099",
    "start_url": "/"
}

It's an important step in making your web apps feel more native-like, but you should also consider the accessibility implications of things like hiding the browser URL bar, locking the screen orientation, and so on.

Show something before your JS loads

Many web app creators have almost nothing in their initial HTML, maybe even just an empty <body> tag, and only render content to the screen once their JS app has loaded. The problem here is that while the JS is loading, the user is staring at a white page. This is a poor user experience and can lead to users bouncing off your page.

A simple solution is to make sure there is some content in the initial HTML page you serve to the users, and by always placing your <script> tags right at the end of the <body>. Browsers render web pages progressively, so the user will be shown the HTML content before the browser attempts to load the content of <script> tags. Many web apps embed a mockup of their UI and a spinner/message - an 'app shell' - which gives the page more of an app-like feel and keeps the user informed. Slack, many Google apps, Facebook, and other big web apps frequently do this, and it's easy to achieve.

<!-- index.html -->
<body>
    <div class="app-wrapper">
        <div class="app-shell">
            <div class="spinner"></div>
            <p>Loading...</p>
        </div>
    </div>
    <script src="app.js"></script>
</body>
// app.js
// Remove the app shell from the DOM and 
// render your React/Angular/whatever app instead
removeAppShell()
renderApp()

Way more content to follow - check back soon.

Curated by njmcode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment