MIW

FrontEnd Optimization Tools

FrontEnd Optimization

How fast is fast?

Delay User reaction
0-100ms Instant
100-300ms Feels sluggish
300-1000ms Machine is working...
1 s+ Mental switch
10s+ I'll come back later

How many resources?

Resources Hell

Request size

Request number

Optimization Techniques

Code checkers

Ensures code style in dev team

Prevents common mistakes

Guarantees minimum quality

  • ESLint | JSHint | JSLint | JSCS
  • cssLint

Wire Dependencies

Reduce project code/size

Free your project from vendor code

Manage dependencies

  • bower
  • JSPM
  • npm

Compilers/Transpilers

Code in your favourite JS flavour

Use bleeding Edge features

Use improved language

  • CoffeScript | ES6 | Typescript => ES5
  • SASS | LESS -> CSS
  • Jade, Handlebars, underscore => HTML | JS

Reduce requests

Concat code

  • JS, CSS

Concat images

  • PNG Sprites
  • SVG Sprites

Cache

  • HMTL: no-cache
  • JS, CSS, images: +1 year
  • Assets versioning

Reduce size

  • HTMLmin
  • CSSmin
  • Uglify
  • GZip (text files)

Workflow

Speeds up develop time

Reduce mistakes

Focus on things that matters

  • Open browser
  • Setup server
  • Watch file changes
  • LiveReload

Continuous Integration

Integrate soon and often

Run automated jobs

Generate reports

Communicate results

  • Travis
  • CodeShip
  • Coveralls
  • CodeClimate

Automating Tools

Automate repetitive tasks

 

Speedup development process

 

Focus on things that matters

Grunt/Gulp

Automation tools

Node based

Community support

Tons of plugins

Grunt: Add plugin

Install

 

 

Setup

 

 

 

Run task

grunt install grunt-contrib-concat --save-dev
module.exports = function(grunt) {

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    grunt.initConfig({
    
        concat: {
          js: {
            src: ['src/app/**/*.js'],
            dest: 'dist'
          }
        }
    
    });

});
grunt concat:js

Grunt: Write custom task

grunt.registerTask('serve', 'Task description', function(target) {
    if (target === 'dist' || grunt.option('custom') === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }
    
    grunt.task.run([
      'clean:server',
      'wiredep',
      'ngconstant',
      'includeSource:server',
      'concurrent:server',
      'autoprefixer',
      'connect:livereload',
      'watch'
    ]);
});
grunt serve
grunt serve:dist
grunt serve --custom=dist

task name

task param

sub tasks

task param

task option

task name

task option

Code time!

Add following task to the funcy project

Testing

Unit Tests

Test isolated componentes/modules

 

Boundary Test Cases

 

Mock/stub dependencies

Integration Tests

Test collaboration between componentes/modules

 

Functional documentation

Tools

Sinon.js

Code time!

  • Setup test project with mocha
  • Create a testSuite for a simple calculator
    • calc.add(a, b)
    • calc.sub(a, b)
  • Add grunt task to run tests
  • Develop calc module

Functional Test

Simulates user interaction

 

Tests user functionalities

 

Checks whole system

Tools

Code time!

Develop a e2e login test

  • Go to login page
  • Write username/password
  • Submit
  • Wait for next page

Tips

Self contained

Independent

Descriptive

PhantomJS?

Async tests

PageObject Pattern

thanks!