Tag Archives: code

Exploring Animation And Interaction Techniques With WebGL (A Case Study)

Two years ago, I decided to start a series of short WebGL experiments on Codepen. Earlier this year, I finally found the time to compile them all together on a single website named “Moments of Happiness”. Since its incarnation, I’ve found ways to explore and learn different animation and interaction techniques, which I’ve implemented in these interactive toys.

Exploring Animation And Interaction Techniques With WebGL (A Case Study)

As you’ll see, the gameplay is very different in each one, but all of the experiments share one principle: The behavior of each character responds programmatically to user input. No precalculated animation — every movement is defined at runtime. Breathing life into these characters with only a few lines of code was the main challenge.

The post Exploring Animation And Interaction Techniques With WebGL (A Case Study) appeared first on Smashing Magazine.

View this article:  

Exploring Animation And Interaction Techniques With WebGL (A Case Study)

Hybrid Apps And React Native: A Time To Transition?

Accomplished musicians often talk about how, at certain moments in their careers, they had to unlearn old habits in order to progress. This process often causes them to regress in performance while they adjust to an ultimately better method.

Hybrid Apps And React Native: A Time To Transition?

Once the new approach is integrated, they are able to reach new heights that would not have been possible with their previous techniques.

The post Hybrid Apps And React Native: A Time To Transition? appeared first on Smashing Magazine.

This article:  

Hybrid Apps And React Native: A Time To Transition?

How To Build A SpriteKit Game In Swift 3 (Part 1)

Have you ever wondered what it takes to create a SpriteKit game from beginning to beta? Does developing a physics-based game seem daunting? Game-making has never been easier on iOS since the introduction of SpriteKit.

How To Build A SpriteKit Game In Swift 3 (Part 1)

In this three-part series, we will explore the basics of SpriteKit. We will touch on SKPhysics, collisions, texture management, interactions, sound effects, music, buttons and SKScenes. What might seem difficult is actually pretty easy to grasp. Stick with us while we make RainCat.

The post How To Build A SpriteKit Game In Swift 3 (Part 1) appeared first on Smashing Magazine.

View original:

How To Build A SpriteKit Game In Swift 3 (Part 1)

Tips and tactics for A/B testing on AngularJS apps

Reading Time: 8 minutes

Alright, folks, this week we’re getting technical.

This post is geared toward Web Developers who’re working in conversion optimization, specifically those who are testing on AngularJS (or who are trying to test on AngularJS).

Angular, while allowing for more dynamic web applications, presents a problem for optimization on the development side.

It basically throws a wrench in the whole “I’m trying to show you a variation instead of the original webpage without you knowing it’s a variation”-thing for reasons I’ll get into in a minute.

At WiderFunnel, our Dev team has to tackle technical obstacles daily: many different clients means many different frameworks and tools to master.

Recently, the topic of How the heck do you test on Angular came up and Tom Davis, WiderFunnel Front End Developer, was like, “I can help with that.”

So here we go. Here are the tips, tricks, and workarounds we use to test on AngularJS.

Let’s start with the basics:

What is AngularJS?

Angular acts as a Javascript extension to HTML, running in most cases on the client-side (through the browser). Because HTML isn’t a scripting language (it doesn’t run code), it’s limited. Angular allows for more functionality that HTML doesn’t have. It provides a framework to develop apps that are maintainable and extendable, while allowing for features such as single page navigation, rich content, and dynamic functionality.

Note: You can mimic Angular with plain Javascript, however, Angular provides a lot of functionality that a Developer would otherwise have to build themselves.

Why is AngularJS popular?

The real question here is why are JS front-end frameworks and libraries popular? Angular isn’t the only framework you can use, of course: there’s EmberJS, React.js, BackBone etc., and different Developers prefer different frameworks.

But frameworks, in general, are popular because they offer a means of providing a rich user experience that is both responsive and dynamic. Without Angular, a user clicks a button or submits a form on your site, the browser communicates with the server, and the server provides entirely new HTML content that then loads in the browser.

When you’re using Angular, however, a user clicks a button or submits a form and the browser is able to build that content itself, while simultaneously performing server tasks (like database submissions) in the background.

For example, let’s think about form validations.

No Angular:

A user submits a form to create an account on a site. The browser talks to the server and the server says, “There’s a problem. We can’t validate this form because this username already exists.” The server then has to serve up entirely new HTML content and the browser re-renders all of that new content.

This can lead to a laggy, cumbersome user experience, where changes only happen on full page reloads.

With Angular:

A user submits a form to create an account on a site. The browser talks to the server via JSON (a collection of data) and the server says, “There’s a problem. We can’t validate this form because this username already exists.” The browser has already loaded the necessary HTML (on the first load) and then simply fills in the blanks with the data it gets back from the server.

Disclaimer: If you don’t have a basic understanding of web development, the rest of this post may be tough to decipher. There is a Glossary at the end of this post, if you need a quick refresher on certain terms.

Why it can be tricky to test on Angular apps

As mentioned above, Angular acts as an HTML extension. This means that the normal behaviors of the DOM* are being manipulated.

Angular manipulates the DOM using two-way data binding. This means that the content in the DOM is bound to a model. Take a look at the example below:

Testing on Angular_2-way-data-binding

The class “ng-binding” indicates that the H1 element is bound to a model, in this case $scope.helloWorld. In Angular, model data is referred to in an object called $scope. Any changes to the input field value will change helloWorld in the $scope object. This value is then propagated down to the H1 text.

This means that, if you make any changes to the H1 element through jQuery or native JS, they will essentially be overridden by $scope. This is not good in a test environment: you cannot guarantee that your changes will show up when you intend them to, without breaking the original code.

Laymen’s terms: $scope.helloWorld is bound to the H1 tag, meaning if anything in the variable helloWorld changes, the H1 element will change and vice versa. That’s the power of Angular.

Typically, when you’re testing, you’re making changes to the DOM by injecting Javascript after all of the other content has already loaded.

A developer will wait until the page has loaded, hide the content, change elements in the background, and show everything to the user post-change. (Because the page is hidden while these changes are being made, the user is none-the-wiser.)

Tom-Davis

We’re trying to do this switcheroo without anyone seeing it.

– Thomas Davis, Front End Developer, WiderFunnel

In Angular apps, there’s no way to guarantee that all of the content has been rendered before that extra Javascript is injected. At this point, Angular has already initialized the app, meaning any code running after this is outside of Angular’s execution context. This makes it complicated to try to figure out when and how to run the changes that make up your test.

When you’re running a test, the changes that make up Variation A (or B or C) are loaded when the page loads. You can only manipulate what’s in the DOM already. If you can’t guarantee that the content is loaded, how do you ensure that your added Javascript runs at the right time and how do you do this without breaking the code and functionality?

Tom explained that, as a dev trying to do conversion optimization on an Angular application, you find yourself constantly trying to answer this question:

How can I make this change without directly affecting my (or my client’s) built-in functionality? In other words, how can I make sure I don’t break this app?

How to influence Angular through the DOM

Angular makes for a complicated testing environment, but there are ways to test on Angular. Here are a few that we use at WiderFunnel (straight from Tom’s mouth to your eyeballs).

Note: In the examples below, we are working in the Inspector. This is just to prove that the changes are happening outside the context of the app and, therefore, an external script would be able to render the same results.

1. Use CSS wherever possible

When you’re running a test on Angular, use CSS whenever possible to make styling changes.

CSS is simply a set of styling rules that the browser applies to matching elements. Styling will always be applied on repaints regardless of how the DOM is bound to Angular. Everytime something changes within the browser, the browser goes through its list of styling rules and reapplies them to the correct element.

Let’s say, in a variation, you want to hide a banner. You can find the element you want to hide and add a styling tag that has an attribute of display none. CSS will always apply this styling and that element will never be displayed.

Of course, you can’t rely on CSS all of the time. It isn’t a scripting language, so you can’t do logic. For instance, CSS can’t say “If [blank] is true, make the element color green. If [blank] is false, make the element color red.”

In other cases, you may want to try $apply.

2. Using $scope/$apply in the DOM

We’ve established that Angular’s two-way data binding makes it difficult to develop consistent page changes outside of the context of Angular. Difficult…but not impossible.

Say you want to change the value of $scope.helloWorld. You need a way to tell Angular, “Hey, a value has changed — you need to propagate this change throughout the app.”

Angular checks $scope variables for changes whenever an event happens. An event attribute like ng-click or ng-model will force Angular to run the Digest Loop*, where a process called dirty checking* is used to update the whole of the app with any new values.

If you want to change the value of $scope.helloWorld and have it propagated throughout the app, you need to trick Angular into thinking an event has occurred.

But, how?

First step: You’ll need to access the model in the $scope object. You can do this simply by querying it in the DOM.

Testing on Angular_$scope

In this example, you’re looking at the $scope object containing all models available to the H1 element. You’re looking at the helloWorld variable exposed.

Once you have access to helloWorld, you can reassign it. But wait! You’ve probably noticed that the text hasn’t changed in the window… That’s because your code is running outside the context of Angular — Angular doesn’t know that a change has actually been made. You need to tell Angular to run the digest loop, which will apply the change within it’s context.

Fortunately, Angular comes equipped with an $apply function, that can force a $digest, as shown below.

Testing on Angular_$apply

3. Watch for changes

This workaround is a little manual, but very important. If the source code changes a variable or calls a function bound to $scope, you’ll need to be able to detect this change in order to keep your test functional.

That’s where Angular’s $watch function comes in. You can use $watch to listen to $scope and provide a callback when changes happen.

In the example below, $watch is listening to $scope.helloWorld. If helloWorld changes, Angular will run a callback that provides the new value and the old value of helloWorld as parameters.

Testing on Angular_$watch

Custom directives and dependency injection

It’s important that you don’t default to writing jQuery when testing on Angular apps. Remember, you have access to all the functionality of Angular, so use it. For complex experiments, you can use custom directives to manage code structure and make it easy to debug.

To do this, you can implement an injector to apply components in the context of the app that you’re testing on. Here’s a simple example that will alert you if your helloWorld variable changes:

For more details on how to use an injector, click here.

—–

These are just a few of the tactics that the WiderFunnel Dev team uses to run successful conversion optimization on Angular apps. That said, we would love to hear from all of you about how you do CRO on Angular!

Do you use the same tactics described here? Do you know of other workarounds not mentioned here? How do you test successfully on Angular apps? Let us know in the comments!

Glossary

DOM: The Document Object Model (DOM) is a cross-platform and language-independent convention for representing and interacting with objects in HTML, XHTML, and XML documents

$scope: Scope is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can watch expressions and propagate events.

$apply: Apply is used to execute an expression in Angular from outside of the Angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).

JSON: (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999

Two-way data binding: Data-binding in Angular apps is the automatic synchronization of data between the model and view components. The way that Angular implements data-binding allows you to treat the model as the single source of truth in your application.

Digest Loop: There is an internal cycle called $digest that runs through the application and executes watch expressions and compares the value returned with the previous value and if the values do not match then a listener is fired. This $digest cycle keeps looping until no more listeners are fired.

Dirty Checking: Dirty checking is a simple process that boils down to a very basic concept: It checks whether a value has changed that hasn’t yet been synchronized across the app

The post Tips and tactics for A/B testing on AngularJS apps appeared first on WiderFunnel Conversion Optimization.

Visit source: 

Tips and tactics for A/B testing on AngularJS apps

Responsive Typography With Sass Maps

Managing consistent, typographic rhythm isn’t easy, but when the type is responsive, things get even more difficult. Fortunately, Sass maps make responsive typography much more manageable.

Writing the code is one thing, but keeping track of font-size values for each breakpoint is another — and the above is for paragraphs alone. Throw in h1 to h6s, each with variable font sizes for each breakpoint, and it gets cumbersome, especially when the type doesn’t scale linearly.

If you’ve tried to tackle responsive type, this may look familiar:

p  font-size: 15px; 

@media screen and (min-width: 480px) 
  p  font-size: 16px; 
}
@media screen and (min-width: 640px) 
  p  font-size: 17px; 
}
@media screen and (min-width: 1024px) 
  p  font-size: 19px; 
}

Sass variables are great for making values reusable throughout a project, but managing them for responsive font sizes easily becomes a mess.

$p-font-size-mobile : 15px;
$p-font-size-small  : 16px;
$p-font-size-medium : 17px;
$p-font-size-large  : 19px;

$h1-font-size-mobile: 28px;
$h1-font-size-small : 31px;
$h1-font-size-medium: 33px;
$h1-font-size-large : 36px;

// I think you get the point…

This is where Sass maps1 and loops are powerful: They’ve helped me manage z-index values2, colors3 and, as you’ll see in a moment, font sizes.

Organizing Font Sizes With Sass Maps

Let’s start by creating a Sass map with key-value pairs — breakpoints as keys and font sizes as corresponding values.

$p-font-sizes: (
  null  : 15px,
  480px : 16px,
  640px : 17px,
  1024px: 19px
);

With mobile-first in mind, we see that the key null represents the default font size (not in a media query), and breakpoints are in ascending order.

Next, the mixin, which iterates through a Sass map and generates the appropriate media queries.

@mixin font-size($fs-map) 
  @each $fs-breakpoint, $fs-font-size in $fs-map 
    @if $fs-breakpoint == null 
      font-size: $fs-font-size;
    
    @else 
      @media screen and (min-width: $fs-breakpoint) 
        font-size: $fs-font-size;
      
    }
  }
}

Note: It’s worth mentioning that this mixin, along with the ones to follow, feature some basic programming logic. Sass, with the help of SassScript4 (a set of extensions that comes baked in), makes basic programming constructs possible, like if/else statements, each loops and a ton more. I encourage you to take some time to read through the documentation5. Sass’ “power features” will introduce you to a new dimension of things you can do with Sass.

We’ll then use the mixin for paragraphs:

p 
  @include font-size($p-font-sizes);

… which results in the following CSS:

p  font-size: 15px; 

@media screen and (min-width: 480px) 
  p  font-size: 16px; 
}
@media screen and (min-width: 640px) 
  p  font-size: 17px; 
}
@media screen and (min-width: 1024px) 
  p  font-size: 19px; 
}

Managing and keeping track of font sizes for elements becomes a whole lot easier! With every new element, create a map and call the mixin in the appropriate selector.

$h1-font-sizes: (
  null  : 28px
  480px : 31px,
  640px : 33px,
  1024px: 36px
);

h1 
  @include font-size($h1-font-sizes);

Keep font sizes consistent for various elements:

p, ul, ol 
  @include font-size($p-font-sizes);

Solving Breakpoint Fragmentation

But wait! What if we decide that we want the font size of ps to be 17 pixels and of h1s to be 33 pixels at a breakpoint of 700 pixels, instead of 640 pixels? With the solution above, that would require manually changing every instance of 640px. By trying to solve one problem, we’ve inadvertently created another: breakpoint fragmentation.

If we can manage font sizes in Sass maps, surely we can do the same with breakpoints, right? Exactly!

Let’s create a map for common breakpoints and assign each value an appropriate name. We’ll also change the font-sizes map a bit by using the breakpoint names we assigned in $breakpoints to establish a relationship between the breakpoints and font-sizes maps.

$breakpoints: (
  small : 480px,
  medium: 700px, // Previously 640px
  large : 1024px
);

$p-font-sizes: (
  null  : 15px,
  small : 16px,
  medium: 17px,
  large : 19px
);

$h1-font-sizes: (
  null  : 28px
  small : 31px,
  medium: 33px,
  large : 36px
);

The last step is to tweak the mixin a bit so that when it iterates through the font-sizes map, it’ll use the breakpoint name to get the appropriate value from $breakpoints before generating the media query.

@mixin font-size($fs-map, $fs-breakpoints: $breakpoints) 
  @each $fs-breakpoint, $fs-font-size in $fs-map 
    @if $fs-breakpoint == null 
      font-size: $fs-font-size;
    
    @else 
      // If $fs-font-size is a key that exists in
      // $fs-breakpoints, use the value
      @if map-has-key($fs-breakpoints, $fs-breakpoint) 
        $fs-breakpoint: map-get($fs-breakpoints, $fs-breakpoint);
      
      @media screen and (min-width: $fs-breakpoint) 
        font-size: $fs-font-size;
      
    }
  }
}

Note: The mixin’s default breakpoints map is $breakpoints; if your breakpoints variable’s name is different, be sure to change it in the second argument of line 1.

Voila! Now, what if we want an element to have a font size for a custom breakpoint that doesn’t exist in $breakpoints? In the font-sizes map, simply drop in the breakpoint value instead of a name as the key, and the mixin will do the work for you:

$p-font-sizes: (
  null  : 15px,
  small : 16px,
  medium: 17px,
  900px : 18px,
  large : 19px,
  1440px: 20px,
);

p 
  @include font-size($p-font-sizes);

The magic happens in the mixin thanks to Sass’ map-has-key function6. It checks to see whether the key name exists in $breakpoints: If it exists, it’ll use the value of the key; if not, it’ll assume the key is a custom value and use that instead when generating the media query.

p  font-size: 15px; 

@media screen and (min-width: 480px) 
  p  font-size: 16px; 
}
@media screen and (min-width: 700px) 
  p  font-size: 17px; 
}
@media screen and (min-width: 900px) 
  p  font-size: 18px; 
}
@media screen and (min-width: 1024px) 
  p  font-size: 19px; 
}
@media screen and (min-width: 1440px) 
  p  font-size: 20px; 
}

Improving Vertical Rhythm With Line Height

Line height is also an important part of achieving consistent vertical rhythm. So, without going overboard, let’s include line height in the solution.

Extend the font-sizes map by including both font size and line height in a list as the value of the desired key:

$breakpoints: (
  small : 480px,
  medium: 700px,
  large : 1024px
);

$p-font-sizes: (
  null  : (15px, 1.3),
  small : 16px,
  medium: (17px, 1.4),
  900px : 18px,
  large : (19px, 1.45),
  1440px: 20px,
);

Note: Although line-height values can be defined using any valid CSS unit (percentages, pixels, ems, etc.), “unitless” values are recommended7 and preferred8 in order to avoid unexpected results due to inheritance.

We then need to modify the mixin to include line height when generating the CSS.

@mixin font-size($fs-map, $fs-breakpoints: $breakpoints) 
  @each $fs-breakpoint, $fs-font-size in $fs-map 
    @if $fs-breakpoint == null 
      @include make-font-size($fs-font-size);
    
    @else 
      // If $fs-font-size is a key that exists in
      // $fs-breakpoints, use the value
      @if map-has-key($fs-breakpoints, $fs-breakpoint) 
        $fs-breakpoint: map-get($fs-breakpoints, $fs-breakpoint);
      
      @media screen and (min-width: $fs-breakpoint) 
        @include make-font-size($fs-font-size);
      
    }
  }
}

// Utility function for mixin font-size
@mixin make-font-size($fs-font-size) 
  // If $fs-font-size is a list, include
  // both font-size and line-height
  @if type-of($fs-font-size) == "list" 
    font-size: nth($fs-font-size, 1);
    @if (length($fs-font-size) > 1) 
      line-height: nth($fs-font-size, 2);
    
  }
  @else 
    font-size: $fs-font-size;
  
}

The mixin checks to see whether the value of the key in the font-sizes map is a list as opposed to a font-size value. If it’s a list, then it gets the correct value from the list by index value, with the help of the nth function9. It assumes that the first value is the font size and the second is the line height. Let’s see it in action:

p 
  @include font-size($p-font-sizes);

And here’s the resulting CSS:

p  font-size: 15px; line-height: 1.3; 

@media screen and (min-width: 480px) 
  p  font-size: 16px; 
}
@media screen and (min-width: 700px) 
  p  font-size: 17px; line-height: 1.4; 
}
@media screen and (min-width: 900px) 
  p  font-size: 18px; 
}
@media screen and (min-width: 1024px) 
  p  font-size: 19px; line-height: 1.45; 
}
@media screen and (min-width: 1440px) 
  p  font-size: 20px; 
}

This final solution is easily extensible to accommodate a host of other attributes, such as font weights, margins, etc. The key is to modify the make-font-size utility mixin and use the nth function to get the appropriate value from the list.

Conclusion

There are various ways to approach responsive typography and consistent vertical rhythm, and they are not limited to my suggestion. However, I find that this works for me more times than not.

Using this mixin will likely generate duplicate media queries in your compiled CSS. There’s been a lot of discussion about duplicate media queries versus grouped media queries, using @extend instead of mixins10, and performance and file size; however, tests have concluded that “the difference, while ugly, is minimal at worst, essentially non-existent at best11.”

I also realize that my solution is not robust (it’s not designed to handle media-query ranges, max-width or viewport orientation). Such features can be implemented in the mixin (my personal version also converts pixel values to ems), but for complex media queries, I prefer to write by hand. Don’t forget that you can use the map-get function12 to retrieve values from existing maps.

Alternatives

Viewport units13 (vh, vw, vmin and vmax) can also be used to create responsive typography:


An example of viewport units in action. One viewport unit = 1% of the viewport’s width or height. (For a 1000-pixel-wide viewport, 1vw = 100px; for a 500-pixel-high viewport, 1vh = 5px.)

For example, viewport-width units can be used to build fluid hero text14. However, because the text will be scaled to the width or height of the viewport (as opposed to the size of the content area of the page) and because CSS currently lacks min and max values for the font-size property, viewport units aren’t suitable for body text: No matter what value you choose, body text sized in viewport units will always end up being too large or too small at extreme browser sizes, necessitating intervention by media query.

FitText.js15 does a similar job, with a focus on sizing text so that it always rests on a single line or measure. SVG techniques can also be used to achieve a similar effect.

Finally, Erik van Blokland16 has been working on some very exciting possibilities for responsive typography17, such as letterforms that actually alter with viewport size to preserve space, rather than simply get smaller.

Further Resources

Modular Scale18 is a great tool to achieve responsive typography, and Sara Soueidan has a great article on responsive typography techniques19.

Image source20 of picture on front page.

(ds, ml, al)

Footnotes

  1. 1 https://jonsuh.com/blog/sass-maps/
  2. 2 https://jonsuh.com/blog/organizing-z-index-with-sass/
  3. 3 https://jonsuh.com/blog/sass-maps/#loops-and-maps
  4. 4 http://sass-lang.com/documentation/file.SASS_REFERENCE.html#sassscript
  5. 5 http://sass-lang.com/documentation/file.SASS_REFERENCE.html
  6. 6 http://sass-lang.com/documentation/Sass/Script/Functions.html#map_has_key-instance_method
  7. 7 https://css-tricks.com/almanac/properties/l/line-height/
  8. 8 https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#Prefer_unitless_numbers_for_line-height_values
  9. 9 http://sass-lang.com/documentation/Sass/Script/Functions.html#nth-instance_method
  10. 10 https://tech.bellycard.com/blog/sass-mixins-vs-extends-the-data/
  11. 11 http://sasscast.tumblr.com/post/38673939456/sass-and-media-queries
  12. 12 http://sass-lang.com/documentation/Sass/Script/Functions.html#map_get-instance_method
  13. 13 https://css-tricks.com/viewport-sized-typography/
  14. 14 http://demosthenes.info/blog/739/Creating-Responsive-Hero-Text-With-vw-Units
  15. 15 http://fittextjs.com/
  16. 16 https://twitter.com/letterror
  17. 17 http://letterror.com/dev/mathshapes/page_20_Excellence.html
  18. 18 http://www.modularscale.com/
  19. 19 http://tympanus.net/codrops/2013/11/19/techniques-for-responsive-typography/
  20. 20 http://www.flickr.com/photos/r2i-social-networking/6925301398/sizes/m/in/photostream/

The post Responsive Typography With Sass Maps appeared first on Smashing Magazine.

Credit: 

Responsive Typography With Sass Maps

Thumbnail

Terrible JavaScript Mistakes To Avoid With A Static Code Analyzer

Hardly any line of my code comes out perfect the first time I write it. Well, most of the time… Some of the time… Um, hardly ever. The truth is that I spend more time chasing down my own stupid programming errors than I’d like to admit. That’s why I use static analyzers in every JavaScript file I write.

Static analyzers look at code and find problems before you run it. They do simple checks, like enforcing syntax (for example, tabs instead of spaces), and more holistic checks, like making sure your functions aren’t too complex. Static analyzers also find errors that you can’t find with testing, like instances of == when you meant ===.

In large projects and on big teams, you’ll be happy to have a little help finding those “simple” bugs that turn out to be a lot less simple than they looked.

JSLint, JSHint And Closure Compiler

You have three main choices for static analyzers in the JavaScript world: JSLint1, JSHint2 and Closure Compiler3.

JSLint

JSLint was the first static analyzer for JavaScript. You can run it on the official website4 or use one of the wrappers5 to run it on your local files. JSLint finds a lot of useful errors, but it’s very rigid. Here’s a good example:

var s = 'mystring';
for (var i = 0; i < s.length; i++) 
  console.log(s.charAt(i));

JSLint will show two errors for this code:

Unexpected '++'.
Move 'var' declarations to the top of the function.

The first problem is the declaration of the variable i at the top of the loop. JSLint also doesn’t like the ++ operator at the end of the loop declaration. It wants the code to look like this:

var s = 'mystring';
var i;
for (i = 0; i < s.length; i = i + 1) 
  console.log(s.charAt(i));

I appreciate where JSLint is coming from, but it’s just too strict for me. It was too rigid for Anton Kovalyov6 as well, so he created JSHint.

JSHint

JSHint works similarly to JSLint, but it’s written on top of Node.js7 and it’s much more flexible. JSHint has a long list of options8, making it possible to create custom checks by writing your own reporter9.

You can run JSHint from the website10, but most of the time you would install JSHint as a local command-line tool11 using Node.js. Once JSHint is installed, you can run it against your files with a command like this:

jshint test.js

JSHint also has plugins for popular text editors, so you can run JSHint while you’re coding.

Closure Compiler

Closure Compiler, from Google, is a different breed. As the name suggests, it’s a compiler as well as a checker. It’s written in Java and based on the Rhino12 parser from Mozilla. Closure Compiler has a simple mode to do basic code checking, but it also has more advanced modes to do extra checking and enforce special type declarations.

Closure Compiler reports errors in JavaScript code, but it also creates minimized versions of JavaScript. The compiler removes white space, comments and unused variables and simplifies long statements to make a script as small as possible.

Google makes a simple version of its compiler available on the Web13, but most of the time you’ll want to download Closure Compiler14 and run it locally.

Closure Compiler will output a list of files into a single minimized file after checking their code. You can run it like that after you’ve downloaded the compiler.jar file.

java -jar compiler.jar --js_output_file compress.js --js test1.js --js test2.js

Choosing the Right Checker

In my projects, I combine Closure Compiler with JSHint. Closure Compiler does the minimization and basic checking, while JSHint handles the more complex code analysis. The two work well together, and each covers some areas that the other doesn’t. In addition, I can use the extension capabilities of JSHint to write custom checkers. One common checker I write checks for particular functions that I don’t want, like calling functions that I don’t want to allow in my project.

Now that we’ve looked at a few checkers, let’s look at some bad code. All of these six examples are code you should never write and are spots where code checkers would keep you out of trouble.

This article uses JSHint for most examples, but Closure Compiler would produce similar warnings.

== Versus ===

JavaScript is a dynamically typed15 language. You don’t have to declare types when you’re coding, but they exist at runtime. JavaScript offers two compare operators to handle these dynamic types: == and ===. Let’s look at an example.

var n = 123;
var s = '123';

if (n == s) 
  alert('The variables were equal');


if (n === s) 
  alert('The variables were identical');

The == operator compares the values of the two objects. It converts the objects and compares them separately from their types. The === operator compares the object types and the values. In this case, the first if block will pop up an alert, and the second if block won’t — because n and s have the same value but not the same type.

The == comparator is a relic from the C language roots of JavaScript. Using it is almost always a mistake: Comparing values separate from types is rarely what the developer means to do. In reality, the number “one hundred twenty-three” is different from the string “one two three.” These operators are easy to mistype and even easier to misread.

Check this code with JSHint and you’ll get this:

test.js: line 9, col 12, Expected '===' and instead saw '=='.

Undefined Variables And Late Definitions

Let’s start with some simple code:

function test() 
  var myVar = 'Hello, World';
  console.log(myvar);

See the bug? I make this mistake all the time. Run this code and you’ll get an error:

ReferenceError: myvar is not defined

Let’s make the problem a little more difficult to spot:

function test() 
  myVar = 'Hello, World';
  console.log(myVar);

Run this and you’ll get:

Hello, World

This second example works, but it has some very unexpected side effects. The rules for declaring JavaScript variables and the scopes they end up in are confusing at best.

In the first case, JSHint will tell you this:

test.js: line 3, col 17, 'myvar' is not defined.

In the second case, it will tell you this:

test.js: line 2, col 5, 'myVar' is not defined.
test.js: line 3, col 17, 'myVar' is not defined.

The first case saves you from a runtime bug. You don’t have to test your app — JSHint will find the error for you. The second case is worse because testing won’t find the bug.

The problem with the second case is insidiously subtle and complex. The variable myVar has now escaped from its function scope and been hoisted16 into the global scope for the whole page. This means that it will exist and have a value of Hello, World after the test function has run. This is called “global scope pollution.”

The myVar variable will exist for every other function that runs after the test function. Run the following code after you’ve run the test function:

console.log('myVar: ' + myVar);

You’ll still get Hello, World. The myVar variable will hang around your code like mold, causing tricky bugs you won’t find until 3:00 am the night before you release, all because you forgot to type var.

Variable Reuse

Redefining variables is allowed in JavaScript, but it’s almost always an accident. Take a look:

function incrementCount(counter) 
  if (counter.count) 
    counter.count++;
   else 
    var counter = 1;
    counter.count = counter;
  
}

In this function we’re incrementing the count property on the object that was passed in, but we need to add the property if it doesn’t already exist. See the bug?

This function will never add or increment a counter on anything. The else statement will always be called, and it will redefine the function argument counter. Basically this function creates a new object, assigns a property to it and then loses the object when the function returns. It will never change the object that was passed in.

This simple typo will make the code run without any errors but will produce a very strange result.

JSHint will tell you this:

test.js: line 21, col 21, 'counter' is already defined.

Curly Braces In Blocks, Loops And Conditionals

if (false)
  doSomethingElse();
  doSomething();

Will this code doSomething or doSomethingElse? At first glance, I always think it won’t doSomething or doSomethingElse. That’s the way it works in Python, but not in JavaScript. JavaScript will treat the one line after the if statement merely as part of the block; the indenting doesn’t matter.

This issue is simply about code readability. If you can’t understand what the code will do, then you’ll write bugs.

Python and CoffeeScript like to skip the curly braces. That might work fine in languages that guarantee to format white space well, but JavaScript is looser than that. JavaScript allows a lot of strange syntax, and curly braces will keep you out of trouble.

if (false) 
  doSomethingElse();
  doSomething();

Add the braces and you’ll always make code more readable. Skip them and JSHint will tell you this:

test.js: line 27, col 5, Expected '' and instead saw 'doSomething'.

Single And Double Quotes

console.log("This is a string. It's OK.");
console.log('This string is OK too.');
console.log("This string " + 'is legal, but' + "really not OK.");

JavaScript allows you to define a string with single or double quotes. It’s nice to have the flexibility, like when you’re defining HTML, but the added flexibility can lead to some very inconsistent code.

Google has a code style guide that always uses single quotes for strings, so that they don’t have to escape double quotes in HTML. I can’t argue that single quotes are better than double quotes, but I can argue for consistency. Keeping everything consistent makes code more readable.

JSHint will warn you about mixed quotes like this:

test.js: line 31, col 27, Mixed double and single quotes.

Copying and pasting or mistyping a quote is easy. Once you have one bad quote, others will follow, especially if a lot of people are editing the file. Static analyzers will help keep the quotes consistent and prevent a big cleanup in the future.

Cyclomatic Complexity

Cyclomatic complexity17 is the measure of how complex a given block of code is. Look at the code and count the number of paths that could possibly run: That number is its cyclomatic complexity.

For example, this code has a cyclomatic complexity of 1:

function main() 
  return 'Hello, World!';

You can follow only one path through this code.

Let’s add a little conditional logic:

function main() 
  if (true) 
    return 'Hello, World!';
   else 
    return 'Hello, unWorld!';
  
}

The cyclomatic complexity has jumped to 2.

Ideal code is easy to read and understand. The higher the cyclomatic complexity, the more difficult the code will be to understand. Everyone agrees that high cyclomatic complexity is bad, but no one agrees on a limit; 5 is fine, and 100 is too high — but there’s a lot of gray area in the middle.

If the cyclomatic complexity gets to the predefined limit, then JSHint will let you know.

test.js: line 35, col 24, This function's cyclomatic complexity is too high. (17)

JSHint is the only one of the three checkers that looks at cyclomatic complexity. It also allows you to set the limit. Go above the maxcomplexity number that you’ve set and JSHint will warn you. I like to set the limit to 14, but I’ll go a little higher in projects in which I do a lot of parsing or when I have other reasons to need many code paths.

The real reason the complexity number is important is that it tells you when to refactor your code. The first time you write a long function, it always makes sense. But if you wait six months and then come back to fix bugs, you’ll be glad that you took the time to make it easier to read.

Cyclomatic complexity usually breaks down with laundry lists. For example, I created a calendar, and I wanted to get the correct first day of the week for each country. I had a function that looked something like this:

function getFirstDay(country) 
  if (country === 'USA') 
    return 'Sunday';
   else if (country === 'France') 
    return 'Monday';
   else if…
}

I supported a lot of countries, so the cyclomatic complexity quickly grew to over 50. Although the code was very easy to read, the number of paths was high, so my code analyzer complained. In the end, I split up the function to get the complexity below my maximum. It was a hack for this particular case, but it’s a small price to pay for cleaner code overall.

Check Everything That You’ll Ever Edit More Than Once

Static checkers find the bugs that you wouldn’t come across with simple testing. They also find bugs at compile time, as opposed to runtime — those middle-of-the-night bugs that only creep in when a dozen people are all trying to do the same thing. Finding all of those subtle bugs is a long and painful process without code checking.

I began this article by claiming that I always use a code analyzer, but I don’t in one case: with throwaway code. I like using quick prototypes to show interactive ideas and to help my team come together on how something should work. Those prototypes are write-once code; I never need to fix bugs in them because I’ll be throwing away the prototypes a few weeks later. This throwaway code exists solely for the quick demos, and I don’t care if it has subtle bugs. Everything I care about, though, gets analyzed.

Fixing these types of bugs at the beginning of a project is easy; finding them on the night before you release will drive you nuts. Code analyzers have saved my butt many times, and they’ll also save yours.

Image on front page created by Ruiwen Chua18.

(al, ml, da)

Footnotes

  1. 1 http://www.jslint.com/
  2. 2 http://www.jshint.com/
  3. 3 https://developers.google.com/closure/compiler/
  4. 4 http://www.jslint.com/
  5. 5 https://code.google.com/p/jslint4java/
  6. 6 http://anton.kovalyov.net/
  7. 7 http://nodejs.org/
  8. 8 http://www.jshint.com/docs/options/
  9. 9 http://www.jshint.com/docs/reporters/
  10. 10 http://jshint.com/
  11. 11 http://jshint.com/install/
  12. 12 https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino
  13. 13 http://closure-compiler.appspot.com/home
  14. 14 https://developers.google.com/closure/compiler/
  15. 15 http://www.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/
  16. 16 http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
  17. 17 http://en.wikipedia.org/wiki/Cyclomatic_complexity
  18. 18 http://www.flickr.com/photos/7162499@N02/3260095534/

The post Terrible JavaScript Mistakes To Avoid With A Static Code Analyzer appeared first on Smashing Magazine.

See the article here:  

Terrible JavaScript Mistakes To Avoid With A Static Code Analyzer

Thumbnail

[Infographic] VWO eCommerce Survey 2014: What Makes Shoppers Buy

We asked online shoppers what were their biggest pain points, what made them purchase right away, what made them come back to their abandoned carts, how social networks influence their purchase behavior, and much more.

We got some pretty amazing insights which will help eCommerce stores optimize their business strategies. If you want to read the full report, click here, else proceed to the infographic.

Click to get the full image ecommerce_infographic

Want to share? Embed this code:

The post [Infographic] VWO eCommerce Survey 2014: What Makes Shoppers Buy appeared first on VWO Blog.

Visit site: 

[Infographic] VWO eCommerce Survey 2014: What Makes Shoppers Buy