You are on page 1of 199

FRONT-END TOOLING

WORKFLOWS

+AddyOsmani
@addyosmani

Building for the web


sometimes feels like

Time is a key factor in staying productive.


Use yours efficiently.

Better tooling can be simple.

Can DevTools help us


emulate real devices?

It can be as simple as opting for

emulation when a real-device isnt needed


for testing.

Throttle network speed


Toggle between devices

Having tools refresh device URLs for you


BrowserSync

Synchronise:
Scrolls
Clicks
Refresh
Forms

Previewing all your


breakpoints at once
Emmett Re:View

or automating style guide conformance checking

JSCS for Sublime Text

Highlight issues

Fix to match the Style Guide

Tooling can be weird..and wonderful.


Search your command-line history
$ history | grep querySelector

Copy to clipboard
$ echo 'Hello World!' | pbcopy

Unzip an archive to the current directory


$ unzip -l images.zip

Discover whats eating your memory


$ top -o vsize

Run the last command with sudo


$ sudo !!

Use Spotlight to search from command-line


$ mdfind <keyword>

It can extend your debugging experience


React DevTools

Angular Batarang

Gradient Inspector

Tamper (modify requests before serving)

ES6 REPL

Optimise sites with little to no configuration..*


Smaller for CSS/JS/HTML (Mac)

Ngx PageSpeed / Mod PageSpeed

ImageOptim (Mac) or PNGGauntlet (Windows)

* well talk about Grunt, Gulp and npm soon

Beautify and fix issues in your source


jsfmt

Format, search and re-write JS


$ jsfmt -w=true source.js

fixmyjs

Non-destructively fix linting errors


$ fixmyjs source.js

jsinspect

Detect structural similarities in code


$ jsinspect -t 30 -i ./scripts

Or just improve your workflow.


Sip Color Picker

Chrome DevTools Eye Dropper

Automation is having tools do the


tedious work, so you dont have to.

If you arent using productivity tools


or task automation, you are working
too hard

Our tools are like onions.

Peel back the layers to discover more functionality.

Learn to love the command-line

Improve your command-line skills


!
!

$ git clone
$ sublime .

Go to the start of the line


Ctrl

Go to the end of the line


Ctrl

Learn to love and


use shortcuts.

iTerm2.x for Mac

Autocomplete

Paste history

Open with a
global shortcut

Replay command history

Zsh

Customisable alternative to Bash

Prezto - config framework for Zsh


Pure - minimal prompt

See http://jilles.me/badassify-your-terminal-and-shell/

cmder for Windows


Slick console with enhancements spiced with Monokai colours and a custom prompt layout

Many CLI apps to augment your workflow


e.g PageRes for generating responsive screenshots from the command-line

Learn to use dot files to alias common


tasks in your workflow

Customise Dotfiles (theme, .aliases, .functions)


!

addyo at addyo-macbook in ~/projects/ on master*


!

$
$
$
$
$

server
clone
tree
fs
gz

Learn to extend your tools

Color Highlighter

CSS & Sass

Gutter Color

ColorPicker

AutoFilename

JSHint Gutter Linter

GitGutter

Enforce code style with JSCS


Code Style Configuration

Emmett for HTML

Type a one-liner

HTML generated
just hit tab!

Navigate quickly to any file

Navigate to any symbol

Pick a theme that helps you focus

Seti UI Theme (for Sublime Text)

Icons per
extension

Crisp
colors

which is a port of Seti UI Theme (for Atom Editor)

Per-tool icons
!

(e.g Grunt, Gulp)

Maybe someday write your tools

Sublime
FixMyJS

Build Tools

What do we build?

HTML
<div class=paper-button id="go" disabled>Go!</div>

CSS
.paper-button {
background-color: red;
}

JavaScript
document.querySelector('.paper-button')
.addEventListener('click', function(e) {
// your code here
}, false);

Pre-processors

sass input.scss output.css


sass watch
Sass

CSS

Bundle dependencies

browserify app.js -o bundle.js

Modules

Bundle

Language transpilers

coffee --compile
coffee --watch
Coffee

JavaScript

Why do we build?

Productivity & performance

b
e
w
e
Th

soup.io

Average page size

1.9MB
~1.2MB images
~0.35MB scripts &
styles
HTTPArchive - October 2014 reports 1944KB

TMI (Too Many Images)


http://github.com/addyosmani/tmi

Human Perception in 2014


0-100ms

300-1000ms

1 second +

10 seconds +

Later.

Automating performance
improvement

When you want to be fast, you have to


give up the things slowing you down.

+
(1) Client renders page, custom JS beacons back ATF CSS styles

PageSpeed gathers critical CSS beacons from visitors


(2) Critical CSS is inlined...

Remaining CSS loaded after first paint

!ModPagespeedEnableFilters!prioritize_critical_css!!!!#!Apache
!

!pagespeed!EnableFilters!!!prioritize_critical_css!!!!#!Nginx!

modpagespeed.com
ngxpagespeed.com

https://developers.google.com/speed/pagespeed/module/filter-prioritize-critical-css

JSConf.eu

Old Speed Index

2149

Optimized: JSConf.eu + mod_pagespeed

Old Speed Index

2149

New Speed Index

1310

How do we build?

Boilerplate Abstractions Frameworks

Testing Docs Workflow Dependency


management Performance

optimization Build Continuous


Integration Deployment Version control

Setup
!

Scaffolding
!

HTML5 Boilerplate

Download libraries
Twitter Bootstrap

Download templates
!

Layouts

Download frameworks

Angular, Polymer, Ember.

Develop
!

Watch

Sass, Less, Stylus


CoffeeScript, ECMAScript 6
Jade, Haml

LiveReload

Refresh pages

Linting

JavaScript
CSS
Style linting

Build
!

Code linting
Running unit tests
Compile everything
Minify and concatenate
Generate images / icons
Optimize performance
HTTP Server
Deployment

Automate workflow for


simple projects

CodeKit

Hammer for Mac

Prepros

Automate workflow for


all types of projects

Build Tools

Make

Why use a task runner


or build system?
Automation

Improve quality

Ship the goods


to users faster

Its easily
repeatable

Automation isnt about being lazy. Its


about being efficient

What are Gulp and Grunt?

Grunt and Gulp

Task runner

Streaming build
system

How are they different?


!

Based on files
Configuration over code

Based on streams
Code over configuration

Creating this workflow

Get files

Modify
them

Make new
ones

Win

Typical Grunt task

!
!

File system

Read files

Modify

Temp

Temp

Write files

Read files

Modify

Write files

Read files

Modify

Gulp uses streams

!
!

File system

File system

Read files

Write
files

Modify

Modify

Modify

Modify

Task automation with Gulp

Before you get started


Prerequisites

Download and install NodeJS

Available for all major operating systems

Install Gulp as a global utility

$ npm install -g gulp

Gulp in a nutshell

Install Gulp
globally

Create
package
file

Install
dependent
packages

Add tasks
to your
Gulp file

Load
tasks into
Gulp

Create your package.json file

$ npm init

Prompts for your author, package


name and the basics.

Install Gulp locally to the package.json file

$ npm install gulp save-dev


save-dev for
development

save for
production

Gulp plugins use streams

Streams
!
!

gulp.src(app/vendor/*.js);
gulp.src(app/**/*.js);
gulp.src(never/gonna/give/you/up.js);
gulp.src([**/*.js,*.cs]);

Install Gulp locally to the package.json file


$ npm install gulp-concat gulp-uglify gulp-jshint save-dev

Concatenate files

Minify files

Lint your
JavaScript

package.json to manage dependencies

Good news! Theres only 4 API methods

Gulps API

gulp.task(name, [dep], fn)

Registers a task name with a function

!
!
!

gulp.task(scripts, [lint], function () {


return gulp.src('js/*.js')
.pipe(uglify())
.pipe(gulp.dest(dist));
});
Optionally declare dependencies

gulp.src(glob)
!
!
!

gulp.task(scripts, [lint], function () {


return gulp.src('js/*.js')
.pipe(uglify())
.pipe(gulp.dest(dist));
});
Take a file system glob (set of files) and emit
files that match

gulp.dest(folder)
!
!
!

gulp.task(scripts, [lint], function () {


return gulp.src('js/*.js')
.pipe(uglify())
.pipe(gulp.dest(dist));
});

Piped files are written to the file system

e.g Minifying JavaScript

Gulpfile.js
!

var gulp
= require('gulp');
var uglify = require('gulp-uglify');
!

gulp.task('minify', function() {
gulp.src('app.js')
.pipe(uglify())
.pipe(gulp.dest('out'));
});

Gulpfile.js
!

var gulp
= require('gulp');
var uglify = require('gulp-uglify');
!

gulp.task('minify', function() {
gulp.src('app.js')
.pipe(uglify())
.pipe(gulp.dest('out'));
});

Gulpfile.js
!

var gulp
= require('gulp');
var uglify = require('gulp-uglify');
!

gulp.task('minify', function() {
gulp.src('app.js')
.pipe(uglify())
.pipe(gulp.dest('out'));
});

Gulpfile.js
!

var gulp
= require('gulp');
var uglify = require('gulp-uglify');
!

gulp.task('minify', function() {
gulp.src('app.js')
.pipe(uglify())
.pipe(gulp.dest('out'));
});

Gulpfile.js
!

var gulp
= require('gulp');
var uglify = require('gulp-uglify');
!

gulp.task('minify', function() {
gulp.src('app.js')
.pipe(uglify())
.pipe(gulp.dest('out'));
});

Uglify
dist/
app.js

app.js

gulp.src

File System

gulp.watch(glob, fn);
!
!

gulp.task(lint-watcher, function() {
gulp.watch('js/**/*.js', [jshint]);
});

Run a function when the glob changes

Youre a Gulp pro now!

task
src

dest

watch

Code defining your tasks,


which loads & uses plugins
Gulpfile.js

Gulpfile.js

Running Gulp

$ gulp <mytask>

Run from the terminal or


command prompt

Task dependencies run in parallel

We need to be careful. If a clean task was running here, it might


finish last, deleting all the output. Whoops!

Task dependency chains

Task automation with Grunt

How are they different?


!

Based on files
Configuration over code

Based on streams
Code over configuration

Before you get started


Prerequisites

Download and install NodeJS

Available for all major operating systems

Install Grunt CLI as a global utility, run from any path.

$ npm install -g grunt-cli

Grunt in a nutshell

Install CLI

Create
package
file

Install
dependent
packages

Config
tasks in
Gruntfile.js

Load
tasks into
Grunt

Register
custom
tasks

Create your package.json file

$ npm init

Prompts for your author, package


name and the basics.

Install Grunt locally to the package.json file

$ npm install grunt save-dev


save-dev for
development

grunt vs grunt-cli
!

In a typical Grunt-based dev workflow, the CLI is installed once per


system, while the lib is installed once per project.
!

The relatively high proportion of CLI installs implies that many devs are
using Continuous Integration, where both the CLI and core lib get installed
every time.

Install package dependencies


$ npm install grunt-contrib-jshint grunt-contrib-cssmin save-dev

Install one or more tasks

contrib tasks are officially


maintained

package.json to manage dependencies

Gruntfile.js
Summary

Your task configuration


JSON Style
Load the plugins

Grunt overview
Task configuration
Task loading
Register custom tasks
Grunt wrapper

Grunt overview
Grunt wrapper
Task configuration
Task loading
Register custom tasks

Task configuration

Task configuration

Gruntfile.js

Load Tasks

Load npm tasks into


Grunt

Task names

Custom tasks

Tasks to run
Custom task name

Running individual Grunt tasks:

$ grunt task

Sample output from


generator-webapp

Evaluate. Choose the tool youre most comfortable with.

Evaluate. Choose the tool youre most comfortable with.

How are they different?

Based on files
Configuration over code
Independent tasks, strong
I/O connection
3600 packages
> 2 years old
Widely used

Based on streams
Code over configuration
Tasks run a sequence of
methods. Less I/O
800 plugins
> 1 year old
Increasingly used

npm as a front-end task runner?

npm run scripts


package.json
"scripts": {
"build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js",
"build-css": "cat static/pages/*.css tabs/*/*.css",
"build": "npm run build-js && npm run build-css",
"watch-js": "watchify browser/main.js -o static/bundle.js -dv",
"watch-css": "catw static/pages/*.css tabs/*/*.css -o static/bundle.css -v",
"watch": "npm run watch-js & npm run watch-css",
"start": "node server.js",
}

Start a server

Watch task

http://substack.net/task_automation_with_npm_run

Build & minify JS

Build tool helpers

Gulp DevTools

Gulp App

Grunt DevTools

Editors + Web Starter Kit

Gulp Recipes
!

https://github.com/gulpjs/gulp/tree/master/docs/recipes

Useful build tasks

grunt-concurrent (concurrency is default in Gulp)


!
!
!
!

Speed up build time by concurrently running


tasks like Sass and Coffee.

grunt-newer (or gulp-changed)


!
!
!

Only run tasks on source files that have been


modified since the last run.

Sizing up the average Bootstrap page


ORIGINAL STYLES

MINIFIED

UNCSS + MINIFICATION

120KB 110KB 11KB


(1) ~ 90% improvement
(2) Based on average improvements reported by UnCSS users

Optimize Critical Path CSS

Just render
visible content!
Dont render
the whole
page!

1. One RTT render for above the fold


2. Fast server response. No redirects
3. Must optimize critical rendering path
a. Inline critical CSS
b. Remove any blocking JavaScript

New Critical-path CSS tools


Critical
$ npm install --save-dev critical

which builds on Penthouse <333


$ npm install --save-dev penthouse

CriticalCSS by FilamentGroup is also solid


$ npm install --save-dev criticalcss

Criticals workflow

Source

Extract
stylesheets
!

(Oust)

Generate Critical
path CSS for a
viewport

Inline styles in
<head>

(Penthouse)

(inline-critical)

Wrap link tags in


<noscript> for
users with JS
disabled

Inject loadCSS &


async load
site.css

Output

Vulcanize

Working with Web Components? Concatenates HTML Imports into a single file
grunt-vulcanize

gulp-vulcanize

https://www.polymer-project.org/articles/concatenating-web-components.html

Continuous performance
benchmarking

WebPageTest CLI
Install
$ npm install -g webpagetest

Usage
$ webpagetest test <url>
$ webpagetest test <url> -- wait
8000

Jenkins

Grunt-PerfBudget

Install
Budget in ms for render, KB for page weight

$ npm install grunt-perfbudget

2
3

GitHub PRs will show the build failed


http://cognition.happycog.com/article/grunt-plugins-reviewed

Over budget? Task fails and reports an error.

Smarter package
management

npm as a front-end package manager?

Will we see a
shift in 2015?

package.json

"dependencies": {
"bootstrap": "^3.3.0",
"jquery": "^2.1.1",
"underscore": "^1.7.0"
},

BrowserifySearch.org
Find packages that work
in both the client and
server-side easily

Bower

Front-end package management for today

Old way of doing things


!

1. jQuery is out of date. Lets update!


2. Open up the site
3. Download the lib
4. Copy from ~/Downloads
5. Paste to app folder
6. Wire in with script tags

Installing jQuery with Bower

$ bower install jquery

Newer hotness

Package manager for the web

Download and install NodeJS

Available for all major operating systems

Install Bower as a global utility

$ npm install -g bower

Find packages

Package manager for the web

Find a library

$ bower search <thing>


!

Lists all the available libraries by that name

Install packages
Package manager for the web

Install a library

$ bower install <thing>


!

Yeoman

Yeoman kickstarts new projects,


prescribing best practices and tools to
help you stay productive
yeoman.io

Scaffolding a project quickly

Subtitle

Yo

Grunt / Gulp

Bower

Scaffolding

Build system

Package
manager

Generators
Over 1000 available today
Anyone can write them

Subtitle

Subtitle

Installation
Download and install NodeJS

Available for all major operating systems

Install Yo as a global utility

$ npm install -g yo

Install a generator
!
!

$ npm install -g generator-webapp


!

Install a generator
!
!

$ npm install -g generator-gulp-webapp


!

Usage
!
!

$ yo webapp

Yo!

Subtitle

Subtitle

Remembers what you like to use


!

$ yo
!

[?]$What$would$you$like$to$do?$
$!$$Install$a$generator$
$$Run$the$Angular$generator$
$$Run$the$Backbone$generator$$
$$Run$the$Blog$generator$
$$Run$the$jQuery$generator$
$$Run$the$Gruntfile$generator$
(Move$up$and$down$to$reveal$more$choices)

<Web Starter Kit>

github.com/google/web-starter-kit

> gulp pagespeed

Choose tools youll use. Add tools &


abstractions when they improve your
productivity.

Trends?
2015

2014

npm for front-end


package management *
+ Browserify
ES6 Modules
(transpiled)
Angular 2.0, Ember

Custom Elements &


HTML Imports will be big.
Web Components,
virtual-dom / React
+ persistent data structures

LibSass, PostCSS

* If were able to address outstanding issues making Bower a better choice for today

#ToolsNotRules
!

Create
Consume
Refine
Relax

<thank-you>
+AddyOsmani
@addyosmani

You might also like