Split Testing Static Sites

I have been looking for a lightweight solution to split test static sites. This blog is a static site generated with Jekyll, and I want to run experiments that might help people get more value out of the things that I publish here. For example, I think the current email subscription call to action is pretty weak, so it would be useful to try to run an experiment around it. Also, I want to beef up my experimental design skills and this seems like a low-risk way to do it.

In this post I’ll tell you how I evaluated a few different options for split testing and why I decided to fork one and open source it.

A potential solution

To start, I didn’t want to use something that required me to set up a server, and I’m guessing that the overall amount of testing won’t require a fancy dashboard. If those were the case, Sixpack seems like an interesting approach.

I found a library called ABalytics that uses Google Analytics to set up split tests. At first, it seemed like ABalytics did everything that I wanted:

  • you can specify split test experiments to run
  • there can be multiple experiments running at a time
  • it stores the tests in an analytics service (Google Analytics)
  • it runs with vanilla JavaScript on the client
  • there is no server component
  • it stores which variant the user has seen and presents it to them if they come back

However, after installing and playing around with it, it seems like the mechanism for how it works in Google Analytics (“Custom Variables”) doesn’t seem to work any more. I think Google Analytics changed the way that they handle these custom variables. Also, it was hard to test since Google Analytics doesn’t really work unless it is on your production site and there is high latency between when you send an event and when Google Analytics reports the event.

Changing ABalytics to use Heap

I considered rolling my own static site split testing framework, but was pretty happy with the feature set of ABalytics. So I decided it would be easiest to fork it and change it to work with Heap Analytics instead.

Heap seems to be a good competitor to Google Analytics. One of the most powerful features of Heap that it stores all of the actions that the user took, and you can retroactively set up events and funnels for tracking the events. So you don’t need to know exactly what you want to track, you can figure this out when you actually want to know it. This seems to be really helpful because unnecessary setup is a large form of waste. Also, you won’t lose days or weeks of data by forgetting to track something important.

Heap tracks most of the same things that Google Analytics tracks, like browser type, number of visits, sessions by a particular user, referral information, and so on. Events that you send to Heap show up almost immediately, so it’s easier to experiment with.

Digging in

First, I had to consider the license of the original code. Since ABalytics uses the MIT license, licensing was not an issue. I just added another copyright line with my information since part of the license requires retaining the existing license when distributing. I don’t think that I would need to change the license if I was using the code for just my site, but it seemed like it would be easy to open source my changes so I wanted to do that. This has the benefit of sharing my work with others and also potentially getting outside improvements.

The key change was changing from using Google Analytics to using Heap. I needed to tell Heap what experiments were being run for the user viewing the page. If we send the experiment information as event properties for the user, all events sent to Heap will be associated with this experiment information. To do this, we just set up a hash with the experiment data and send it to Heap:

HeapWrapper.prototype.recordExperiment =
        function (experimentName, variantName) {
    var properties = {}
    properties['experiment_' + experimentName] = variantName;
    this.heap.setEventProperties(properties)
};

I figured since Heap would potentially get a lot of event data, that I would prefix any experiments with experiment_ before sending.

How it went

I successfully resisted the desire to change a bunch of things, since I didn’t know whether my approach would work at all and I wanted the diff to be as small as possible. I reasoned that I could change the code to my liking after I had a good solution locally and pushed up. I tested the changes locally, and it seemed to come together quickly.

Heap sets up a development and production environment by default, and they are switchable by setting a variable. With this, I am able to test locally and won’t impact my production data. I have a client snippet that looks at the location and uses the production environment identifier if it is running on my blog and otherwise uses the development identifier. This keeps complexity down by not needing to know the environment when building the site.

The source is available at the HeapAB repo. The instructions in the README should be enough to get up and running, but let me know if you run into anything that is tough or could be explained better. I’d like to add a few features and clean it up, but it should be helpful for people today.

I’m not currently running any split tests, but am looking forward to using this library for improving this blog.

Useful HTML Elements You Might Not Be Using Enough

I was taking a look around the Mozilla Developer Network site to learn more about HTML elements. While doing so, I saw a few that I either didn’t use or thought that I could be using more and wanted to share with you. For each, I’ll post what it is and why you might consider using it more in your code.

Why would you do such a thing?

I think this is interesting because even while I do web development quite a bit, there are always new things coming out. While I might have been familiar with elements a few years ago, the built-in tags are evolving. (I tried to avoid tags in this post that were not supported by most browsers.)

This actually applies to many areas of learning and knowledge. What we think we know ends up being inaccurate or incomplete, so we need to continually review and reevaluate what we know.

The main recurring theme in this post is that more accurate tags allow us to capture the semantics of the content that we have in them. When we use semantic tags, we give a deeper understanding of what the content actually means. Search engines and other automated tools can get a better understanding of our website, and while we are working with it, we also can understand the intent more clearly.

With HTML5, we can create any tag we want. By seeing what tags are already there, we avoid reinventing tags. Also we can get ideas for semantic tags that we can create in our own projects.

Tag, You’re It!

<address>

I like this tag because it is pretty common to put an address on a web page (maybe in the footer or on a contact/about page.) But instead of putting it in a <div> or something, this tag allows us to be semantic about the address.

<code>

This tag is more common. Again, using it is more semantic than using something like a <pre> tag for displaying monospaced text. It signifies that the contents are computer code.

There are various plugins online that will highlight text in code blocks. Some of them work off of class attributes, and others try to infer the language from the contents.

<samp>

I think this tag is a little more rare in the wild. It should show the output of running a computer program. I think this is interesting because it most of the time the <code> or <pre> shows both the input and output, but this would actually be more correct. By using a different tag, you can style them differently to show the output more clearly. I think this would make various technical writing and documentation easier to understand. Worst case, you could make the styles the same as your <code> formatting and then change them when there is a meaningful distinction from your output.

<kbd>

I actually really like this one for technical manuals. There are many times when you try to say something like: Ctrl + Alt + Delete, when with the <kbd> tag you can get nice styling like Ctrl + Alt + Del with some CSS. (Inspect those tags to see the styling I used.) I think that the result is easier to read.

<cite>

[citation needed] is all the rage on Wikipedia, and it is common to need to cite sources in our own work. Instead of having quotes have “– Aristotle, The Republic” at the end, you can have a <cite> tag that has this information and then use styling to add the dash at the beginning.

<fieldset>

I find <fieldset> useful for laying out forms. One approach is to put a border around a group of controls, so that they visually distinct from other form elements.

<legend>

If you’re using <fieldset>s, <legend> tags can help explain what the contents are. For example, if you had first name, last name, and date of birth in a <fieldset>, you might call the group “General information”.

<q>

This one is interesting. It is supposed to be a semantic way to represent short quotes. I’m guessing that it would be useful for research papers. But I think it might also be nice for inline quotes (quotes inside of quotes) or for styling quoted text. I haven’t used it much, but might consider this going forward.

<track>

<track> gives you the ability to link text to audio or video elements for subtitling. This would be really useful if you had a web app or podcast that linked together a presentation with audio and a text transcript. Or maybe even a video with audio and a text transcript.

<time>

This tag can be used for exactly specifying time. Programs could then read this and understand when a game will start, when an event is happening, or when something occurred.

I’m not sure if there is a fuzziness factor (something happened on this day in history, not this exact time) or for time ranges, but I think these would be useful.

A possible extension would be to say when something happened, and then for the website to use JavaScript to automatically convert the time into something more human-readable. So instead of “2015-12-06 18:04”, say “yesterday at around 6”. This could be achieved pretty easily using something like moment.js.

<dfn>

Again, I think this element has merit for technical documentation. You have the ability to link a word to its definition, and can refer to this throughout the documentation in an unambiguous manner. One possibility would be to automatically create a glossary for a book by parsing it for <dfn> elements. Another use would be for styling definitions consistently.

<mark>

While using <span>s with class attributes might be one approach to highlighting text, you might as well use the built-in tag to accomplish the same goal. You can still change the color with CSS, but get the added benefit of saying that this element exists purely for styling.

<progress>

This was one that I didn’t know about before reading the documentation. Basically you can display a progress bar using nothing but HTML and CSS and change the value using JavaScript. While many front-end frameworks have an implementation of progress bar, this would be a good lightweight control if you aren’t using one. Bootstrap appears to use a <div> with a progress class instead of using an element. I wonder what the tradeoffs of using a <progress> instead would be.

<var>

Last, the <var> tag represents a variable in a mathematical expression or a programming context. I think that this could be useful for styling these elements differently and also for separating code or shell commands from variables. You might use it to replace most inline <code> elements.

Wrapping up

Hope you found these tags interesting, and maybe you looked around a little and found some other tags that you didn’t know about.

Are there any great tags that you think are underrated? Share them in the comments!

Fluent Forever Review

I just finished up the Fluent Forever book by Gabriel Wyner and thought it was great. I’m interested in learning Spanish, and I like the approach that the book takes. It has solid advice and is backed up with some research citations.

In this post I’ll break down my key takeaways from the book and the accompanying website which has rich videos. Check out Derek Sivers’s post for an in-depth review.

Spaced repetition is key

Consistent spaced repetition underpins the entire system. I won’t go into heavy detail in this post, but it is basically a way to create flash cards that you see at the optimal time for retention. An algorithm determines how often you will see cards, so you only review cards that you actually need to review. By setting up small cards that you can review, you can learn and retain a lot of information.

Pronunciation first

Wyner stresses learning pronunciation first. It is important to do this if you want to speak in your target language so you aren’t actually learning two languages, one spoken and one written. This seems to make sense, although I think I would have tried to put pronunciation off until later without this advice.

He spends some time in the book and has various resources on his website about learning pronunciation. Specifically, the IPA is used. I would have disregarded this as a tool, but it actually seems like a good way of learning the sounds of your language and being able to sound out words that you might not know. Also, being able to spell out words that you hear.

Vocabulary next

After getting some base pronunciation to avoid needing to unlearn words, the next step is to learn the top words of your target language.

To start thinking in your target language, don’t use your native language at all. Only use pictures that you recognize to give meaning to the words. So instead of saying “cat” -> “gato”, you say “picture of cat” -> “gato” (and the reverse) and “audio of gato” -> “gato”. This helps reinforce the language that you are trying to learn and prevents you from translating into your native language.

By learning the top 600-1000 words, you can greatly increase the amount of the language that you can say and understand.

Grammar from sentences

After this, start looking for grammatical patterns and creating cards in your spaced repetition system for them. Also, start working on different verb terms, etc.

Speak, read, and listen

You should at this point start producing in your target language because this will expose where you are weak and strengthen your grasp of the language. There are a variety of resources online to talk to people that speak your language and potentially help them with English.

He recommends reading in your target language, especially if you can find an audiobook version and play it at the same time for the first book. This helps reinforce your pronunciation.

Television and movies in your target language are another resource that can be helpful for helping you be able to carry on a conversation in the language you are trying to learn.

Recommended

Overall, I recommend checking this book out if you are interested in learning a new language. I think that it takes an approach to learning languages that is both new and seems really useful.

Daily and Weekly Points Checklist

Wanted to share an organization system that I came up with that combines my weekly flip fold calendar idea and life gamification. In this post I’ll give you a template to use to set up your own system. Wanted to share since I was thinking about systems like this recently and realized that I hadn’t written it up yet.

Basically, you set up your daily goals, and they total to 100 points per day. Then, you have some weekly goals, and they should total to 300 points. Then at the end of the week, you see how many of your goals you have accomplished. 700 points would be a 70% success rate. I made it 1000 points just because it was a nice round number and I think it was a good weighting for daily and weekly items. You need to do daily habits (they can be simple), but also keep your weekly goals in mind.

Here is the daily/weekly points template. I made this by using some graph paper to keep everything lined up, and the scan took out the guidelines.

Here is a rough image of what a completed template looks like). I blocked out some things that were potentially sensitive.

I generally prefer keeping things analog until I am pretty sure that I am going to use them regularly. It also lets me modify the system, which keeps it a bit more flexible.

At the bottom, you can see the flip calendar reincarnated in a more linear fashion. All of the basic elements are there as they were before. Again, this is a good way to plan out the week and slot in the weekly tasks that I want to get done.

I think it helped me be more aware of all of the things that I was trying to do and organize them. The image I linked to was when I did BJ Fogg’s Tiny Habits program and had three small habits each day to do. The others were “conducts” to try to do things that I thought would help me be more consistent. I liked that some of the habits on this sheet were meta: “get points for filling out this day on the day it happens” and “get points for finishing the sheet”. I think part of the value is continuing with the system, and it also relates to other habit posts that I had, including the streaks calendar.

Should I Work For Free?

In one of the Slack organizations I am in, some of the people in the design channel were talking about how spec work permeates their industry and how it is harmful. They talked about how this came to be and the effects of it. I stayed out of the discussion for a while, but I finally posted this to try to help understand what they were saying and state my perspective. Since I thought it might be valuable to you if you are a freelancer or consultant, wanted to share it here.

The Post

I have worked more in a software development capacity, so I am not steeped in the “spec work” culture as much, but I basically would not give work away for free for someone who is able to pay money. I think part of our responsibility as people who take on clients is to verify the following before engaging to learn more:

  • what is the significant business problem you have?
  • why are you trying to solve it today?
  • have you had and solved problems like this before?
  • do you have a budget for this project, and is it at least $X0000 dollars?
  • are you the project owner?

I will admit to mostly lifting this from Brennan Dunn’s Double Your Freelancing Rate book and related materials. But I think it is a good list to qualify leads that will prevent a lot of headache. There are certainly clients that will filter out of the process at this point, and the best case would be for you to be able to direct them to someone else that would be able to help or to a good resource to learn more. I think we have all run across someone who wants a MailChimp clone for $500, and we just have to say that this is almost certainly unreasonable, and here is why, and here are other resources that you can investigate and the potential advantages or pitfalls of going that route. Sometimes people just have an unrealistic or uninformed expectation, and at least we can tell them why we think this is incorrect and help them on their journey.

A business might think they need a new website, when in reality they have a product or positioning issue, or they are not getting enough traffic to their existing website, or other problems. So I think it is our responsibility to understand the underlying problems the client has and to make sure that we are solving the actual problem they have. That is a lot more valuable than just saying “yep, you specify it, I code it.” Or, “you give me a design, and I design it.” At that point you are a commodity, and will be able to charge accordingly. If you can provide more value than that, then you are not in the same market segment and can justify a higher rate as a result.

I think it’s easy to blame the industry or norms, but I think it’s important to say “what can I do to ensure that the projects that I take on are going to be the kind of projects that I want to work on?” Part of it is working with clients to establish better default communication and expectations.

It’s interesting though. I think that there likely some “free” work involved in most consulting industries. If you write a blog post or go to a conference or a networking event, or learn a new technology or process, or meeting with leads, this is time that you are not charging clients. But it is probably really important to ensuring that you get new work in the door. If you were turning away good work every week, would you have any incentive to do spec work?

Thanks for reading, and I’d actually love to hear more about this. I think it is an interesting topic.