High Performance Browser Networking

Today I learned that flushing the HTML document early can improve performance by allowing the browser to fetch resources as soon as possible.

Also, if you’re interested in learning more about web performance, High Performance Browser Networking is available to read for free on O’Reilly.

The HTML document is parsed incrementally by the browser, which means that the server can and should flush available document markup as frequently as possible. This enables the client to discover and begin fetching critical resources as soon as possible.

Google Search offers one of the best examples of the benefits of this technique: when a search request arrives, the server immediately flushes the static header of the search page prior to even analyzing the query. After all, why should it wait, the header is the same for every search page! Then, while the client is parsing the header markup, the search query is dispatched to the search index, and the remainder of the document, which includes the search results, is delivered to the user once the results are ready. At this point, the dynamic parts of the header, such as the name of the logged-in user, are filled in via JavaScript.

Source: High Performance Browser Networking

Print PHP Stack Trace

I was having a bit of trouble tracking down exactly where a method was getting called from today.

Usually a search in my project directory will turn up the result very quickly, but I wasn’t having luck with PHPStorm for some reason.

So, the next best thing was to get a stack trace so that I could get the last few functions that had been run. I don’t do stack traces much in PHP, so I had to track down the code to use.

Of the few options to use, this seemed to be the easiest to use and remember.

$e = new Exception;

// Output the stack trace to the browser
echo $e->getTraceAsString();

// Send stack trace to error log
error_log( $e->getTraceAsString() );

And if you’re wanting more verbose output, including the arguments that were passed to each function, try this.

$e = new \Exception;

// Recursively print the stack trace
print_r( $e->getTrace() );

// Log the stack trace object
error_log( print_r( $e->getTrace(), true ) );

Creating JavaScript Keyboard Shortcuts with jQuery

I recently added a keyboard shortcut to a project I was working on.

And while I have used the jQuery Hotkeys plugin for adding keyboard shortcuts recently, I didn’t use a plugin for this project since I only needed a single keyboard shortcut.

Taking a large bit of inspiration from Krasimir Tsonev, who also documented his solution, I came up with this:

(function( $ ) {
var $doc = $( document );
$doc.ready( function(){
$doc.on( 'keydown', function( e ){
if ( ! $( e.target ).is( ':input' ) ) {

// props rauchg for pointing out e.shiftKey
if ( 87 == e.which && e.shiftKey ) {
// `shift` and `w` are pressed. Do something.
}
}
});
});

})( jQuery );

Explanation

First, I create an anonymous function wrapper and invoke it while passing jQuery as a parameter. This allows me to use the $ syntax for jQuery without worrying about collisions with other libraries.

Then, after the DOM has loaded, I attach a keydown event handler to the document. Before I run any logic though, I check to make sure that we are currently not within any input type. This is important as I don’t want to trigger keyboard shortcuts when a user is typing.

After the code ensures that we are not in an input, I check to see if both the shift key and w have been pressed. If so, do some magic!

Do Yourself a Favor, Turn On Chrome's Warn Before Quitting

As a developer, keyboard shortcuts are a necessary part of life. And as a web developer, I use several shortcuts within Chrome as well:

  • ⌘ + t: new tab
  • ⌘ + ^ + i: open developer tools
  • ⌘ + shift + {: shift one tab to the left
  • ⌘ + shift + }: shift one tab to the right
  • ⌘ + w: close current tab
  • ⌘ + q: quit Chrome

And if you’ve used the above shortcuts for any period of time, you’ve likely accidentally quit Chrome when you meant to close the current tab. :facepalm:

This used to happen for me at least once a week… until I found Chrome’s Warn Before Quitting option.

Chrome warn before quitting

This obscure gem can be found under the Chrome menu. When enabled, you will need to hold ⌘ + q to quit Chrome.

Copy to Clipboard in Google Chrome Console

When developing for the web, sometimes I want to JSONify an object to throw into Sublime Text for an easier look or maybe to compare two separate objects.

While it’s easy to log an object in Google Chrome, the issue I have is easily getting that from the console to Sublime Text.

After doing a bit of searching, I found that Google Chrome has a copy function that will copy any text to the clipboard.

Here are a couple of ways that you could use this function:

To copy any string, simply use

copy( "some string here" );

To copy a JSONified object, you could use something like:

copy( JSON.stringify( object ) );

Update Backbone Model with No Change Events

I recently needed to update an array of models to add a “reflowed” attribute to a comment which would act as a flag to show that the comment had been reordered.

Doing it Wrong

When I was working through this issue, the first thing that came to mind was that I could update the model attributes myself.

This is possible with the following syntax.

model.attributes.attribute = value;

But, this isn’t good software development. So, I trashed that idea.

The Backbone Way

The Backbone way to update a model is:

model.set( { attribute: value } )

But, by default, this will trigger a change event on every changed attribute. For my use case, triggering change events for several models wasn’t necessary.

Looking into the annotated Backbone source code, I noticed that I could pass in an options array that set silent to true. This makes the model update look like this:

model.set( { attribute, value }, { silent: true } );

Get Most Visible Element on a Web Page

Recently, I was working on updating keyboard shortcuts for o2 and came across a unique shortcut.

When pressing r, we wanted to open the reply box for the most visible post. When I first started thinking about this requirement, I found myself thinking: “How the hell can I determine what the most visible post is?”

Attaching to Scroll Event

One of the first things that crossed my mind was that I could attach to the window scroll event and then update a mostVisiblePost variable as needed. For example, when a scroll event occurs:

  • Get all posts on the page
  • Check which posts are in the viewport
  • Get the offsets for each and try to determine which is most visible.

I wasn’t quite fond of this method because it could make scrolling janky and seemed prone to error.

An Alternative Surfaces

While I was reading Javascript: The Definitive Guide I came across the JavaScript method elementFromPoint(x,y).

As I thought more about getting the most visible element on the page, I came up with the idea of creating a grid of points that covered the page. I could then get the element at each point and traverse up the DOM to find which post was at that point.

After thinking through this a bit more, I decided to go for it and came up with the following solution:

// Note that Underscores and Backbone are being used here.

//Let's create a grid of points in the top half of the viewport.
var viewPortWidth  = $( window ).width(),
    viewPortHeight = $( window ).height(),
    xCoords = _.map( [ .2 , .4, .6, .8 ], function( num, key ){ return num * viewPortWidth; } ),
    yCoords = _.map( [ 0, .1, .2, .3, .4 ], function( num, key ){ return num * viewPortHeight; } );

/*
* For each coordiante pair (x,y), get element at point,
* traverse up to find a post, and add post ID to elems.
*/
var elems = [];
_.each( yCoords, function( y ){
    _.each( xCoords, function( x ){
        var element = $( document.elementFromPoint( x, y ) ),
            closest = element.closest( o2Keyboard.threadContainer + '.post' );

        if ( closest.length > 0 ) {
            elems.push( closest.attr( 'id' ) );
        }
    });
});

// Find most frequent (mode) post ID in elems array.
// Thanks Matthew Flaschen - http://stackoverflow.com/a/1053865
if ( elems.length > 0 ) {
    var modeMap = {};

    var maxEl = elems[0],
        maxCount = 1;

    _.each( elems, function( el ){
        if ( modeMap[ el ] == null ) {
            modeMap[ el ] = 1;
        } else {
            modeMap[ el ]++;
        }

        if ( modeMap[ el ] > maxCount ) {
            maxEl = el;
            maxCount = modeMap[ el ];
        }
    });
}

For the purposes of O2, we defined the most visible post to be in the top 40% of the viewport. So, we created an array of y points from 0-.4 times the viewport height. We then created an array of x points that covered most of the viewport.

Once we’ve created the xCoords and yCoords arrays, we then loop over these two arrays and get the element at each (x,y) coordinate pair. In this example, we will be creating 20 unique (x,y) coordinate pairs. You can fine tune that for your needs.

Once we have the element at each point, we traverse up the DOM to see if there is a post. If there is, that post’s ID gets added to an array.

We then take a mode, essentially finding the post with the most hits, on the elems array and that is the most visible post.

Questions or Comments?

If you have any questions or comments about this method, feel free to leave a comment below.

Remove .sass-cache and node_modules from Sublime Text

I’ve recently been playing with Foundation, Sass, and Grunt. And while each of these are powerful tools in their own right, they are quick to clutter up a project.

Grunt creates a node_modules directory while Sass creates a .sass-cache directory.

But don’t worry, because lucky users of Sublime Text have a simple fix.

Add .sass-cache and node_modules to Folder Excludes List

To exclude a directory from showing up in Sublime’s search and in the sidebar, all you need to do is add it to the folder_exclude_patterns key in your user preferences.

To do this:

  • Click Sublime Text → Preferences → Settings – User
  • Add the snippet below
{
"folder_exclude_patterns": [".svn", ".git", ".hg", "CVS", ".sass-cache", "node_modules"],
}

This line of code should ignore the .sass-cache and node_modules directories as well as common source control directories.

Gravity Forms Review

Gravity Forms is a form building plugin that simplifies the task of building attractive interactive forms for your WordPress websites. Sure, if you’re just looking for some basic contact form functionality, then there are several great contact form plugins out there for $0. But, if you’re looking for a contact form plugin that has extra features, such as:

  • Submissions stored and viewable on WordPress Backend
  • Multi-page forms
  • Post Field
  • Advanced fields for Name, Email, Address, etc.
  • Drag-and-Drop form creation
  • Create dynamic notifications using merge tags
  • Ability to add custom logic through hooks
  • Conditional logic to hide or show fields
  • and MUCH MORE!

I can imagine and have seen or personally used Gravity forms to create:

  • A quiz that would send a custom notification to the user based on the answers that were given.
  • A multi-page application form that lets the user know how far they are in to the application process.
  • A small e-commerce store that sells products, collects payment, and then delivers product

Now that you’re acquainted with some of the features of Gravity Forms, let me run you through the backend so you can see for yourself how easy and intuitive it is to create your own custom forms. This plugin really is a time-saving beast!

Above is a picture of the form builder within gravity forms. This is one of gravity forms biggest selling points, and why I recommend it so highly in this review. If you manage multiple websites or multiple forms on one website, then this is going to be a killer time-saving feature. You can simply click each box, the box will slide down with some extra options, and then you can choose between these options which include things such as custom logic, required field, or values.

Above is a screenshot of the gravity forms notifications builder. The notification builder allows you to create custom emails that are sent to either the website admin (or other appropriate persons) or the person who submitted the form. By customizing a submission notification we were able to create a quiz with a dynamic email that depended on what the user submitted in his questionnaire. Try doing that with a free plugin…

On top of some of these obvious features, gravity forms also allows you to advanced logic through accessing hooks and filters. An example of this would be to access the pre_submission hook in order to compute some response based on the user’s input. Another example would be writing some custom code to interface gravity forms with a 3rd-party service. This really expands gravity form’s functionality by essentially allowing you the ability to manipulate the submitted data however you need.

Bottom Line

It took a while for me to bite the bullet and drop the $199 for a developer’s license of Gravity Forms. But looking back, I am glad that I did. In the past few months alone I have used Gravity Forms on several websites, and have saved tons of time over having to write custom code from scratch. If you run any serious WordPress website, I highly recommend you get Gravity Forms.

How to Add a Google Map to your Website with Geocoding

Inserting Google Maps into a website is CRAZY easy! Usually what I would advise someone to do is to:

  1. Go to Google Maps
  2. Search for the address that you want to show on your map
  3. Grab the embed code
  4. Insert embed code in your website

Could it get any easier? Well, that really depends on what your development needs are. I recently completed a project for a client that owned a mobile BBQ restaurant. This client wanted a map on his website that he could easily update with the location of his mobile smoking pit. I didn’t think it made much sense to make the client do the 4 steps above just to update his map… So I decided to look into Geocoding a google map. This way, all my client had to do to update his map was to login and change the address.

For those that do not know, geocoding is essentially the process of taking an address and turning that into latitude and longitude coordinates. Google maps has geocoding baked in – FOR FREE!

Without further ado, below is some code on using geocoding with Google Maps.

This code goes in the head.

<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>

This code can go anywhere in the body.

<div id="map" style="width: 413px; height: 300px;"></div>

<script type="text/javascript">// <![CDATA[


var mapOptions = {
    zoom: 16,
    center: new google.maps.LatLng(54.00, -3.00),
    mapTypeId: google.maps.MapTypeId.ROADMAP
};

var geocoder = new google.maps.Geocoder();

var address = '3410 Taft Blvd  Wichita Falls, TX 76308';

geocoder.geocode( { 'address': address}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
        map.setCenter(results[0].geometry.location);
        var marker = new google.maps.Marker({
            map: map,
            position: results[0].geometry.location
        });
    } else {
        alert("Geocode was not successful for the following reason: " + status);
    }
});

var map = new google.maps.Map(document.getElementById("map"), mapOptions);
// ]]></script>

You can update the size of the map by changing the width and height values of the #map div. To change the starting zoom level, change zoom. You can change the type of map by changing mapTypeId. And most importantly, you can change the address by changing the value in var address.

You should be able to plug this code in to your website and be good to go. This code will take the address in var address, Geocode it using Google, and then center the map with a marker at the address specified.

This is a fairly simple example of Geocoding, but you could take this code and make a map that will dynamically update with user input. In a future post, I will discuss how to integrate Geocoding into WordPress so that you can easily create and edit maps without having to get latitude and longitude coordinates.