Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Automation for Site Performance - Web Directions 2015

Automation for Site Performance - Web Directions 2015

Automating for site performance, presented at Web Directions South 2015 in Sydney, NSW, Australia on October 29th.

Kitt Hodsden

October 29, 2015
Tweet

More Decks by Kitt Hodsden

Other Decks in Technology

Transcript

  1. Kitt Hodsden • @kitt • http://ki.tt/wd15 1 Automation for Site

    Performance Kitt Hodsden / @kitt slides here
  2. Kitt Hodsden • @kitt • http://ki.tt/wd15 10 Determine key metrics

    Establish a baseline Make a change Measure effects
  3. Kitt Hodsden • @kitt • http://ki.tt/wd15 11 Determine key metrics

    Establish a baseline Make a change Measure effects
  4. Kitt Hodsden • @kitt • http://ki.tt/wd15 13 40% will abandon

    a website that takes more than 3 seconds to load.
  5. Kitt Hodsden • @kitt • http://ki.tt/wd15 53 $ npm init

    This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sane defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (dev) performance version: (1.0.0) description: Automating front-end performance metrics and improvements entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to .../e4e/dev/package.json: ...
  6. Kitt Hodsden • @kitt • http://ki.tt/wd15 54 $ npm init

    This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sane defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (dev) performance version: (1.0.0) description: Automating front-end performance metrics and improvements entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to .../e4e/dev/package.json: ...
  7. Kitt Hodsden • @kitt • http://ki.tt/wd15 55 { "name": "performance",

    "version": "1.0.0", "description": "Automating front-end performance”, "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } This is what a package.json file looks like
  8. Kitt Hodsden • @kitt • http://ki.tt/wd15 57 { "engines": {

    "node": ">= 4.1.0" }, "devDependencies": { "grunt": "~0.4.5", "grunt-contrib-jshint": "~0.11.3", "grunt-contrib-watch": "~0.6.1", } } This is what a package.json file looks like
  9. Kitt Hodsden • @kitt • http://ki.tt/wd15 58 { "engines": {

    "node": ">= 4.1.0" }, "devDependencies": { "grunt": "~0.4.5", "grunt-contrib-jshint": "~0.11.3", "grunt-contrib-watch": "~0.6.1", } } This is what a package.json file looks like
  10. Kitt Hodsden • @kitt • http://ki.tt/wd15 59 $ npm install

    With a package.json file, you can install the needed packages easily.
  11. Kitt Hodsden • @kitt • http://ki.tt/wd15 60 $ npm install

    No -g here! With a package.json file, you can install the needed packages easily.
  12. Kitt Hodsden • @kitt • http://ki.tt/wd15 61 $ ls Gemfile

    README.txt fonts node_modules tpl Gemfile.lock config.rb img package.json widgets Gruntfile.js css js scss
  13. Kitt Hodsden • @kitt • http://ki.tt/wd15 Check dependencies into the

    repo? http://addyosmani.com/blog/checking-in-front-end-dependencies/ http://redotheweb.com/2013/09/12/should-you-commit-dependencies.html 62 Total sidebar on checking dependencies into the repo or not
  14. Kitt Hodsden • @kitt • http://ki.tt/wd15 63 module.exports = function(grunt)

    { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %> <%="yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } }); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); };
  15. Kitt Hodsden • @kitt • http://ki.tt/wd15 64 module.exports = function(grunt)

    { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %> <%="yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } }); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); }; A basic Gruntfile.js file
  16. Kitt Hodsden • @kitt • http://ki.tt/wd15 65 module.exports = function(grunt)

    { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %> <%="yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } }); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); }; A basic Gruntfile.js file
  17. Kitt Hodsden • @kitt • http://ki.tt/wd15 66 module.exports = function(grunt)

    { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %> <%="yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } }); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); }; A basic Gruntfile.js file
  18. Kitt Hodsden • @kitt • http://ki.tt/wd15 68 grunt.loadNpmTasks('grunt-aws-s3'); grunt.loadNpmTasks('grunt-cafe-mocha'); grunt.loadNpmTasks('grunt-contrib-clean');

    grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-jade'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-imagemin');
  19. Kitt Hodsden • @kitt • http://ki.tt/wd15 69 grunt.loadNpmTasks('grunt-aws-s3'); grunt.loadNpmTasks('grunt-cafe-mocha'); grunt.loadNpmTasks('grunt-contrib-clean');

    grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-jade'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-imagemin'); grunt.loadNpmTasks('grunt-contrib-sass'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-env'); grunt.loadNpmTasks('grunt-favicons'); grunt.loadNpmTasks('grunt-html-validation'); grunt.loadNpmTasks('grunt-mkdir');
  20. Kitt Hodsden • @kitt • http://ki.tt/wd15 72 module.exports = function(grunt)

    { // load grunt tasks matching ['grunt-*', '@*/grunt-*'] patterns require('load-grunt-tasks')(grunt); grunt.initConfig({ ...
  21. Kitt Hodsden • @kitt • http://ki.tt/wd15 73 module.exports = function(grunt)

    { // load grunt tasks matching ['grunt-*', '@*/grunt-*'] patterns require('load-grunt-tasks')(grunt); grunt.initConfig({}); grunt.registerTask('default', []); }
  22. Kitt Hodsden • @kitt • http://ki.tt/wd15 77 devperf: { options:

    { urls: [ 'http://localhost:8000' ] } } … grunt.registerTask('pe', ['devperf']);
  23. Kitt Hodsden • @kitt • http://ki.tt/wd15 79 … devperf: {

    options: { urls: [ 'http://grunt.wtf/' ], numberOfRuns: 5, openResults: true, resultsFolder: './devperf', phantomasOptions: { 'film-strip': true } } } … grunt.registerTask('pe', ['devperf']);
  24. Kitt Hodsden • @kitt • http://ki.tt/wd15 Remove HTML Comments 89

    https://github.com/gruntjs/grunt-contrib-htmlmin
  25. Kitt Hodsden • @kitt • http://ki.tt/wd15 91 … htmlmin: {

    dist: { options: { removeComments: true, collapseWhitespace: true }, files: { 'dist/index.html': 'src/index.html', 'dist/contact.html': 'src/contact.html' } }, dev: { files: { 'dist/index.html': 'src/index.html', 'dist/contact.html': 'src/contact.html' } } } … grunt.registerTask(‘comments-be-gone‘, ['htmlmin']);
  26. Kitt Hodsden • @kitt • http://ki.tt/wd15 92 Determine key metrics

    Establish a baseline Make a change Measure effects
  27. Kitt Hodsden • @kitt • http://ki.tt/wd15 93 Determine key metrics

    Establish a baseline Make a change Measure effects
  28. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install @micahgodbolt/grunt-phantomcss --save-dev

    https://github.com/micahgodbolt/grunt-phantomcss https://github.com/Huddle/PhantomCSS 102 Make sure you haven’t removed things you need
  29. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install @micahgodbolt/grunt-phantomcss --save-dev

    https://github.com/micahgodbolt/grunt-phantomcss https://github.com/Huddle/PhantomCSS 103 We can install from github
  30. Kitt Hodsden • @kitt • http://ki.tt/wd15 105 grunt-cssstats configuration https://github.com/cssstats/grunt-cssstats

    phantomcss: { desktop: { options: { screenshots: 'test/visual/desktop/', results: 'results/visual/desktop', viewportSize: [1024, 768] }, src: [ 'test/visual/**.js' ] }, mobile: { options: { screenshots: 'test/visual/mobile/', results: 'results/visual/mobile', viewportSize: [320, 480] }, src: [ 'test/visual/**.js' ] } }
  31. Kitt Hodsden • @kitt • http://ki.tt/wd15 106 grunt-cssstats configuration https://github.com/cssstats/grunt-cssstats

    phantomcss: { desktop: { options: { screenshots: 'test/visual/desktop/', results: 'results/visual/desktop', viewportSize: [1024, 768] }, src: [ 'test/visual/**.js' ] }, mobile: { options: { screenshots: 'test/visual/mobile/', results: 'results/visual/mobile', viewportSize: [320, 480] }, src: [ 'test/visual/**.js' ] } }
  32. Kitt Hodsden • @kitt • http://ki.tt/wd15 107 grunt-cssstats configuration https://github.com/cssstats/grunt-cssstats

    casper.thenOpen('http://grunt.wtf/web-directions') .then(function() { phantomcss.screenshot('#region-branding', 'region-branding'); }) .then(function now_check_the_screenshots() { phantomCSS.compareAll(); });
  33. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-cssstats --save-dev

    108 https://github.com/cssstats/grunt-cssstats Look at the site’s CSS statistics
  34. Kitt Hodsden • @kitt • http://ki.tt/wd15 115 grunt-cssstats configuration https://github.com/cssstats/grunt-cssstats

    cssstats: { dev: { options: {}, files: { 'stats/css-stats.json': ['css/example.css'] }, } } … grunt.registerTask('stats', ['cssstats']);
  35. Kitt Hodsden • @kitt • http://ki.tt/wd15 116 grunt-cssstats configuration https://github.com/cssstats/grunt-cssstats

    cssstats: { dev: { options: { safe: false }, // Barf on invalid CSS files: { 'stats/cssstats-dev.json': ['app/styles/main.css'] } }, prod: { files: { 'stats/cssstats.json': ['dist/styles.css'] } } }
  36. Kitt Hodsden • @kitt • http://ki.tt/wd15 117 grunt-cssstats configuration https://github.com/cssstats/grunt-cssstats

    cssstats: { dev: { options: { safe: false }, // Barf on invalid CSS files: { 'stats/cssstats-dev.json': ['app/styles/main.css'] } }, prod: { files: { 'stats/cssstats.json': ['dist/styles.css'] } } }
  37. Kitt Hodsden • @kitt • http://ki.tt/wd15 121 Determine key metrics

    Establish a baseline Make a change Measure effects
  38. Kitt Hodsden • @kitt • http://ki.tt/wd15 122 Determine key metrics

    Establish a baseline Make a change Measure effects
  39. Kitt Hodsden • @kitt • http://ki.tt/wd15 125 grunt.initConfig({ montage: {

    iconaroo: { files: { "images/sprites": [ "images/icons/*.png" ] }, options: { size: 32, outputImage: "sprite-icons.png", outputStylesheet: "sprite-icons.css" } } } }); Sample grunt-montage configuration
  40. Kitt Hodsden • @kitt • http://ki.tt/wd15 127 imagemin: { prod:

    { files: [{ expand: true, cwd: 'imgs-src/', src: ['**/*.{png,jpg,gif}'], dest: 'imgs/' }] } }
  41. Kitt Hodsden • @kitt • http://ki.tt/wd15 129 grunt.initConfig({ svgmin: {

    // Task options: { // Configuration that will be passed directly to SVGO plugins: [ { removeViewBox: false }, { removeUselessStrokeAndFill: false } ] }, dist: { // Target files: [{ // Dictionary of files expand: true, // Enable dynamic expansion. cwd: 'img/src', // Src matches are relative to this path. src: ['**/*.svg'], // Actual pattern(s) to match. dest: 'img/', // Destination path prefix. ext: '.min.svg' // Dest filepaths will have this extension. // ie: optimise img/src/branding/logo.svg and store it in img/branding/logo.min.svg }] } }); grunt.loadNpmTasks('grunt-svgmin'); grunt.registerTask('default', ['svgmin']); Sample grunt-svgmin configuration
  42. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-responsive-images --save-dev

    131 Responsive images by resizing https://github.com/andismith/grunt-responsive-images
  43. Kitt Hodsden • @kitt • http://ki.tt/wd15 132 grunt.initConfig({ responsive_images: {

    myTask: { options: { sizes: [{ width: 320, height: 240 },{ name: 'medium', width: 640 },{ name: "large", width: 1024, suffix: "_x2", quality: 60 }] }, files: [{ expand: true, src: ['original/**.{jpg,gif,png}'], cwd: 'images/', custom_dest: 'images/{%= width %}/' }] } }, }); Sample grunt-responsive-images configuration
  44. Kitt Hodsden • @kitt • http://ki.tt/wd15 133 <img src="/images/medium/cat.jpg" alt="cat"

    srcset="/images/small/cat.jpg 320w, /images/large/cat.jpg 1024w"> Using img srcset
  45. Kitt Hodsden • @kitt • http://ki.tt/wd15 134 <img src="/images/medium/cat.jpg" alt="cat"

    srcset="/images/small/cat.jpg 320w, /images/medium/cat.jpg 640w, /images/large/cat.jpg 1024w"> Using img srcset
  46. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-grunticon --save-dev

    135 SVG with PNG fallbacks https://github.com/filamentgroup/grunticon
  47. Kitt Hodsden • @kitt • http://ki.tt/wd15 Him: “Hey, I have

    two megs of webfonts…” Me: “…” Him: “Is this okay?” 138
  48. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-ziti —save-dev

    https://github.com/caiguanhao/grunt-ziti 141 Reduce font file sizes
  49. Kitt Hodsden • @kitt • http://ki.tt/wd15 142 grunt.initConfig({ ziti: {

    subset_only: { options: { font: { chars: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', }, convert: false }, files: { ‘assets/fonts/my.ttf': [ ‘src/fonts/original.ttf' ] } } } }); grunt.loadNpmTasks('grunt-ziti'); grunt.registerTask('fontsubset', ['ziti']); Sample grunt-ziti configuration
  50. Kitt Hodsden • @kitt • http://ki.tt/wd15 150 The API key

    is provisioned for up to 200 page loads per day … sufficient for most low-volume use cases and for building a proof-of- concept for larger testing
  51. Kitt Hodsden • @kitt • http://ki.tt/wd15 154 perfbudget: { default:

    { options: { url: ‘http://example.io/', key: 'PUT_YOUR_API_KEY_HERE' } } } … grunt.registerTask('budg', ['perfbudget']);
  52. Kitt Hodsden • @kitt • http://ki.tt/wd15 155 perfbudget: { default:

    { options: { url: 'http://fromthemiddle.io/', key: 'thisismykey', wptInstance: 'ec2.us-west-2.amazonaws.com', location: 'us-west-2_wptdriver', pollResults: 10, connectivity: '3G', runs: 1, timeout: 240 } } }
  53. Kitt Hodsden • @kitt • http://ki.tt/wd15 156 perfbudget: { default:

    { options: { url: 'http://fromthemiddle.io/', key: 'thisismykey', wptInstance: 'ec2.us-west-2.amazonaws.com', location: 'us-west-2_wptdriver', pollResults: 10, connectivity: '3G', runs: 1, timeout: 240 } } }
  54. Kitt Hodsden • @kitt • http://ki.tt/wd15 157 perfbudget: { default:

    { options: { url: 'http://fromthemiddle.io/', key: 'thisismykey', wptInstance: 'ec2.us-west-2.amazonaws.com', location: 'us-west-2_wptdriver', pollResults: 10, connectivity: '3G', runs: 1, timeout: 240 } } }
  55. Kitt Hodsden • @kitt • http://ki.tt/wd15 159 perfbudget: { default:

    { options: { url: 'http://fromthemiddle.io/', … connectivity: '3G', timeout: 240, budget: { render: '3000', SpeedIndex: '7500', visualComplete: '6000' } } } }
  56. Kitt Hodsden • @kitt • http://ki.tt/wd15 164 // bring up

    the login screen navigate https://grunt.wtf/user // log in setValue name=user testuser setValue name=password testpassword submitFormname=user-login
  57. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-shell --save-dev

    166 http://example.com/ Installing the grunt shell package to get to everything else
  58. Kitt Hodsden • @kitt • http://ki.tt/wd15 167 function log(err, stdout,

    stderr, cb) { console.log(stdout); cb(); } grunt.initConfig({ shell: { dirListing: { command: 'ls', options: { callback: log } } } });
  59. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-mocha --save-

    dev 168 http://example.com/ Running client side tests
  60. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-mocha-test --

    save-dev 169 http://example.com/ Running server side tests
  61. Kitt Hodsden • @kitt • http://ki.tt/wd15 npm install grunt-wpt --save-dev

    174 https://github.com/sideroad/grunt-wpt https://github.com/sideroad/grunt-wpt-page
  62. Kitt Hodsden • @kitt • http://ki.tt/wd15 175 wpt: { options:

    { url: 'http://fromthemiddle.io/', server: 'ec2.us-west-2.amazonaws.com', dest: 'wpt/' }, ftm: { options: { server: 'http://ec2.us-west-2.amazonaws.com', url: ['http://fromthemiddle.io/'] }, dest: 'wpt/', } } … grunt.registerTask('wptrun', ['wpt']);
  63. Kitt Hodsden • @kitt • http://ki.tt/wd15 182 $ cat tests.json

    [ { "name": "From the Middle", "url": "http://fromthemiddle.io/", "type": "home" }, { "name": "Kitt Hodsden", "url": "https://kitt.hodsden.org/", "type": "away" } ]
  64. Kitt Hodsden • @kitt • http://ki.tt/wd15 186 Determine key metrics

    Establish a baseline Make a change Measure effects
  65. Kitt Hodsden • @kitt • http://ki.tt/wd15 187 Determine key metrics

    Establish a baseline Make a change Measure effects
  66. Kitt Hodsden • @kitt • http://ki.tt/wd15 188 Determine key metrics

    Establish a baseline Make a change Measure effects Announce effects
  67. Kitt Hodsden • @kitt • http://ki.tt/wd15 203 docker pull sitespeedio/graphite

    docker pull grafana/grafana docker pull sitespeedio/sitespeed.io
  68. Kitt Hodsden • @kitt • http://ki.tt/wd15 205 https://www.sitespeed.io/documentation/performance-dashboard/ $ sudo

    mkdir -p /data/graphite/storage/whisper $ sudo htpasswd -c /path/to/.htpasswd YOUR_USERNAME $ sudo docker run -d \ --name graphite \ -p 8080:80 \ -p 2003:2003 \ --restart="always" \ -v /data/graphite/storage/whisper:/opt/graphite/storage/whisper \ -v /path/to/.htpasswd:/etc/nginx/.htpasswd \ sitespeedio/graphite
  69. Kitt Hodsden • @kitt • http://ki.tt/wd15 207 $ sudo mkdir

    -p /data/grafana $ sudo docker run -d -p 3000:3000 \ -v /data/grafana:/var/lib/grafana \ -e "GF_SECURITY_ADMIN_USER=myuser" \ -e "GF_SECURITY_ADMIN_PASSWORD=MY_SUPER_STRONG_PASSWORD" \ --name grafana \ --restart="always" \ grafana/grafana
  70. Kitt Hodsden • @kitt • http://ki.tt/wd15 209 $ sudo mkdir

    -p /data/grafana $ sudo docker run -d -p 3000:3000 \ -v /data/grafana:/var/lib/grafana \ -e "GF_SECURITY_ADMIN_USER=myuser" \ -e "GF_SECURITY_ADMIN_PASSWORD=MY_SUPER_STRONG_PASSWORD" \ --name grafana \ --restart="always" \ grafana/grafana
  71. Kitt Hodsden • @kitt • http://ki.tt/wd15 211 # ifconfig docker0

    Link encap:Ethernet HWaddr 02:42:62:d5:83:18 inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:62ff:fed5:8318/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:419578 errors:0 dropped:0 overruns:0 frame:0 TX packets:399294 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:66734551 (66.7 MB) TX bytes:834474594 (834.4 MB)
  72. Kitt Hodsden • @kitt • http://ki.tt/wd15 212 $ docker run

    --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u http://fromthemiddle.io -b firefox -n 1 --graphiteHost 172.17.42.1 --graphiteNamespace sitespeed.io
  73. Kitt Hodsden • @kitt • http://ki.tt/wd15 213 $ docker run

    --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u http://fromthemiddle.io -b firefox -n 1 --graphiteHost 172.17.42.1 --graphiteNamespace sitespeed.io
  74. Kitt Hodsden • @kitt • http://ki.tt/wd15 214 $ docker run

    --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u http://fromthemiddle.io -b firefox -n 1 --graphiteHost 172.17.42.1 --graphiteNamespace sitespeed.io
  75. Kitt Hodsden • @kitt • http://ki.tt/wd15 228 SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 0,15,30,45

    * * * * docker run --privileged --rm -v /sitespeed.io:/ sitespeed.io sitespeedio/sitespeed.io sitespeed.io -f urls.txt -b firefox -n 11 --connection cable -r /tmp/ --graphiteHost YOUR_GRAPHITE_HOST --seleniumServer http://127.0.0.1:4444/wd/hub >> /tmp/sitespeed-run.txt 2>&1 # YOUR_GRAPHITE_HOST = likely your IP address if you docker’d # -f urls.txt = list of URLs to analyze # -n 11 = depth to go, use -n for single page
  76. Kitt Hodsden • @kitt • http://ki.tt/wd15 Worth looking at: https://github.com/andyshora/grunt-yslow

    https://github.com/jrcryer/grunt-pagespeed https://github.com/addyosmani/psi/ http://perf-tooling.today/tools 231
  77. Kitt Hodsden • @kitt • http://ki.tt/wd15 266 $ vi ~/.ssh/authorized_keys

    dd # delete the first line [esc] # trigger the vi command sequence :wq # save the file and quit
  78. Kitt Hodsden • @kitt • http://ki.tt/wd15 267 sudo vi /var/www/webpagetest/www/settings/settings.ini

    # update publishTo with ec2 hostname # update ec2 = 0 # update ec2_locations = 0 # add EC2.us-west-2.securityGroup line from sample # add EC2.us-west-2.subnetId line from sample #
  79. Kitt Hodsden • @kitt • http://ki.tt/wd15 268 sudo vi /var/www/webpage/test/www/settings/keys.ini

    [server] secret=addarandomstringhere key=addakeyhere [addakeyhere] description=Web UI ;[email protected] limit=0 [thisisyourapikey] description=API Key ;[email protected] limit=0
  80. Kitt Hodsden • @kitt • http://ki.tt/wd15 269 $ cd /var/www/webpage/test/www/settings/

    $ sudo cp locations.ini.EC2-sample locations.ini # delete extra locations # update key values to your thisisyourkey value
  81. Kitt Hodsden • @kitt • http://ki.tt/wd15 272 EC2 server key

    in settings.ini (more complicated to set up, better automation management)