Tuesday, August 14, 2012

Everything I Know About SVG


Everything I Know About SVGSVG is arguably going to be the main image format of the modern web. I recently wrote an article for Safari Books Online called SVG Icons for New Devices that covers some of the basics of dealing with SVG. This article tries to focus more on the pain points of using SVG in production and it turns out there are many. Read along to see what I’m talking about.

Plain Old <img> Tags

Here’s how you link to your amazing vector image.
<img src="/images/logo.svg">
This is pretty straightforward and should work very well for most of your cases. You can also specifcy width and height this way or in your CSS.

Vector is XML

SVG files are supposed to be human readable, but XML is terrible, so it’s been slow going for me. That being said I have noticed one strange thing about the content of SVG files, notably the fact that there are width and height attributes:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="15px" height="15px" viewBox="0 0 15 15" enable-background="new 0 0 15 15" xml:space="preserve">
Sometimes in Firefox when you scale up SVG images (browser-zoom) you get some weird bluriness. If you change the width and height from px to em this bluriness seems to myseriously dissappear. Because in this case it’s a sqaure 1em and 1em work great. I’m not sure if this is a bug in Firefox or if it’s even still a problem in the newer versions. Your mileage may very.

Basic Icons

It’s pretty easy to use SVG for icons and just make them background images. This is probably your standard use case for SVG anyway.
.icon {
    height: 16px;        
    width: 16px;
    background-size: 16px 16px;
}

.icon-arrow {
    background: url("/images/icon-arrow.svg") no-repeat;
}

<div class="icon icon-arrow"></div>

Relatively Easy EM Icons

EM’s are relative to font-size, so you can easily use them to size your SVG images relative to some text, which can be really helpful in a lot of cases. Here’s an exaple of putting them next to some headings.
h1 {
    font-size: 24px;
}

h2 {
    font-size: 18px;
}

.icon-before {
    background-size: 1em 1em;
    padding-left: 1em;
}

.icon-arrow {
    background: url("/images/icon-arrow.svg") no-repeat;
}

<h1 class="icon-before icon-arrow">Header 1 w/Icon</h1>
<h2 class="icon-before icon-arrow">Header 2 w/Icon</h2>

Fallbacks

If you care about IE8 or Android 2.x or other browsers that don’t support SVG images you can combine some fanciness like this with a simple custom build of modernizr to easily fallback without too much ugliness.
.icon {
    height: 16px;        
    width: 16px;
    background-size: 16px 16px;
    background-repeat: no-repeat;
}

/* only show svg icon */
.svg .icon-arrow {
    background-image: url("/images/icon.svg");
}

/* don't show anything but png */
.no-svg .icon-arrow {
    background-image: url("/images/icon.png");
}    

<div class="icon icon-arrow"></div>
Note: With this approach we do have to wait until modernizr adds our svg or no-svg classes to the pages <body> before the images show up. Other fallback approaches can avoid the wait, but this guarantees the right thing will show up in the right browser.
Another Note: Someone really needs to write a Sass plugin one day to create the PNG images directly from the SVG, so that we don’t have to bug the designer for it.

Data-URIs

Data URI’s are this amazing way to embed binary image content directly into your CSS files. This results in a reduce number of seperate downloads and can improve performance in some situations (hover states, etc).
.icon {
    height: 16px;        
    width: 16px;
    background-size: 16px 16px;
    background-repeat: no-repeat;
}

.icon-arrow {
    background-image: url(data:image/svg+xml;base64,..);
}

<div class="icon icon-arrow"></div>
Compass provides the inline-data() helper to assist with base64ing images and bringing them into your stylesheets. You can also drag and drop your SVG images into the SVG is Rad tool I wrote to get the proper CSS.

Weird Bugs

In some versions of WebKit (Chrome < 18 and Safari < 6) you cannot combine SVG data-URIs and background-repeat: repeat-x. The image turns into a blurry mess! Because of this bug in some cases I had to switch to referencing the SVG from a file and it was fine.

MIME Types

If you try to link to external SVG files for background images and don’t specify the correct mime type they just won’t show up. This happened to us after we switched from base-64 encoded SVGs to linking to files, because the so-called magic mime type detection script in our version of Apache noticed that our SVG files looked like XML and served them up as text/xml.
You can add this to your .htaccess file if Apache is doing the same thing to you (hat tip: this 5 year old article):
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
If you’re on NGINX check out this stackoverflow question about SVG MIME types and NGINX.

Related Research

Other people are doing a lot of interesting things with SVGs at the moment. Here are some topics I don’t know quite enough about at the moment:
  1. Spriting with SVG Images
  2. Styling SVG with CSS
  3. SVG Stacks

Thursday, May 3, 2012

Sass Mixins

I was asked to make some buttons at work. I thought it might be a good idea to play with Sass mixins to generate the buttons. I got really excited about this and tried my hardest to generate the buttons from a single base color. It was fun and hard at the same time. It ended up being kind of crap.

In my earlier post about Sass color palettes I was playing with keeping all my colors in a single file. this way we can keep track of them and easily change them in the future. We won't get lost in slightly difference shades of blue everywhere. It's a good idea.

Not being an expert at color theory, I couldn't have told you how to get from one shade to another with anything other than Sass's built-in lighten() and darken() functions. That quickly got me a really terrible looking button, so I had try more complicated approaches.

I had the original CSS styles to work with already, so I tried to make legitimate guesses as to how to get from say the top of the gradient color to the bottom of the gradient color. I did math around the rgb() and though about adding or subtracting various amounts of red, green, or blue. The gradients weren't too bad, but the borders were tricky, they weren't just darker, they were redder, but only for the orange button.

So then I had the idea to inspect the hue, lightness, and saturation. I could get each colors hsl() codes, I could then figure out how different each part of the button was from the other colors, hopefully finding a way to pick a good base color. This proved a decent approach, and it seemed to work pretty much universally, well you know, it worked out okay for most of the darker colors, but lighter colors presented another problem.

It turns out that the trick is dealing with gray, especially light gray, because all of the sudden all of the supporting colors have to change and where you were once lightening colors, you may have to darken them. A decent measure of grayness was to look at saturation. Once I established grayness I also had to look at lightness before deciding which color text to use.

I spent maybe 1 to 3 hours on this and found it a fairly tedious process. It not something I'd wish on anyone else, but I did learn a bit. What do you think of the results?

Conclusion

This experiment was worthwhile, but we ended up just sass-ifying the webkit-only CSS the designer gave us and hard-coding each button separately. Two different buttons might have different box-shadow lengths or border sizes, not to mention hover states. I'm still glad I learned about how mixins work and that this sort of thing was definitely doable. Like a lot of approaches to design (grids, etc) I think it really takes working with a designer that can see the value in the approach and work closely with you on it from the start. Anyone have suggestions on how it could been done better?

Friday, April 6, 2012

JSConf 2012 Notes






Introduction

JSConf has a pretty great reputation. Node.js, Phonegap and other huge projects were announced in JSConf's past. There are legendary parties and fantastic speakers. This year was no exception. As such, the 250 conference tickets sold out in less than 5 minutes. We dressed up like cowboys, rode a mechanical bull and even had shoot-outs. It was a pretty awesome adventure. 

Themes

I try to look for themes in the talks that I saw to figure out what's going on in the community right now. Other than the cowboy theme there were a couple of ideas I heard repeated more than once:
  1. Experimentation / play leads to great ideas.
  2. Everyone is working really hard to make JS faster.
  3. We need more women/diversity in JS.
  4. Build tools / dependencies let us do cooler things.

My Talk

I gave a quick talk about some things I think are important to the JS community.
  1. Open Source
  2. Respecting Diversity
  3. Helping New People
  4. Startup/DIY Culture
You can see the slides here: JavaScript as a Subculture

While no one mentioned it directly, this popular tweet was in response to my talk: Talk about JS culture: "we hated ie, we hated tables,.. What's the new enemy? Someone answers: the threat of native" good answer @jsconf. I'm famous!

Big Announcements

People look to JSConf for big announcements. There were a few of those. It usually takes a few years though to see which ones actually end up panning out.
  1. Project Bikeshed client/server-side flash -> js converter by UXEBU
  2. Grunt ant/rake for JS, by Ben Alman
  3. Everyone got Mozilla B2G Phones for hacking. Sooo cool.
  4. Joyent's node.js PaaS is being phased out and moved to Nodejitsu.
  5. The Chrome team introduced Source Maps for debugging minified code.

Best Talks

I obviously couldn't see all of the talks, so I may have missed a few things, but here were some of the top talks I saw at least in relation to front-end development, which is what I do at my day job. Many other amazing talks were also given about improving JS Performance in the browser, other programming languages and politics.

Jeff Archibald: AppCache is a Douchebag


Summary: AppCache is not progressive enhancement, it completely changes how the browser handles your site.

This talk laid out basically all of the flaws and awkward parts of using HTML5 AppCache and how to use localStorage, iframes and other hacks to get it to behave properly. He made a separation between "get stuff" sites like blogs and wikipedia, and "do stuff" sites like drawing apps and games. It was really entertaining, but ultimately a depressing talk, because of how hard it is to get the AppCache to work properly :(
  1. http://lanyrd.com/2012/jsconf-us/sqxcz/
  2. http://dl.dropbox.com/u/2501978/appcache-diagram.svg

Remy Sharp: Build Anything


Summary:
Use HTML5's JS APIs to progressively enhance your site.

A good reminder of the latest crop of fairly well supported HTML5/JS APIs. We're already using most of these at oDesk, but some that we are not yet using include the HTML5 Drag'n'Drop API to handle file uploading, HTML5 input types, HTML5 History/PushState API, and EventSource (Server sent events).
  1. http://lanyrd.com/2012/jsconf-us/sqxcb/

Paul Irish: Tools


Summary:
There are a lot of great tools out there to help web development. Embrace these dependencies.

Paul Irish laid out every testing framework, css pre-processor, debug tool, and CI Server you could use to maintain your site. He also talked about source maps and some mobile web tools. He mentioned Jenkins and Travis as decent CI Servers.
  1. http://dl.dropbox.com/u/39519/talks/jsconf-tools/index.html

Jacob Thornton: Brûlons les musées


Summary:
We can make things better by starting over, but we need to have clear specs/tests to make sure our new thing still works the same.

The creator of Twitter Bootstrap and ender.js took us for a journey through Dada-ism and french futurism, finally landing on a quote by a famous futurist which translates to "burn the libraries". Jacob tried doing that with ender.js and it ended up being kind of awesome, but quickly people realized small differences with jQuery made it really hard to use. He took a similar approach at re-writing mustache.js in a project called Hogan, which ended up being really successful, because mustache.js had unit tests that could be used to ensure it was perfectly compatible. His approach ended up being significantly faster than the original and eventually was accepted into the mustache.js core. Super funny talk. Final quote "Burn all the libraries without tests".
  1. http://lanyrd.com/2012/jsconf-us/sqxkg/

New Friends

  1. I briefly talked to Nicole Sullivan, who was nice nice nice and seemed pleased as punch we were doing OOCSS at oDesk. She gave me some tips on grids and HTML5, which I'll share with my teams.
  2. I spoke with @substack who made browserling/testling who said we could get it to work behind our VPN if we opened up an SSH Tunnel somehow.
  3. I spoke with Devrim Yasar from Koding about his in-browser IDE. It's very similar to Cloud9, but it's more friendly to non-js environments. I'd really love to give something like this a try, but it will take some work to tweak our dev infrastructure.
  4. Ben Alman from Bocoup showed me his command-line tool Grunt, which is similar to my odesklint tool. It has built-in jshint, minification, and can run qUnit on the server-side with PhantonJS out-of-the box (almost). Grunt has a plugin architecture and may be a good starting point for future tools. I'm going to try and get the unit testing thing working and integrated with a CI server. :)
  5. I talked to the guys from Twillio, who make a really easy to use API for building SMS sender/receivers. Think user-verification and other use-cases. Fantastic stuff.
  6. John David Dalton had some ideas about how to speed up ES5 shims for things like Array.forEach. Really smart guy!
  7. I had a two total fanboy moments when I got to meet Rebecca Murphey and Remy Sharp, but you know everyone has their favorites. I met a bunch of other cool people too. Yay for talking to people. It can be so hard!

Tuesday, March 20, 2012

Mobile Web Anti-Patterns

I'm trying to capture some common mobile web anti-patterns, so we can learn from the mistakes of others. I found a couple of mobile-optimized sites that were well, not so optimized. Please add to the comments if you've seen some of these or other anti-patterns!

Beware the Landing Page



Contrary to what ABC News had in mind, I was trying to find the website not the app. I may have even clicked on a link from Google News or something, but when I saw this I immediately thought, "nevermind".

Native-only




I clicked a link from my Twitter client to hear a song and what do I get? There's no way to actually listen to the song without downloading the app and presumably searching for it. I don't even know the name of the song, just the artist. Worthless. :(

Where Are You?

 

Use your Google Maps app to look up the Post Office, because there website is too hard to use in a mobile situation. It's a mobile optimized site. It knows where I am. One of the biggest mobile web anti-patterns is asking for information you already have.

Too Small Text
 



There sandwiches are great, but if I can't read what they sell or even zoom-in, what is the point of having a website. Your site may be pretty and small, but it's not optimized for mobile if I'm not able to read anything. In this case the problem was using images instead of CSS3 and web fonts to create its look. Other sites don't let you zoom in at all.


Need Examples...

Phone Numbers as Text
Forgetting Map Links on Addresses
Serving Tablet's the Phone Site
What else?

Monday, March 12, 2012

On Tech Reading & Learning

I recently posted mini-book reviews of tech books. This got me thinking about the worth of books in the digital era for learning new technologies.

Personal E-Book History

When the iPad came out I was working at Rain and they were happy to buy me e-books to help me learn the latest and greatest technology, but I was slow to embrace the digital medium for reading, Mostly I really liked the way holding a book in-front of me felt. After I left Rain and wanted some new tech books and I noticed that O'Reilly regularly offered significant discounts on their e-books. Similarly, the fantastic A Book Apart series offers e-book versions of their mini-books for $8. It quickly became difficult to justify purchasing the paperback version of these books, so I started reading technical e-books pretty much exclusively.

Learning Styles

A great thing about books, both the paper and e varieties,  is that they have fewer distractions than a lot of other modern learning mediums. Think about Twitter. It encourages distraction. You might see 5 interesting links since yesterday. You have no way to read all of them thoroughly. The topics are wide ranging and the content decent, but you also want to stay up with the latest posts. Each of those links may have comments and a sidebar full of interesting stuff. It's not a focused experience. Books offer the ability to dive into something a little deeper and stay focused on them a little longer.
 Portability

Moving to e-books I found that I could read books wherever I went. I read most of CSS3 for Web Designers on my iPhone while my wife and I were shopping at Old Navy. Suddenly the structured learning experience that books provide was completely portable.

Lately, I've been doing a lot of reading at the gym as I run on the treadmill. Normal tech books just don't work well in this environment, because they're either too big or the pages don't stay open. E-books on the other hand are perfect. Being able to read a book at the gym helps me stay focused and not think about the treadmill moving under my feet, so I read a lot and get fit while I'm doing it!

Negatives 

In this age of digital learning are books still the ideal way to learn? I'll just lay out some of their obvious downsides.

Technical books are inherently static. You can't interact with them physically. They don't update automatically. They're essentially out of date the day they're published.

They're one sided. Web discussions and forums provide many viewpoints, because anyone can comment. A book may have one or two preset ways of looking at things, but it can hardly be expected to cover all of them.

Books can be really long. They must think they're really important for technical books to venture into the 800 page range (actually the post-120 range is pretty much enough for me). I don't have a huge attention span. While books encourage focus, they can only hold that focus for so long. It's hard to wade through all of the content of the multi-hundred page book.


Book I Like Best

While I'm really good at looking up information on the Internet. I don't always know what I should be looking up. For all of their former glory books with titles like Bible, Definitive Guide and Cookbook  are losing the battle for my attention span. In this I'll much more likely hit up the MDN or StackOverflow than pull out of a paper-back guide when I'm in the middle of a project. Despite their waning appeal there are still books out there that I value greatly.


Books that appeal to me are short.
Books that appeal to me are specific.
Books that appeal to me introduce me to new concepts.
Books that appeal to me often use color to make them clearer.

As I read books that meet these criteria I'm able to learn something new wherever I am and then when I get back to a computer somewhere I know what terms I want to use in my search for more about the topic. These books open my mind up to a new concept or idea. The practical knowledge of how to apply that idea to my specific situation is something I'd probably much rather find online where it will be up-to-date, littered with helpful comments, and checked out by the community at large.



Friday, March 9, 2012

Short Tech Book Reviews

Inspired by this thread on Google+  https://plus.google.com/u/0/116910304844117268718/posts/c3A4wgSAgx4 I decided to put together a bunch of short book reviews of tech books I've read recently.


Introducing HTML5
Great overview of new tags and JS APIs w/some good examples and demos.

HTML5 For Web Designers Loved it
Essential, short, colorful guide to HTML5.

Canvas Pocket Reference
It's like the MDN for when you don't have a computer.

Developing with Web Standards
A bit long, but still it has great chapters on accessibility, CSS, and web standards.

JavaScript: The Good Parts Loved it
Essential, concise, opinionated guide to JavaScript. Covers regexes, functions, objects, etc.

JavaScript Patterns Loved it
Every JS developer should read this book. It's a fantastic review of types, patterns and best practices.  Personally, I prefer the NPM Coding Standards for my server side JS, but this book is still essential.

CSS3 For Web Designers [e-book] Loved it
Read the entire thing on my iPhone. Great, short read. Extremely useful. Totally sold me on rgba().

Mobile First [e-book]
Decent essay on why mobile is becoming more and more important. Best given to someone who's not already steeped in mobile.

Supercharged JavaScript Graphics [e-book]
Stupid title, but plenty of interesting tidbits. Wished it were shorter and only covered Canvas.

JavaScript Web Applications [e-book] Loved it
The best book on web app fundamentals (w/backbone.js, spine, etc.) Covers MVC, HTML5 drag & drop and other APIs. Read it mostly at the gym and on airplanes.

Big Data Glossary [e-book]
Would be more useful as a PDF or even better a wiki.

  
Secrets of the JavaScript Ninja [e-book]
Lots of crazy stuff about prototypes, testing, etc. Been in progress since like 2009 and it's not finished, so we get updates every couple of weeks.

Android in Action [e-book]
Too long.

Hardboiled Web Design [e-book] Loved it
I wish I would have paid to get a hard copy of this, because it's beautiful. Great essay on why we should build cool websites now with some killer examples.



Hello Android
Perfect for Android beginners who want the basics. 

MongoDB: The Definitive Guide [e-book] 
Awesome guide for anyone doing anything with Mongo

Tapworthy [e-book] Loved it
Essential mobile UX & design. 

Recipes with Backbone [e-book]
A ton of great examples about design patterns and testing backbone apps.

50 Tips & Tricks for MongoDB Developers [e-book] Loved it
Essential MongoDB tips for n00bs like me.
 
Learning the iOS 4 SDK for JavaScript Programmers [e-book]
Basically worthless if you've read a beginner tutorial on using XCode. Used it once or twice as a reference for splitting strings into arrays.

Getting Started with GEO, CouchDB and Node.js [e-book]
I now know a little bit about GeoJSON and CouchDB. Kind of weird. Kind of cool. Don't know.

High Performance JavaScript [e-book]
Informative. Don't forget to strike a balance between performance, readability, and maintainability.

Responsive Web Design [e-book] 
Pretty nearly essential book about how the web is changing and how to react to it.

Mobile Web Roundup

This week was a huge week week for mobile web development.  Here are some quick summaries of the latest tools/announcements.

Adobe Shadow

Live preview your sites in your desktop and mobile.

Google Page Speed for Mobile (requires ICS)

If you're lucky enough to have Android for mobile you can now find out bottlenecks in your sites. It's hard to debug for mobile, so any help like this is welcome.

Sencha Touch 2.0

The best mobile-web framework just got way faster in Android and added a bunch of new features.

What iOS 5.1 and the new iPad mean for web developers

Of course the iPad 3 was announced this week and @firt reminds of how to get our sites ready with a quick blog post.

iPad3's Retina Display Will Wreak Havoc on the Web

A follow up to the above article with some warnings about serving up high-res images in every context.

Friday, March 2, 2012

Taking a Leap into Cloud9 IDE


After a lot of high profile coolness from the Cloud9 team, such as their work on Treehugger I thought it might be cool to check out the Cloud9 IDE. From what I understand it is an open source project with a paid version that offers additional features. Because it's written in node.js and JavaScript it's the first IDE I know of that really takes JavaScript seriously.

Some of things that I hoped to find in the IDE were:

  • JavaScript code completion
  • easy collaboration / code reviewing
  • instant previewing
  • use on any machine
  • git integration
  • built-in JSHint support via Treehugger
I went to the site c9.io and immediately signed in with my github account. It was smart enough to show me all of the projects I had on github. 




Initially, I was hoping to use this for my day job at oDesk, but I quickly ran into a hurdle: all of our files our stored on servers behind a VPN. I reached out to some people from the Cloud9 team and found out that at the moment I'm not able to use this service to do work that's behind a private VPN. I think it's also the case that you cannot do work locally either.

It's a good thing I have all of those github projects. One that I'm particularly excited about working on is a Words with Friends inspired word game called Words vs. Zombies.

I opened up the project and it seemed to clone the existing repo into one of the Cloud9 servers somewhere. It gave me a sort of shell as well as the files in the repo. From there I could preview my files, edit them, get good code feedback and more.



Sharing

At this point I was pretty much blown away. I'd heard about the collaboration features, so my first instinct was to look for the "invite a friend" option. I couldn't find it anywhere! I just wanted to show my friends how cool the experience was and hopefully get them to help me finish this project. There was no easy way to do it.

Doing Work

Okay the code editor is pretty much amazing. It doesn't seem to have that good of code-completion, but it does try to be helpful, though it's not super smart about typing or anything like that. I've heard that Web Storm offers decent JS code completion, so maybe I can check that out in the future. Despite the imperfect completion the error checking stuff is amazing. It's completely configurable and basically gives you built-in JSHint while you're coding. It's incredible and the speed and ease of typing in this web IDE is fantastic.  The syntax highlighting, customizable key-bindings, and other features really make this a great IDE.

Updating the Project

So after playing around with the current files, I decided I wanted to take my basic HTML/JavaScript project and turn it into a full-fledged Node.js project. First thing I tried to do was move my files around. I created some sub-directories and tried dragging some files into them. This didn't work. I tried moving them with the command line. That didn't work either. I tried in Safari and the dragging worked, but the files didn't appear to actually be moved. It was a mess. Giving up I thought I'd try and use express to create my files for me.  I tried things like this:

npm install express
(some response)

./node_modules/express/bin/express --help
./node_modules/express/bin/express . 


I basically got no response from any command I tried to run other than the initial npm install. So, I gave up, went back to Coda made the changes and pushed them to github.  I went back into my project and could not figure out how to pull the latest change. I tried re-loading the page, pressing the "refresh" button on the project, ran git pull, but nothing worked. git seemed mad because I had manually created files it wanted to create, but trying to remove files in the command line to prevent a conflict didn't actually seem to work.

Conclusion

I can't tell you how frustrating it was to not be able to do work in the IDE. The potential is great, the idea of it is amazing, but if I can't do work it's worthless to me. Despite that frustration I really see the benefit of the Cloud9 IDE and I can't wait until this thing is ready to use. I really think it will transform the way we do collaborative work. The server and preview features are amazing. I can run my app on their servers. That's huge. For a node.js app or even an html/javascript project there is no editor I've seen that can compete. They just need to work out a few bugs first.

Here's a more specific bug report I compiled if you're interested in what browser I was using when and what errors I received.

Tuesday, February 28, 2012

Sass Color Palette Generator


Inspired by EngineYard's Front-End Maintainability with Sass and Style Guides article about how helpful it is to keep track of your Sass color variables in one place I sought to automate the process a little bit. There are a bunch of ways that this could be done, but I took a really simple client-side approach. Just make sure your _scss file is publicly accessible and this code should generate an always-up-to-date style guide from your Sass (scss) color file. What do you think?




Saturday, February 25, 2012

Express.js Dynamic Helpers vs. Middleware


If you're build a site in express.js that relies on variables being set on every single page you may be tempted to use middleware and for a long time I've done something like this. It works fine.

// app.js file
var middleware = require('./util/middleware')
app.use(middleware.setLocals)

// middleware.js file
exports.setLocals(req, res, next) {
  res.local("currentPageName", applyFancyFormatting(req.url))
  res.local("luckyNumber", Math.floor(Math.random() * 100))
  next()
}

Express has something called dynamicHelpers that were built specifically with this in mind. It's a little bit simpler and in my opinion cleaner. It also doesn't make you next() after each one. You can put this anywhere you'd put an app.use statement. Check it out:

app.dynamicHelpers({
    currentPageName: function(req, res) {
        return applyFancyFormatting(req.url)
    },
    luckyNumber: function() {
      return Math.floor(Math.random() * 100))
    }
})

Or you can be like me and store them in different files like this:

// app.js
var dynamicHelpers = require('./util/dynamicHelpers')
app.dynamicHelpers(dynamicHelpers)

// utils/dynamicHelpers.js file
exports.currentPageName = function(req, res) {
    return applyFancyFormatting(req.url);
}
exports.luckyNumber = function() {
   return Math.floor(Math.random() * 100);
}


See it's great isn't it? What do you think?

Thursday, January 26, 2012

HTML5 Canvas Performance Tips


Here are some things we learned when building the i.TV grid with HTML5 Canvas, which was a fun experiment, but probably a terrible idea. You can decide if it was a good idea here: http://i.tv/guide.

1. Close your paths! (Avoid memory leaks)
2. Don't draw when you don't need to! (Improve FPS)
3. Profile! Profile! Profile!
4. Keep your canvas as small as possible. (Decrease memory use and improve FPS)
5. Check out requestAnimationFrame for animations. (Optimize FPS)
6. Mobile browsers don't do well with canvas animations (5 FPS FTW!)
7. Native scrolling > JS Scrolling!
8. DOM = slow, Canvas may be slower.

Here are some other techniques I've heard an help as well:
9. Typed arrays http://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/
10. Consider variable re-use to prevent garbage collection. (Smoother animation)

Here are some other general tips for dealing with Canvas:
11. Make sure to handle touch events for mobile
12. Test your offset code in multiple browsers as it can get a little hairy

Friday, January 20, 2012

LESS is awesome

Lately we started using LESS for some of our web apps at i.TV. I just wanted to iterate some of the benefits and a few of the downsides.  Initially we were using connect-less to compile our less dynamically when the app is started. We still use this for our development environment but now we use lessc in our build scripts to compile it before hand. It's a little more stable that way.

AWESOME BITS

  1. We can use constants for z-indexes to prevent the endless desire of devs to make them higher forever. z-index: @z-modal > z-index: 999999999
  2. Separate .less files for each UI widget makes for awesome code organization. This is HUGE!
  3. Makes CSS3 browser prefixes a little more manageable.
  4. Using variables for color names makes it a lot easier to make sure you're on the same page with a designer.
  5. CSS code re-use FTW!
  6. Mixins are okay.
NOT-SO AWESOME BITS
  1. Weird issue with using the @arguments variable where there are commas. (See: https://github.com/cloudhead/less.js/issues/301)
  2. connect-less initially had some trouble including files with includes inside them, but I think it's fixed now.
  3. It would be really nice to be able to just include a full directory instead of manually including all x number of files (within the widgets directory for example) manually.
  4. LESS doesn't encouraged any specific structure or good patterns, which is fine, but you sometimes get really excited about using the nesting feature, because it seems so convenient and clean, but it can actually can make your code less re-usable if you don't do it right.

NodeUp 11 Commentary


Yesterday, I listened to the nodeup podcast (http://nodeup.com/eleven) about databases and node.js. It was pretty epic. I wanted to write up my thoughts and summarize it as best as I could. There are some great things going on in the node.js and database worlds and I have my opinions about them too. Here we go...

1) Postgres

People like Postgres if they need relational database. This is because the community is really cool and they add lots of features (every feature!) There's even a JSON-store feature Postgres is working on. Yammer is the only known (big) company to be using Postgres with node in production, but the node-postgres library is supposedly pretty decent.

2) Database people hate MongoDB, developers love it

Supposedly, 10Gen is the hermit of the database world. They don't hang out with other database people, but what they do is listen to customers/end-users more than database engineers, so it's very developer friendly, but database people think it's technically inferior (??). People say "Mongo loses data", presumably because journaling used to be off by default, but Mongoose has become the de-factor ORM of simple node websites and MongoDB with node is obviously really popular. For the record I LOVE MONGODB.

3) Redis

Redis has a lot in common with node. It's single threaded and fast, but it doesn't scale horizontally very well. It's also really really fast and has really good node support. There actually aren't a lot of good use cases for Redis, because it doesn't scale up super well. Because it's in memory it's going to be faster than most other databases. DShaw wrote a redistore for socket.io, but it's unclear how well it can scale, pretty darn well though, apparently. It does have a pubsub feaure that can be subscribed to with a regex (?), which people think is really cool.

4) CouchDB

So the node community has been huge on CouchDB for a long time. Isaac S. uses it for NPM and a lot of people use it for other things. Pros: HTTP Interface super easy to use, map reduces are incremental and therefore super fast. Cons: It scales terribly. Imagine 1,000,000 users each with their own DB doing master->master replication. It will blow up. A ton of data or a huge number of users don't make a good fit for couchDB. That being said, if you have less users and less data (say in the thousands of things) and want to experiment with master->master replication for example from a mobile app to the web it could be really cool. Again, it can actually be really slow.

5) Riak

Riak does map reduces really really slowly. They were joking that they should be called "work orders" instead of jobs. Someone, maybe it was Voxer? is using them heavily in production and converted their super slow couchDB instance to Riak and they found that it worked way better. Riak is a huge key/value store than is highly available and easy to scale horizontally. It's pretty simple and doesn't have a lot of fancy features, but it works well if you're trying to keep it simple. It has an HTTP interface (like couchDB). If you're trying to be fancy and do a lot of complex map reduces your life will suck and it would be faster to use carrier pigeons.

6) The future

A lot of people are excited about building databases in Javascript. Isaac S. noted some technical limitations of JavaScript, but everyone else was arguing that there are limitations in any langauge and the ones JavaScript has (not good with large numbers, etc), may prove solvable or less important. It seems the idea is that building databases isn't that hard and people (with some helpful tools) will likely continue to build custom databases for their own needs. Awesome.

Thursday, January 19, 2012

Mongo Map Reduce Vs. Query

Just had something come up today where I had to take a bunch of users from an existing collection and put some of their data in a new collection with new IDs. Here are two approaches that do the same thing, with wildly different speeds.


Map reduce is way faster than looping over a really fast query for this kind of work!

Tuesday, January 17, 2012

File upload with express.js


Uploading files with express.js is insanely simple!

FYI, there's something special called req.files when you upload multipart forms. In this case I upload the file with a form field with the name of "file".



I found this stuff out here:
https://groups.google.com/forum/#!topic/express-js/vDmtdWMx5tY


Monday, January 16, 2012

Installing node.js on Linode (Ubuntu 10.04)

Never really used Ubuntu for a server before.

Here's I was able to get it setup to run node.js and mongoDB.

Node:

apt-get update
apt-get install build-essential
apt-get install openssl
apt-get install libssl-dev 
cd /root
mkdir builds
cd builds
wget http://nodejs.org/dist/v0.6.7/node-v0.6.7.tar.gz
tar xzvf node-v0.6.7.tar.gz
cd node-v0.6.7
./configure
make
make install

Mongo:

Follow these instructions:
http://www.mkyong.com/mongodb/how-to-install-mongodb-on-ubuntu/



cat 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' >> /etc/apt/sources.list
sudo apt-get update
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
sudo apt-get install mongodb-10gen