Static file web servers

Testing a static website can be done simply by opening the HTML files in a web browser, but for some functionality to perform correctly, such as local AJAX calls, the files need to be served from a web server.

Alternatively, you may want to check out some static files on your mobile device. You can do this easily by starting a simple web server for the project and navigate to your computers IP address with the given server port.

Python Server

The easiest way to do this on UNIX based systems is to use the Python Simple HTTP Server, like so:

python -m SimpleHTTPServer 8080

Run this command in the same directory as your project from the terminal, then point your browser to http://localhost:8080.

This is a great way to get a server running in seconds, for basic testing, but I have found that as the number of files in the project increases, the stability of the server decreases. Often files will not be passed to the client and 404 errors are encountered. For these reasons I have investigated a stronger solution that is still simple to setup. This leads me to Node.JS.

Node Server

Node.JS is no stranger to web servers, in fact this is often the primary task of a Node application.

"Connect" is a Node.JS middleware application that makes the creation of simple web servers trivial.

To get Connect running, first install it via npm:

npm install -g connect

Here is a web server that can be used, simply paste the code into a file called "server.js" in your project's root directory.

var connect = require( 'connect' ),
  http = require( 'http' );

app = connect()
  .use( connect.logger( 'dev' ) )
  .use( connect.static( __dirname ) );

http.createServer( app ).listen( 8080 );

Finally run the server from the terminal like so:

node server.js

If no error was received, the server is running and files can be viewed by browsing http://localhost:8080, just like in the Python example.

I have not had any trouble with the Connect version of my server and it comes built with a nice development logger, showing what files were requested and with what status. This output can be viewed live in the terminal window as requests come in.

Connect Server Dev Log

The most efficient CSS reset pattern

I've recently been investigating web page performance and focusing on CSS efficiency to see where performance gains can be made. After using the Chrome CSS profiler, I came to the conclusion that my "reset" CSS file was taking a long time to parse and match selectors, slowing down the browser paint process.

Reset CSS files are used to normalise default DOM element styles, so that your custom styles will work effortlessly across all browsers.

Naturally then, the reset CSS must target many elements in order to change their style. However, how can this be done in the most efficient manner?

This useful website, CSSReset.com provides 5 popular reset methods for you to use.

For my experiment I have used each of the provided codes and implemented them in turn into my web page. I then run though a "script" of accessing certain parts of the website while the Chrome CSS profiler is running and measure the results of each. I have performed the script multiple times with each code snippet to ensure a valid result.

In short, my findings are: normalize.css has the best efficiency, by quite a long way, with YUI coming in second place.

The reason normalize.css is highly more efficient is that unlike the other scripts, it does not select all DOM elements in a single comma separated declaration, but breaks up the declarations into smaller segments.

Due to my project not using many DOM elements, the browser can skip parsing for many of these declarations making overall performance better.

This is interesting as normalize.css is the least used code snippet on the website, at the current time of writing.

I'd be interested to follow up on this and here any arguments for or against using a reset CSS in this manner.

Improve page performance with optimal CSS

There are certain CSS best practices that should be followed in order to increase CSS performance in the browser. These will help the browser to perform less DOM parsing and reduce the time of repaint events.

1. Browser reflow and repaint

If you are unfamiliar with the concepts of reflow and repaint, here are some articles that will get you up to speed:

2. Remove unused styles

Simply having styles that aren't used causes the browser to search the DOM for matches needlessly. This is wasted processor time. Additionally, the CSS file will have a higher page weight that is needlessly sent over the wire to the client.

It may not seem to make a huge difference but removing dead CSS code will greatly increase performance and additionally improve the project stability and maintainability.

Fix frozen OSX gestures without restart

Occasionally when working with OSX the magic mouse/trackpad gestures will stop working at random. This appears to be caused by 3rd party software interfering with the Dock, so restarting it will usually fix this problem rather than performing a computer restart.

You can restart the Dock program by opening a terminal window and issuing the following command:

killall Dock

Check size of localStorage usage in Chrome

localStorage is a great tool for JavaScript developers to persist information across multiple sessions. Due to its simple API, large browser support and and higher reliability than cookies, it can easily lead to the situation of overusing localStorage.

Since localStorage has a maximum size of 5MB the following snippet will help inspect what localStorage keys are being used and how much size is being allocated to each.

To give credit, I have taken the method here and added a total counter.

var total = 0;
for(var x in localStorage) {
  var amount = (localStorage[x].length * 2) / 1024 / 1024;
  total += amount;
  console.log( x + " = " + amount.toFixed(2) + " MB");
}
console.log( "Total: " + total.toFixed(2) + " MB");

Simply run this in the Chrome console or create a bookmarklet from the following code (Right click bookmark bar > Add Page > Copy the code as "URL")

javascript:var total = 0;for(var x in localStorage) {  var amount = (localStorage[x].length * 2) / 1024 / 1024;  total += amount;  console.log( x + "=" + amount.toFixed(2) + " MB");}console.log( "Total: " + total.toFixed(2) + " MB");

Which will give a similar output:

Matches = 0.40 MB
Matches_timestamp = 0.00 MB
Teams = 0.19 MB
Teams_timestamp = 0.00 MB
Total: 0.59 MB

OSX Convert image formats in terminal (GIF to PNG)

Answer found from Superuser: http://superuser.com/questions/571003/how-to-convert-gif-files-to-png-or-jpeg-in-os-x-with-command-line

Using the sips command, almost any image format can be converted into another, like so:

cd /directory/with/gif/images/
mkdir pngs
sips -s format png ./*.gif --out pngs

This will create new images with a png extension in the pngs subfolder to match the gif version.

Dynamically append LESS.js stylesheets

Here is a function that can be called to dynamically apply a LESS.js stylesheet to the DOM after the page has finished loading. The following code snippet uses jQuery for convenience.

 function loadLESS ( filename ) {
    // If LESS isn't available, do nothing
    if ( !window.less ) { return;}

    // Create LESS link and add to <head>
    var $link = $("<link type='text/css' rel='stylesheet/less' />");
    $link.attr("href", filename + ".less");
    $("head").append( $link );

    // Notify LESS that there is a new stylesheet
    less.sheets.push( $link[0] );
    less.refresh();
}

The important parts are after applying the new link tag to the head section, the raw DOM node $link[0] must be added to the less.sheets array and then refresh called to apply the changes to the web page.

Also remember that the rel attribute for the link tag must be set to "stylesheet/less" rather than just "stylesheet".

How to handle user time zones in Ruby on Rails

Displaying a date time correctly for users around the world is made very easy with Ruby on Rails. The time zone can be set per request and loaded from the logged in user's configuration. All of the default time zones are already built into Ruby on Rails and provides the ability to add custom ones, for custom cities too.

Model

First we need to allow the user to choose their desired timezone, so a migration is required:

class AddTimezoneToUser < ActiveRecord::Migration
  def change
    add_column :users, :timezone, :string
  end
end

Then of course this change needs to be applied to the database.

$ rake db:migrate

Then ensure the User model has timezone under its accessible attributes

class User < ActiveRecord::Base
    attr_accessible :email, :name, :timezone, :created_at, :updated_at
end

View

Next we must provide a field to choose from. In this example I am simply adding a new form field to my users/_form.html.erb partial. Here we use the built in time_zone_select form helper.


Which will automatically give a result similar to the following screenshot. The select menu is prefilled from the Rails ActiveSupport::TimeZone class.

image

Controller

Lastly, an application controller before_filter is required that will set the time zone for each request.

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :set_timezone

  private

  def set_timezone
    tz = current_user ? current_user.timezone : nil
    Time.zone = tz || ActiveSupport::TimeZone["London"]
  end
end

Here current_user points to the logged in user record. This is the default behavior when using the "devise" gem. If the current user does not have a timezone, I choose to fallback to GMT (London) time. This can be changed for whatever default makes sense in your given project.

Append an HTML string to the DOM without a JavaScript Library

In the event where appending new nodes to the DOM via JavaScript is required but there is no access to a library such as jQuery or Prototype.JS, this handy snippet allows an easy librabry-like API with a tiny amount of code:

 function append ( elString, parent ) {
    var div = document.createElement( "div" );
    div.innerHTML = elString;
    document.querySelector( parent || "body" ).appendChild( div.firstChild );
 }

This snippet can be used easily:

// Append a link tag to the head
append( "<link rel='stylesheet' href='css/foo.css' />", "head" );

// Append a parapgraph to the body
append( "<p>My text</p>" );

// Append a new list item
append( "<li>Cheese</li>", "ul.shopping-list" );

Install Node.JS on Debian Wheezy

Official Method

The official Node.JS install guide recommends manually downloading and building the Node.JS package for Debian. This can be done using the following set of commands:

sudo apt-get install python g++ make checkinstall
mkdir ~/node_js_src && cd $_
wget -N http://nodejs.org/dist/node-latest.tar.gz
tar xzvf node-latest.tar.gz && cd node-v*
./configure
checkinstall
sudo dpkg -i node_*

This install method should work fine but will take a long time to complete on the Raspberry Pi's hardware. For this reason I experimented a little and found a quicker install method that doesn't require a manual compile, by using the Ubuntu package.

Ubuntu Method

This install method will be much faster than the official method but is not designed for Debian Wheezy, so use at your own risk! Personally I have not had any trouble with my node install yet but I cannot guarantee this will be the case for anyone else.

sudo apt-get update
sudo apt-get install -y python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js

At this point the file with the new repository details must be edited. Open the file: /etc/apt/sources.list.d/chris-lea-node_js-wheezy.list with a text editor like vim and change the word "wheezy" to "lucid". Thanks to Ken Yap for this hint.

Now, go on and finish installing Node.

sudo apt-get update
sudo apt-get install -y nodejs

© Blake Simpson, 2012 – 2018