David Lains

Language, Learning, Code.

Here We Go Again

I’m baaaack! Yes, it has been a long absence. I have no excuse, other than, well, super busy. The site is all new. I moved it from Sinatra to Rails because I’m using the admin area as a kind of playground for some language learning ideas I’m working on.

I’ve been slowly teaching myself Japanese over the last two years. I started simply because I enjoy Anime and thought it would be cool to actually be able to understand some of the language. I have since become a bit obsessed with language learning, and learning in general. It is an incredibly deep and interesting subject.

I have been a bit frustrated with the language learning sites and tools that I’ve tried. Most seem to focus on a single aspect of language learning, building vocabulary with an SRS, teaching grammar or focusing on listening and reading. Real language doesn’t work like this. I think it is better to absorb all aspects of a language (vocabulary, usage, reading, writing, listening) at the same time.

I’m working on a system that will cover as many aspects of language learning as possible in a coherent way. It will step you through a language in small increments and keep building on previous knowledge.

It starts by teaching a set of words. Not just nouns though; a set of words that can be used to form simple sentences. The words will be added to an SRS to help with memorization.

Once the first set of words have been memorized a grammar rule lesson will become available. The grammar will be taught using the previously memorized words of course. Additional sentences using the new grammar rule will be added to the SRS.

When the grammar rule has been memorized listening exercises will become available, and so on, eventually going back to another full cycle of words, grammar, listening, etc.

So, that is what I’m playing around with. If I get something that works well for me I will probably split it out to a separate site, but for now I’m just having fun experimenting.

Strange Twitter Bootstrap Scrolling Issue

So, I've been working on a web application. Actually it is one that I 'finished' over a year ago but never ended up deploying for various reasons. Once Titlz was released I wanted to get back to Rails and web development; it is just so much more fun than iOS development.

In the process of updating and polishing my web app I decided to give Twitter Bootstrap a look. You can't do much work in the web world without hearing a lot about Twitter Bootstrap. People love it, people hate it, whatever.

After a week of use I have to say I really like it. As a solo developer with limited resources Twitter Bootstrap provides a huge base of functionality to work with.

I did run into a strange problem while I was converting my code to use Bootstrap. I saw that some other people have had the same problem and there didn't seem to be an acceptable answer around the internet. It took me a while of poking around with my code but I finally figured out what the problem was and I thought I'd share it in case anyone else finds it useful.

What happened was the vertical scroll bar for the entire page would not show up. I have a fair amount of test data in my development database so the page always has a scroll, but after switching over to Twitter Bootstrap the scroll bar disappeared. I could see the data was still in the DOM, I just couldn't scroll down the page at all.

It is a very frustrating problem because there are no errors, no warnings, no apparent reason for things not to be working correctly. I did find one question on Stackoverflow that suggested the problem was with the navigation bar.

If you want the Twitter Bootstap navigation bar to be anchored at the top of the page you have to add the navbar-fixed-top CSS class to your navbar. This adds a position: fixed; rule to the navbar. The answer in the Stackoverflow question stated that if you remove the position: fixed; rule then the vertical scroll bar would reappear.

I tried that solution and it did indeed fix the scroll bar problem, but it also introduced another. The navbar was no longer fixed at the top of the page. I tried using a negative margin on the navbar to force it back to the top but that didn't do any good and was a hack anyway.

I didn't think the issue was really related to the position: fixed; CSS rule. Other people were using a fixed top navbar without having to tweak CSS rules.

I poked and prodded and moved things around. I knew it had to be something simple and it was probably staring me right in the face. Then suddenly I saw it. All of my page content was somehow wrapped up inside the navbar.

The standard Twitter Bootstrap navbar example looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
  <title></title>
</head>
<body>
  <div class="navbar navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container">
        <ul class="nav"></ul>
      </div>
    </div>
  </div>
  <!-- Page Content -->
</body>
</html>

I was looking at my page DOM in the Developer Tools when I noticed that my page structure was actually:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
  <title></title>
</head>
<body>
  <div class="navbar navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container">
        <ul class="nav"></ul>
      </div>
    <!-- Page Content -->
    </div>
  </div>
</body>
</html>

That's right, my entire page was actually wrapped up inside the navbar. I had changed a nav element in my header to a div in converting my page, but I forgot to change to closing nav to a closing div. This threw off the page structure and essentially made the entire page fixed to the top along with the navbar.

So, if you see strange vertical scrolling issues with Twitter Bootstrap make sure to double check your page structure and make sure all of your div's are closed.

How Well Does Your Website Perform?

Do you run your own web site? Do you know if it can handle a traffic spike? Do you know if it performs as well as it could?

There is a huge amount of work involved in getting a web site built and deployed. Once you decide to move forward with an idea for a site you have to determine what exactly you want to build, what features you want it to have, design the look of the site, write the code, write unit tests to make sure everything works correctly and continues to work in the future, figure out how to let people know about the site and so on.

A huge amount of time and effort can go into just building a site and getting it deployed for everyone to see. Now imagine one person has to do all that work and it is easy to see how some aspects might be delayed or outright forgotten about.

If, like me, you have worked for larger companies that have their own web operations staff or you are just new to running your own web site this information should give you a better idea of how well your site performs and how you can make it perform better.

Please also be aware that I don't claim to be an expert in this area. If you see some glaring problem with my recommendations feel free to point them out in the comments.

Determine Site Bandwidth

The first step is to find out what your bandwidth limits are. I host this site on a Linode VPS which provides 200gb of bandwidth per month. Some shared hosting services are providing unlimited bandwidth, but if you are getting enough traffic on a regular basis to exceed 2-300gb of bandwidth a month you will probably be causing problems for the other customers on the shared host and you might get asked to move anyway.

Most of the calculations I will be doing will be in kilobytes to keep things simple. One gigabyte is equal to 1,048,576 kilobytes, so the total amount of kilobytes I can send without incurring bandwidth charges is 200 * 1,048,576 = 209,715,200 total kilobytes/month.

There are numerous free bandwidth calculators around, but they all assume you know how many page views you expect in a given month. This article will look at bandwidth from a different perspective. Given my bandwidth limit, how many page views can I send per month.

Now you need to find the average size of your site's pages. You can't just look at the size of the HTML file to estimate the size. The full HTTP response is going to include CSS, Javascript, images, and any other resources your page uses. This is where Pingdom Tools comes in handy. You type in your site address and Pingdom will test the load time of that page. It includes a performance score, total number of requests embedded in the page, load time, and most importantly, the page size. Another fee site, GTmetrix provides the same service as Pingdom but shows two different performance scores. Both sites give in depth information about the performance score and how to improve your score, some of which I will mention, but most is beyond the scope of this article.

To get an average page size for your site choose one of the tools above and test a good sample of your pages. Test smaller pages as well as larger pages to get a good average. I ended up with an 186.3kb average after testing my pages.

Now its just simple math to figure out how many page views I can handle before I reach my bandwidth limit. If I divide the total kilobyte/month by my average page size I will have an approximate number of page views per month that will stay within my bandwidth limit, so 209,715,200 / 186.3 = 1,125,685 page views per month.

That number is approximate of course. My home page will fluctuate in size depending on how large or small the current blog posts are. It gives me a ball park figure to work with however.

My site isn't getting anywhere near that amount of traffic right now, but what happens if I get a spike from Hacker News. That is the most likely site that I would be getting a traffic spike from, so it seemed like the best place to start. After some searching and reading I found that a Hacker News spike can range anywhere from 7000 - 60,000 page views in a day depending on the popularity of the article.

If I had that many page views a day would I go over my bandwidth limit? 1,125,685 / 60,000 = 18.76. I could sustain heavy traffic for almost 19 days before exceeding my bandwidth. That isn't bad. It also isn't very likely that I'll ever get that many page views for that long. How many page views could I handle a day without going over my limit? 1,125,685 / 31 = 36,312. I could handle roughly thirty six thousand page views a day for a month.

Now we have some simple equations to get an idea of how much bandwidth our web pages use and how many page views we can generate per month:

  • limit-in-gb x 1,048,576 = limit-in-kb
  • limit-in-kb / average-page-size = approx-page-views-per-month
  • limit-in-kb / high-page-views = days-until-bandwidth-is-exceeded
  • limit-in-kb / 31 = page-views-per-day-within-bandwidth

Optimize Bandwidth Usage

Now that you have a good idea what your web sites page sizes are and how much bandwidth you use it is time to look at reducing and optimizing your bandwidth usage as much as possible.

Reduce Page Size

The very first thing to do is reduce the page size as much as you can.

  • Minify CSS and Javascript - The browser doesn't care about nicely formatted CSS and Javascript files and the extra whitespace just slowly chews up your bandwidth. There are tools on the Internet to minify your CSS and Javascript.

  • Combine CSS and Javascript Files - The fewer requests the browser has to make to the server the faster the page will be visible in the browser. This doesn't strictly reduce overall page size, but if you minify your CSS and Javascript it makes sense to combine any files you can at that point as well.

  • Optimize Images - If there are any background image files that are used in your CSS and used on every page you should make sure those image files are optimized and made as small as possible.

  • Remove HTML Comments - Comments are generally for the site developers and not the viewers, so removing or at least keeping the size of HTML comments low will shave off some more from your page size. If you are using an HTML template system like Haml or ERB you can use the template language comment which will be removed when the final HTML is generated. That way your developers can comment as much as they like and none of those comments will be sent to the browser.

  • Remove Duplicate Code - Check through your CSS and Javascript to make sure there are no duplicate CSS rules or Javascript functions.

  • Enable Compression - Most web servers support compression now, but it is generally not enabled by default. Investigate you web server documentation and configuration settings to make sure your pages and assets are being compressed before being sent to the browser.

Enable Caching

There are three types of HTTP caching, browser cache, proxy cache and gateway cache. In the context of this article we are interested in browser caching. Browsers set aside space on the users system to store assets that have been downloaded from a web site, but a browser will only store assets in its cache that have some kind of HTTP cache header. (Expires:, Cache-Control:, Last-Modified:, Etag:)

Many web servers will add the Last-Modified: HTTP header automatically for static files such as images, CSS and Javascript. The Last-Modified: header is not enough information on its own however. If a static asset only has the Last-Modified: header the browser will cache it, but it will have to connect to the original web site to verify that the asset has not changed.

To avoid the validity check add the Expires: header. If an asset has an Expires: header the browser will save the expiration time along with the asset in the cache. If that asset is requested again and it has not yet expired the browser skips the validity check saving a round trip to the web server.

One trick many sites use it to add an Expires: header to static content such as images, CSS and Javascript with a expiration date far in the future; several months or years. This will make the browser keep the asset and not revalidate it for a long time. All web sites grow and change over time, and you will probably change some of those assets eventually. How do you get the browser to get updated assets if they aren't expired yet? Use fingerprinting. You can add a version number to the file and update your site to use the new file name. This will automatically invalidate the existing version of the file in the browser cache and get the new and updated version of the file.

Actually adding the cache headers to your web pages and static assets is going to be specific to your site. You can do it directly in the web server or in the language or framework you are using.

HTTP caching is a large subject and I can't cover it all here. If you are interested in the details I have found several good articles:

That's it for this article. I hope you have a better idea how your bandwidth is being used and some ideas on how you can improve you pages to be more efficient.

How It Started

Summer, 1979. My friend Tom Burns' birthday party, at what is now called Haunted Trails, but was a miniature golf course and arcade back then, in Bridgeview Illinois, a suburb of Chicago. That is when I discovered what I wanted to do with my life.

I don't remember very much about the party. It was a standard birthday party for an eleven year old. There was bad pizza, plastic cups filled with soda and a birthday cake. We all got a dollar in quarters for the arcade; probably part of the birthday party package. We didn't get to miniature golf, which was fine by me. I've never cared for it.

The parents were all at the reserved table doing parent things. All of us, the kids, were in the arcade. You have to realize this is 1979 though. The arcade consisted of mainly Skee Ball and Pinball machines. It wasn't like the arcades in the eighties that had music, lighting, hundreds of machines with teenagers hunched over them. Arcades in the mid to late seventies were actually pretty boring.

I wandered over to one of the pinball machines which gobbled up three of my quarters rather quickly. I was looking at the other pinball machines trying to decide which one to waste my last quarter on when I noticed Tom and the other kids were gathered around something new. It was a tall box with a weird green insect on the side. I could hear the other kids gasping at what they were seeing so I walked over to see what was going on.

This is what I saw. Galaxian That's right. Galaxian.

My mouth dropped open. It was like nothing I'd ever seen before. I watched Tom as he played his game and I figured out how to operate the machine. Move the lever with the red ball left and the ship moved left, move it right and the ship moved right, press the red button to fire your laser at the enemy. So simple by today's standards, but it was like magic to me. I literally walked to the back of the machine to see if I could glean some kind of information about how the magic box worked.

I knew what to use my last quarter for now. All the other boys had called their turns so I had to wait. The time simultaneously dragged and flew by. I was mesmerized watching the other party goers play, seeing them figure out the controls, learn the rules of the game and eventually lose all their ships. I was also desperate to get my hands on the controls.

Finally it was my turn. I plopped my quarter in the coin slot, hit the single player button, and proceded to lose all of my ships in record time. Far faster than any of the others. It didn't matter though. I was hooked. I knew this was my future. I had to be a part of whatever it was that made this game work. I wasn't even really sure what it was yet.

Looking back at that moment now I can see the difference between me and the other boys at the party. They were all amazed at the graphics, (this was the first color video game any of us had seen) and the game play (the ships flew down at you in wild patterns unlike the boring Space Invader ships which just marched back and forth across the screen). I was amazed at those aspects too, but mostly I wanted to know how it worked. What was inside that case, how was it possible for me to control images on a television screen.

I'd heard about computers, mostly in movies and science fiction books, but they were room sized things in large buildings far away from where I lived. The concept of a personal computer had not yet entered the consciousness of the average person. I figured that Galaxian had to be controlled by some kind of computer and that controlling a computer meant you had to write a program for it but beyond that I knew absolutely nothing.

I kept my eyes open, learned whatever I could whenever I could. Over time I got access to computers. I read programming books, fumbled around at writing my own games. It was a slow process and I'm still working at it. The plan is to continue working at being the best programmer I can be, figuring out how things work and building interesting things for the rest of my life.

I was lucky. I know many people that never had a moment like this in their life. They never got that "AHA" moment that propelled them down a path that would define their life. I also know people who did get that moment and have turned their back on it for whatever reason. I'm not judging, I've turned my back on my dreams from time to time as well. It is HARD WORK. It is solitude, frustration, pain, terror, self-loathing and sometimes a whole lot of fun.

I hope you have found your path and have the strength to follow it. If you haven't, I hope you continue to look for it.

Overcome Self-Doubt

One of the biggest obstacles solo developers face is self-doubt. It is easy to look at the project you are working on and decide that nobody is ever going to actually need it, or you don't really care if it ever sees the light of day. There are a million points in the life of a project that can cause you to despair and wonder why you ever started working on it.

You run into a tough technical problem that seems un-solvable. You don't like the design. Someone looks confused when you try to describe the project to them. The amount of work needed to finish it seems impossible to surmount.

There are times when this self-doubt is valid. Looking at your work critically is important. Not every design is good, not every idea needs to be realized. You have to be extremely careful though. There is a fine line between looking critically at your work and tipping over into despair and dumping the project.

It is easier if you work for someone else or you are at a startup. Working with other people doesn't prevent self-doubt, but you generally aren't allowed to give in to it. For the sake of the team or your paycheck you have to push through the doubts and finish your part of the project. It is almost worth it to work at a larger company for a time just to get this kind of experience.

Having worked through self-doubt in the past is not always enough. What can a solo developer do to overcome self-doubt and push through to finish projects? Here is what has worked for me:

  • Be Stubborn:
    This works especially well in those situations where there is some technical problem making you wonder if what you are trying to do is even possible. Just keep at it. It will be incredibly frustrating. You will want to throw your mouse across the room (try to avoid people or pets), but if you stay with it you will find a solution. There is always a solution. Even if that solution is scaling the feature back slightly to get it working for now.

  • Take a Break:
    When you are overwhelmed with self-doubt and the whole project looks like a waste of time, it's time to take a break. It can be very draining to be a solo developer. You have to make every decision yourself. You have to solve every technical problem on your own. This can easily drain all of your energy. If you have been working very hard for a long time and your work suddenly looks redundant; don't do anything. Don't make any decisions. Just step away from it completely and rest. The work will not seem pointless after a few days or even a week away.

  • Talk To a Friend:
    Just talking about your doubts can help alleviate them. Things that seem like the end of the world in your head suddenly don't look all that apocalyptic when you say them out loud.

  • Have Rituals:
    When things look bad don't be afraid to shut your computer down and walk away from your work for a short time. Sometimes even thirty minutes is enough to refresh your perspective. When you reach an important milestone celebrate it in some way. Go out for a coffee, spend some time browsing your favorite store.

  • Work On a Different Aspect:
    If a certain area of your project looks hopeless try doing some work on an entirely different part of the project. This is always easy to do as a solo developer because the whole project is yours. Stuck on coding? Start fleshing out the documentation. Working on a project from a different point of view can help you to see the whole in a better light.

It's easy to see all the little faults in our own work. Don't let that stop you. Clean up what you can right now, keep plugging away at your project, and don't let self-doubt keep you from finishing.