UserScript: Showing Page Titles & URLs in Google Analytics

Often, when you're using Google Analytics, you want to be able to segment by the page's title, but there is no default way to do this with Google Analytics.

Well, a couple of hours ago I started catching up on my reading in Google Reader, and I noticed a blog post from LunaMetrics titled "Showing Page Titles & URLs in Google Analytics", and that post pointed out exactly how to segment by page title.

So, I took a couple of minutes and wrote a userscript to add this dimension to the 'segment by' drop down with a userscript so that you can easily segment by page title, without having to think about how to do this. Here's the code:

This userscript is available on userscripts.org as well, here: Google Analytics Page Title Segmentation

Enjoy!

Easier GitHub Fork Switching

There are many issues I have with my favorite site to host git repositories, GitHub, but today I decided to solve one of them.

The Problem

When you are on a page in one of your project forks on GitHub for say some file in the repository, and you want to switch to see the same page for the project that you forked from, then you have a number of clicks and page loads ahead of you. My feeling is that there should be a single link that allows you to do this, and vice versa.

[More]

The Principle of JavaScript Illumination

Every web developer knows that their site should work when the site's users disables JavaScript, but I constantly find this principal is violated when it is simple thing to obey. When web UI developers violate this principal it shows an extreme laziness and a failure to understand good practices on their part; this can greatly worsen the user experience. So, I'd like to articulate what I'm going to call The Principle of JavaScript Illumination which is an idea I haven't seen articulated yet, but that everyone knows in their gut they should do, and yet I hardly ever see this principal adhered to in practice.

Definition

The Principle of JavaScript Illumination is a simple one, if some user interface element will not work when JavaScript is disabled, then have JavaScript add the element.

Implications

If you have a user interface (UI) element that uses JavaScript, then make sure there is a default functionality that will work when JavaScript is disabled. If the UI element cannot work at all without JavaScript, then you should make JavaScript add the element, this way if JavaScript is disabled then the user will not see UI elements that will not work, causing a bad user experience.

Examples

Facebook Chat

When you log in to Facebook with JavaScript disabled, the chat widget is displayed to you on the bottom right of the screen, but it doesn't do anything, it's completely useless to you and it's just in the way, so why the heck is it displayed to the user?

Kampyle

Kampyle provides some widget code for anyone to put on their site which adds a "Give Feedback" button to the bottom right of the user's screen, which the user can click on to give feedback for the site. The trouble is, when JS is disabled, or when the user uses NoScript to block assets from the kampyle.com domain, then the button doesn't work (see ROIRevolution's site for an example of this), so why the heck is it displayed to the user?

Conclusion

Be a good web citizen, and a smart web developer by obeying The Principle of JavaScript Illumination, because it's the right thing to do and because you're users will thank you for it.

My Solution to the Alt-Tab Problem

While I was reading through my subscriptions the other day I noticed Aza Raskin's recent blog post, "Solving the Alt-Tab Problem", where he describes issues with the current alt-tab implementation which orders the applications by Most Recently Used (MRU), please take a moment to read his very detailed post before continuing with this post.

I thought this was a very interesting problem. I've personally always hated the way that alt-tab works, and hardly ever use it because of this, even though I know it should be helpful, it just is not. So, I thought a bit about this in the back of my mind and I finally came up with a solution that I like, and I haven't seen it mentioned yet so I will explain it here, but first I want to list the issues Aza mentioned with MRU and my main issue with it, then I'll quickly describe some of the other solutions I've heard, and finally I'll give you my solution.

Issues With MRU

  • Switching between 3+ applications is brutal (see Aza's post).
  • Constant seethings of MRU confound a person's strong spatial memory (see Aza's post).
  • Thinking about how to switch tabs rips a person's attention from their real task (see Aza's post).
  • If a user presses alt-tab, then decide they made a mistake and want to return to the application that they were using before pressing alt-tab, then they need press alt-shift-tab, because if they just let go of the alt key, then they will be switched to the last application that they used (my issue).

The first and last issues listed above are the two main reasons why I never use alt-tab today.

Proposed Solutions

Aza's HRMRU

In Aza's post he mentions a possible solution, which he admits he doesn't think is great, which is a habit respecting design which he dubbed HRMRU. HRMRU is basically a prediction algorithm which allows the computer to try to predict the order that you desire (read his post for a full explanation). He mentioned the possibility of using a Markov model, but an HRMRU could be implemented an infinite number of ways.

The way that HRMRU is implemented doesn't really matter imo, throughout my time at UBC studying statistics and computer science (with a focus on machine learning), and the rest of my life, I haven't seen an algorithm that would be suitable to implement HRMRU, indeed I wouldn't trust a human being with all of the time in the world to predict my habits (in this context). Furthermore, if some HRMRU method were implemented, then in order to switch applications in the blink of an eye I would have to predict the predictions made by the HRMRU implementation, and that would a terrible user experience. My last issue with this solution is that it would bog down my machine; I absolutely hate it when applications use cpu cycles when it is not necessary, when that happens I start losing control of myself, and I seriously want to start bitching at the developers, because it's what they deserve (if they didn't give me the option of turning their crappy code off).

Lukas Mathis' Solution

I'm not sure what to call Luka's solution, but he explains it here. Basically his idea is to have the currently open application in the second position, and the last application opened in the first position, and the rest are listed in positions 3 and on. Read his post for full details.

This solution would solve the last issue listed above, but does not solve the other issues.

Others

In the comments of Aza's post I saw a number of other options/~solutions mentioned, some of which I think are worth mentioning here, which I'll do as best as I can. There are other solutions mentioned in the comments of Aza's post though, so don't assume this is a comprehensive summary, because it's quite far from that.

Constant Order

This solution is very simple, the applications are listed in the same order that they were opened.

Truth be told I think this was the best solution mentioned in the long list of comments on Aza's post, it's even better than MRU, it takes care of all issues except for allowing quick application switching, which happens to be very important.

alt-tab-mouse

This is implemented on OSX and the windows alt-tab power toy (maybe winXP too I haven't checked). It's a simple solution, the user presses alt-tab, then uses their mouse to select the desired application.

This is a great solution, there is no doubt about it, but switching from keyboard to mouse all of the time is a terrible user experience, so a fully keyboard based solution is a must have, so this is only really part of a solution. Also, switching between 3+ applications in the blink of an eye is not possible with this solution, so it's just not enough.

Application Grouping (Activity Grouping)

I didn't really bother figuring out how this solution is supposed to work, as I understand it though you'll be able to group applications together, then some how you're able to switch quickly between applications..

Albeit, I don't fully understand this idea, and may not fully appreciate it, but it doesn't sound great to me. Presumably I would have to switch group/activity, then choose an application, and how I would do this isn't clear to me. This does sound like it could be an option, but it sounds like switching between 3+ apps may still be an issue, or at least it's not something that you could do in the blink of an eye.

Number the Listed Applications

This idea is simple, number or letter each open application (with 0-9 and a-z, then nothing). This way a user can alt-tab, then hit the number/letter associated to the desired application.

I like this solution.

My Solution

To start with I think a few of the solutions mentioned above should be implemented, namely the alt-tab-mouse solution, the lettering of the first 26 open applications, and ordering the applications by the order that they were opened.

Obviously, I think that if the user presses alt-tab then lets go of these keys, then I don't think the application should be changed. Also, I think the user needs to be able to customize the order that the applications are ordered (the default ordering would be the order they were opened, and this would be customizable on the fly), so the question is how should the user be able to do this? well I thought of a couple ways, one is to use the mouse to change the order via drag & drop, and the keyboard method I thought up was to incorporate the ctrl key. To change the order of the applications by keyboard only a user would simply move the selection box to the application that they want to move (so alt-tab or alt-shift-tab to the application, while holding the alt key) then they hold the ctrl key along with the alt key which 'picks up' the application, and then the user could press alt-ctrl-tab to move it right, or alt-ctrl-shift-tab to move the application left.

Now when the user presses alt-tab the currently focused application will be selected, and they can quickly alt-tab to switch to the application to the right, or alt-shift-tab to switch to the application to the left, and they can manually alter the order of the applications to something suitable for them at that moment in time.

There should also be a separate key for switching back and forth between the last application used, I don't care what it is, maybe alt-tab-`, it doesn't matter I think. It would also be nice if the last application used was easy to spot in the alt-tab list somehow, so that the user could slow down and ensure that they are going to the right application before switching, so in this case they would press alt-tab, then hold tab see the last application used, and then press ` to select it and then they just let go of the alt key to switch to it.

Finally, I've got another set of hotkeys that I think will help, which are to use the numbers 1-5 or 1-9 such that the user can quickly switch to the application that is some # positions away from the currently application in the alt-tab list by pressing alt-# or alt-shift-# (ie: pressing a number while holding alt) which would select the application some # of positions to the right or left of the current application (ie: pressing tab while holding alt is equivalent to pressing 1), and if the desired application is 100 positions away or whatever, then they just press alt-tab-5 20x, or reorder the list so that they don't have to do that every time. This may sound bad for a large number of applications, but that'll be the case with any solution, even HRMRU.

You'll notice that all of the issues listed above are solved, and the code would be lightening fast, the only issue I see is that unless you've read about these hotkeys you may not find them, but alt-tab will still work, and be useful.

Using Web Workers Today

I did a little reading on Web Workers a few months ago, and I recently used them in a little test I was asked to perform, so I thought I would share what I've discovered since I don't see much in Google search results about how to use Web Workers in a cross browser fashion with graceful degradation.

Web Workers

For those of you that do not know what Web Workers are I suggest you read the Web Workers Draft Recommendation, but in brief they provide web developers with the ability to create thread-like operations.

This is obviously useful for long operations. The standard way of dealing with laborious tasks like these in the past was to split up the work with multiple setTimeout() calls.

setTimeout

Before Web Workers, setTimeout() had to be used to split up long operations in to multiple small operations, because you only had a single thread, so this had to be done in order to avoid having an unresponsive UI or triggering a unresponsive script warning.

Current Browser Support For Web Workers

Currently the latest versions of Firefox, Chrome, and Safari all support Web Workers; IE and Opera do not support Web Workers.

So how do you detect if a browser supports Web Workers programmatically? this is how:

if( Worker /*check for support*/ )
// Web Workers are supported
else
// Web Workers are not supported

Minor Note For Safari

While Safari supports Web Workers it requires that strings be used when passing messages, which is something that Firefox and Chrome do not require. Firefox and Chrome both stringify anything not already a string that is crossing the bridge to or from a Web Worker, but Safari does not do this, so you must. This is a simple thing to do, but one that you must remember, always use the JSON object to JSON.stringify when sending a message and JSON.parse when receiving a message (if web workers are supported, then so will the JSON object be).

Supporting Browsers That Do Not Support Web Workers

The biggest hurdle for most to implement Web Workers today is the fact that not all browsers support them, but the fact is that it is simple to degrade gracefully, thus allowing those users that are using browsers that support web workers to start reaping the rewards, and allowing you to improve your site and be prepared for when IE and Opera finally come around.

So what is the best way to handle the browsers that do not support Web Workers? well I see two options:

  1. Maintain a secondary script to be used when Web Workers cannot be, and add it to the page by creating a script element and appending it to the document.body.
  2. Make the Web Worker friendly to being used in a window scope instead of a Web Worker's scope so that it can be simply added to page like I describe in option 1.

Option 2 will be the better approach in most cases I suspect, because it means that two separate files with two slightly different methods of achieving the same task do not need to be maintained. In order to implement option 2 two there are some things to consider:

  • You cannot use functions like postMessage, onmessage, or importScripts while in the window scope.
  • You will need to split the work up with setTimeout (which is available in the Web Worker scope as well) to avoid an unresponsive UI and unresponsive script warnings.
  • You should assume that your Web Worker will be used in the window scope, so do not pollute your global scope.

There are a couple of ways to determine if you are not in a Web Worker's scope, as to avoid using the postMessage, onmessage, and importScripts functions (which are available to Web Workers) when your script is run in the window scope (postMessage has another purpose in the window scope). The first method is this:

if(typeof importScripts == "function") {
// web worker scope
}
else {
// not web worker scope, assume window scope
}

The other method is to check if you are in the window scope:

if(typeof window != "undefined") {
// window scope
}
else {
// not window scope, assume web worker scope
}

Or, combining the two methods above:

if(typeof window == "undefined" && typeof importScripts == "function") {
// web worker scope
}
else {
// another scope
}

These methods will allow us to avoid using postMessage, onmessage, or other methods we use while in the scope of a Web Worker.

To avoid polluting the global space normal tactics apply, I would simply suggest wrapping all of the code in an anonymous automatically executed function, like so:

(function(){
// this is an anonymous automatically executed function
})()

Putting these methods together, we would get web workers like so:

(function(){
var winScope = true;
if(typeof window == "undefined" && typeof importScripts == "function") {
// web worker scope
winScope = false;
}

if(!winScope) {
onmessage = function() {
postMessage("blah");
}
}
else {
alert("blah");
}
})()

Except that real Web Workers would do interesting things, and use setTimeout.

© Erik Vold 2007-2010. Contact Erik Vold. Top ^