JavaScript as a Last Resort

My favorite fantasy novel is Douglas Crockford’s JavaScript: The Good Parts, because I don’t think JavaScript has any good parts and should be used as a last resort. This puts me at odds with most web developers, and probably puts me at odds with Kev Quirk, who holds the opinion that JavaScript is only bad when misused.

Let me start by explaining why JavaScript has a bad reputation. You see, it’s a programming language that can be used to do all kinds of things on websites. These can range from benign uses, like formatting a hamburger menu on mobile devices, to more nefarious uses like browser fingerprinting.

The problem comes when web developers try bundle megabytes upon megabytes of JS into their websites. This can make websites extremely heavy and slow to load, which doesn’t sit well with me as I’m all about optimised websites.

I don’t have any argument with this, but I stand by my opinion that JavaScript should only be used as a last resort. I’m probably a bit old-fashioned here. I think that HTML, HTTP, and server-side processing should be the first technologies a web developer uses. They work for just about everybody. If you’re on 56K dialup in some godforsaken Kansas farm town it’s likely to be the only web tech that will work. But if you’re on an unmetered 10 gigabit connection in New York City it will fly like a bat out of Hell.

Of course, raw HTML can be ugly unless you like your websites oedipal, so let’s slather some CSS on top of the HTML, HTTP, and server-side code so that it doesn’t frighten off the suits.

Wait? What’s that? We don’t want to render entire pages on the server side any longer because we’re getting 10,000 requests a minute, the server’s wheezing like Donald Trump at the eighteenth hole, and the DevOps team has threatened to unionize and do work-to-rule? OK, fine, let’s layer some AJAX calls on top of the raw HTTP methods and use those when the client side has enough processing power and sufficient bandwidth to handle it.

We used to call this approach “progressive enhancement”, and it worked when developers were given time and latitude to do their jobs and deliver performant, reliable software that solved legitimate use cases. The developers working on the BBC’s website called it “cutting the mustard”. They delivered a reasonable baseline experience in less than 25KB of data and less than ten HTTP requests, and then used feature detection to deliver a fancier experience to visitors that could handle it.

Of course, I’m not the BBC. I’m just some metalhead who codes for a living, writes crappy science fantasy, and insists on having his own website instead of being content with a social media profile or three. But I like sharing music videos and most of them are on YouTube.

This presents a problem. The default method for sharing a YouTube video in a more visually appealing manner than a plain link is to use an embed. YouTube encourages this by providing markup you can paste into your blog. It looks like this.

<iframe width="560" height="315" src="https://www.youtube.com/embed/DLzxrzFCyOs" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

It looks easy, doesn’t it? Just past that snippet of text into your web page and boomshakalaka! You’ve got Rick Astley on your blog.

But there’s a catch. You see all that stuff in the “allow” property? That gives YouTube all kinds of device access that it shouldn’t need just to play “Never Gonna Give You Up”. It gets worse, though. For every YouTube embed you add to a page on your site, anybody visiting that page will end up downloading hundreds of kilobytes of JavaScript, much of it spyware analytics, just to play a video. Not to mention a bloated preview image that itself might weigh over 100kb.

a brown tabby cat with his tongue out
“Dude, there’s got to be a better way to share YouTube videos on your website than using an iframe that pulls in over 100KB of JavaScript. I’m just a cat but even I know better.”

Smudge is pretty smart for a cat who keeps forgetting to pull his tongue back into his mouth when he’s done washing himself. He’s right; there are ways to share YouTube videos without inflicting Google’s spyware on unsuspecting visitors.

It just involves work. Let’s consider that Rick Astley song that everybody is sick of hearing every time they click the wrong link (and never mind that it could be goatse). Its URL is https://www.youtube.com/watch?v=DLzxrzFCyOs. A preview image for this video is available at https://i.ytimg.com/vi/DLzxrzFCyOs/sddefault.jpg. sddefault.jpg is 640 pixels wide and 480 pixels tall, and its size is less than 15K.

Here’s the fun part: if you know a YouTube video’s URL, you can get its ID. If you have its ID, you can pull its standard definition preview image. It’s low-resolution, but good enough for our purposes, which is to provide a visual preview of a YouTube video inside a link to the video without using JavaScript.

a brown tabby cat yawning
“Hey, boss, why do we have to pull YouTube video preview images? Can’t we just hit https://i.ytimg.com whenever we need an image instead of self-hosting them?”

Purrseus isn’t as smart as Smudge. Then again, he’s still just a big kitten. Hopefully he’ll learn. What he’s talking about is called hotlinking. It’s generally a bad idea for the following reasons:

  • Every somebody visits your site, they’re hitting the other site too.
  • It takes longer for your site to load because you’ve got to wait for the other site.
  • You can’t cache data from other people’s sites.
  • It annoys sysadmins, who aren’t necessarily subtle but are quick to anger.
  • If the image gets moved or deleted, you’re shit out of luck.
  • A clever sysadmin could redirect your requests to something foul.
  • You wouldn’t want somebody doing it to your site.

How do I avoid hotlinking? I grab the preview image once and upload it to my site. Then I wrap the image inside a link with a caption instructing visitors to click the image if they want to watch the video. Doing it my way looks like this:

YouTube preview image
Click the image to watch “Never Gonna Give You Up” on YouTube.

The resulting HTML looks somewhat like this:

<figure>
  <a href="https://youtu.be/DLzxrzFCyOs?autoplay=1" target="_blank" rel="noopener">
	<img loading="lazy" width="640" height="480" src="/assets/images/yt-thumb-DLzxrzFCyOs.jpg" alt="YouTube Preview Image" />
  </a>
  <figcaption>Click the image to watch &#8220;Never Gonna Give You Up&#8221; on YouTube.</figcaption>
</figure>

I say ‘somewhat’ because I’m using WordPress and the actual HTML generated by WordPress might just be capable of giving Clive Barker nightmares. I’m as serious as a public explosive rectal prolapse here. If you right-click and select “view source” on the average WordPress site, well…

Kirsty Cotton just aced her front-end developer interview…

OK, I’m just having a bit of fun at my readers’ expense. WordPress-generated HTML isn’t terrible; there’s just a metric shitload of CSS classes involved that would have gotten in the way of my example and distracted from my point, which is…

You can provide a visually appealing YouTube preview that links to the original with nothing but HTML, some CSS, and a bit of elbow grease.

Smudge

I suppose, however, that you think it might be tedious to manually download a preview image every time you want to share a YouTube video. That’s what shell scripts are for. I don’t do this manually; I don’t get paid enough for that shit.

Instead, once I figured out how to do it consistently, I wrote a little shellscript called yttget (YouTube thumbnail get). It depends on curl and the display tool from ImageMagick—which is a brilliant and versatile toolkit once you learn to use it.

#!/bin/sh -e

# yttget (YouTube thumbnail get)
# © 2021 Matthew Graybosch <contact@matthewgraybosch.com>

# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all
# copies.

# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.

# usage: yttget https://www.youtube.com/watch?v=DLzxrzFCyOs

URL="$1"
ID=$(echo $URL | cut -d = -f 2)
FILE="${HOME}/Downloads/ytt-${ID}.jpg"
THUMB_URL="http://i.ytimg.com/vi/${ID}/sddefault.jpg"

curl ${THUMB_URL} --output ${FILE}

echo "Thumbnail available at ${FILE}"
echo "Video URL: https://youtu.be/${ID}?autoplay=1"
echo "Suggested Caption: Click this image to watch on YouTube..."

display ${FILE}

Yes, it’s absolutely trivial as far as shell scripts go, but it works for me and you’re welcome to copy the code, save it, make the file executable, and use it yourself.

Does this seem like overkill compared to using the embed code YouTube provides? Perhaps, but I honestly think that blindly using iframe snippets provided by corporate-owned platforms like YouTube is taking the easy way out and does a disservice to people visiting my site.

Besides, since I’m using WordPress and have learned to cope with the Gutenberg block editor, I can make my previews into reusable blocks. If you’re using a static site generator, or even building your site with m4 macros, shell scripts, and duct tape, it shouldn’t be hard to create a partial or macro that accepts a YouTube video ID.

But if you absolutely must use JavaScript, write it yourself. Don’t use it unless you’ve run into a problem you can’t solve without it. The people using your site might not thank you, but it might help you avoid some headaches down the line.

Fuck You. Pay Me.

I’m a good enough software developer that I’ve been making a living at it since 1999. It’s not my passion; I do the job, and then I get paid.

Click the image to see how a Real Programmer handles unreasonable bosses.

Tom Ritchford at Medium has a problem with this, and with the notion that programming doesn’t require talent or passion. He asks…

Why would you even want to work in a field where you had no talent and no passion? Why would you want to work on something where you are always going to be second rate, and which you will never really enjoy?

And why would anyone hire you? Would you want to eat a meal by someone with no talent for cooking? Or go to a doctor with no talent for medicine?

I don’t know if Mr. Ritchford is a colleague or not. Either way, he seems to have drunk the new corporate Flavor-Aid that demands that workers not merely be skilled, but passionate about their work. He doesn’t understand what sort of emotional labor he expects from programmers.

So I’ll explain. I’ll try to use small words. Here’s the deal: I have the talent. I don’t have the passion. I don’t need it, but some people don’t understand why somebody who doesn’t love to code does it for a living.

Not that it’s any of your business, but I do it because I’m an author who can’t afford to quit his day job yet, and programming pays a hell of a lot more than waiting tables, tending bar, or cleaning toilets — a fact I learned the hard way. Rather than whine about how life isn’t fair because I can’t make a living doing what I love, I swallowed my pride and got a job that paid.

I don’t need to be passionate about writing yet another custom web application for a client that does nothing but provide a pretty skin over arcane business logic and CRUD operations. And while you might not want to admit it to yourself, most of the programming work done in the US is the sort of boring, business-oriented stuff that used to be written in COBOL and run on IBM mainframes.

With the sort of coding I do (so you don’t have to), passion is a liability. Passionate programmers let their ego get in the way. When somebody reports a bug in their code, they scramble to find alternative explanations.

I outgrew that nonsense my first years on the job, because it’s never worth it. Instead, I take a breath, diagnose the problem, and fix it— even if it means working past midnight on my birthday or wedding anniversary. Why? Because I am an adult and a professional.

I might not enjoy the work, but I enjoy the honey-roasted fucknuts out of not being poor. Because having money is so goddamn awesome, I’m determined to give my employer and their clients their money’s worth so that they keep paying me. That means being reliable, being competent, and keeping my skills current.

Yes, I’m a mercenary. I do the job, and then I get paid. Deal with it. How I feel about the work is none of your business, because we’re not friends. If you want me to do more than code for you, I have four words for you. If you’ve seen GoodFellas, you should be able to take an educated guess as to what those for words are.

If not, let me paraphrase it for you:

  • You want me to work overtime? Fuck you. Pay me.
  • You want me to pretend I love my job. Fuck you. Pay me.
  • You want me to pretend we’re friends? Fuck you. Pay me.

How To Retain Good Developers

Table of Contents

DHH, creator of Ruby on Rails, thinks you can’t retain every developer forever, and that you shouldn’t try. He says so right here.

Bullshit. I’d love for a company to try to keep me around forever, as long as they did it by earning my loyalty. It wouldn’t be that hard. Just treat me like a human being instead of a resource to be exploited or a cost to be eliminated if I no longer benefit the company. You think I want to be a mercenary with no ties to anything or anybody?

Hell no. I do it to survive in modern America. I don’t like it any more than you do. So if you’d rather have samurai on the job instead of rōnin, keep reading. Here’s some suggestions for being a company I would willingly stick with throughout my working life.

Offer Adequate Compensation

You don’t have to pay me hundreds of thousands of dollars, but if I’m working for you as a developer, the last thing you want me thinking about is money. So pay me a salary that ensures that I need not worry about not having enough money, and make sure to adjust that salary to account for inflation.

If you’re going to provide group health insurance, please offer plans that aren’t going to nickel and dime me into the ground. If I can get a better deal at healthcare.gov, you’re doing it wrong.

Likewise for retirement benefits. A pension would be lovely, but I’m not that naive. At least offer a 401k with access to index funds and a decent matching percentage.

Have Reasonable Hours

I would love to work at a shop that didn’t care how many hours I put in as long as I provided the required results. Such a results-based approach would motivate me to deliver quality work quickly and efficiently so that I have more time for myself.

However, I recognize that there are some businesses where you need staff on the job eight hours a day, Monday through Friday. I can deal with that.

But if you’re going to have me work more than forty hours a week, and it isn’t because I screwed up, I’ll be a hell of a lot more willing to do it if the overtime is rare, announced well ahead of time (don’t tell me at 4:45PM Friday afternoon that you need me on the job the following Saturday), and compensated.

Always Pay Time and a Half

I don’t care what exemptions the Fair Labor Standards Act provides for techies. I don’t care that I’m on salary. If you want me to work more than 40 hours a week, including time spent on call, I want time and a half for overtime.

The formula’s pretty simple, by the way. I’ll express it C-style.

// Let's start with a reasonable salary. Figures in
// comments below are rounded to the nearest cent.
// But I'm not rounding the wages because those centimes
// do eventually add up. :)
private double _salary = 75000;

// $75000 divided by 52 weeks should be about $1442.31/week.
// $1442.31 divided by 40 hours should be about $36.06/hour.
private double _hourlyWage = (salary / 52) / 40;

// Time and a half for $36.06/hour is about $54.09/hour.
// My cat wrote this code, by the way.
private double _timeAndAHalf = hourlyWage * 1.5;

Now, why pay time and a half for overtime even though Federal labor law doesn’t require it? Simple: remember what I said about loyalty?

You expect to get the work you pay for. I expect to get paid for the work I do. If I only get paid to work forty hours, but you’ve got me working fifty or sixty hours a week and it wasn’t because I screwed up, I’m going to start to suspect that you’re taking advantage of me.

Furthermore, being on a flat salary means I get paid the same whether I work 40 hours or 80. It also means I get paid the same whether I actually work a full 40 hours a week or get all of my actual work done in 8 hours and spend the other 32 hours in meetings so I look busy. There’s no positive incentive for me to work any longer or harder than necessary.

Aside from that, think of it this way: you already have me on the payroll. If you can pay time and a half and get me to put in more time rather than hiring another person, training them, and waiting for them to learn the ropes and figure out the product, you’ll save money in the long run. It’s a win-win situation. I make more money, and you save time and money.

Offer a Healthier Workplace

Don’t worry, I’m not asking for fancy chairs, on-site yoga classes, or an in-house masseuse (my wife would kill me). But I’d appreciate it if you gave some thought to the spaces in which you expect people to work.

We know that sitting around all day is bad for people, yet we still make people do it. Is it really that hard to modify cubicles so that people can stand and work for at least part of the day?

Also, if you ask me to stay late to work on something, and I offer to come in early the next morning instead, it’s for a reason. I know myself better than you do, and I know when my brain has nothing left to give for the day. Tired programmers make dumb mistakes. I learned this the hard way so you wouldn’t have to.

Hell, just let me work from home. Why make me sit in a car for an hour or two a day when I could just walk upstairs to my study?

Make it Easier to Concentrate

It might not be realistic to give every developer a private office, but there are a few things a company can do to make it easier for me to concentrate on my work, which leads to me making fewer mistakes, which in turn saves the company money.

Don’t be shocked if you see me with headphones on. You wouldn’t believe how many developers find it easier to get into a flow state with the right music. (I prefer heavy metal, but tastes vary.) I’m not slacking off, even if it looks like I’m just staring at my screen.

Please don’t just come to my desk and drag me into a meeting. If you have to have meetings at all, it’s better to schedule them ahead of time. Remember that not only is time spent in meetings time not spent working, but once I get out of the meeting I have to get back into the zone.

Please max out the RAM in my computer. RAM’s cheap, and having more means I spend less time waiting for my computer to finish builds and other long-running tasks.

Also, please consider issuing developers machines with SSDs as their OS/software drive. Time spent fighting with one’s tools is time one could spend doing useful work.

Leverage My Experience

As tempting as it might be to just lay off older developers when embarking upon a new project requiring the use of new technologies, think twice. I might know more than you think, and might have at least tinkered with the new hot language/framework/toolkit in my downtime. If not, I’m willing to RTFM and learn it. The Web being what it is today, you might not even have to reimburse me for books. 🙂

Chances are your experienced developers, even if they are old salts like me, can learn a new programming language, development framework, or toolkit faster than you can find wet-behind-the-ears CS grads willing to work for you, acclimate them to the organizational culture, and teach them how to develop software in the real world. We’re already on the job, we know the ropes, and we won’t make promises we can’t keep.

The smart thing to do would be to keep people like me on the job, especially if you need to modernize an existing product. Developers who don’t understand the original product because they didn’t implement it might make the same mistakes. Developers who were on the job the first time around probably have some ideas for avoiding the mistakes they made the first time around — though we might make new mistakes.

“I Do the Job, and Then I Get Paid.”

I might not be a passionate developer who loves to code, but that’s not the kind of developer you want. Passion fades, and love affairs eventually end. I’m what you really want, even if I do think of my position at your company as my “day job”.

In fact, you should be glad. It means you don’t have to worry about whether I find my work meaningful. You don’t have to feed my soul. Just pay me on time and don’t stiff me if I go above and beyond for you. I’ll feed my soul on my own time, as long as you haven’t taken it all.

It’s just a job to me, and that means I do the job, do it well, and then I leave for the day. I’m not going to mess around, because wasting your time just wastes my time. I have better things to do with my life.

Chances are I’ll do more for you in a solid eight hours than you’ll get out of a developer trying to prove themselves by spending fourteen hours a day on the job. So don’t choose a “passionate” programmer. Choose a working-class professional like me. I’ll surprise you.

Code For Your Best Friend

Table of Contents

I recall a programming proverb dating from the mid-1990s that says, “Always code as if the guy who ends up maintaining your code is a violent psychopath who knows where you live.” A quick Google search suggests it arose in the Perl community, and attributes it to various sources.

It’s good advice, but not exactly something you’d expect to see on a motivational poster in an American workplace unless you work in a shop where management regularly jokes about improving worker morale by beating the crap out of them.

Instead, I would suggest that you design and implement your code as if the poor schmuck who will inherit your code after you leave is your best friend. Would you want your friend to chew up a bottle of aspirin a week as they try to make sense of your code? Would you want your friend to come to hate you for the suffering you inflicted upon them?

It isn’t even that hard to write code that another developer can take over without resorting to self-medication to kill the pain. We’ve known most of the principles for at least a decade:

Indent your code properly.

This should be self-explanatory, and your preferred editor/IDE probably provides tools to help. Either pick a style, or stick to the style already in use at your shop.

Use meaningful variable names.

Something like string driverFirstName or driverFirstName = '' is self-explanatory, but I’ve seen lazy programmers use names like drvfstnm or DRIVER_FN. And the latter, if you’re used to C and languages derived from C, is easy to mistake for a constant if you don’t check the declaration.

Use meaningful method names.

It’s the same principle as with variable names. A new developer is going to have an easier time understanding what a method named UpdateDriversLicenseAddress() does than if the method is called UpdDLAddr().

Don’t abbreviate.

As soon as you start using abbreviations, you force the next developer to spend time figuring out what the damn abbreviations mean. This breaks the developer’s flow and hampers productivity.

Keep your methods short.

Anything method longer than thirty lines is probably trying to do too much, and is a good candidate for refactoring.

Use the standard library instead of reinventing the wheel.

Admittedly, “standard library” is a C-specific term, but chances are your preferred programming language has something similar with a different name. Everything you implement yourself is more work for the next person. It’s also more for you to test and debug, and you probably don’t get paid enough for that shit.

Don’t repeat yourself.

The same functionality shouldn’t be implemented in two modules, because it will have to be updated in two modules if requirements change. It will also have to be tested twice. If you’re tempted to copy and paste code because you have a case that needs slightly different functionality, try inheriting from the base code.

What about comments?

You may have noticed that I didn’t say anything about commenting your code. You can comment your code if you like, or if your shop’s coding standards specify comments when declaring classes and methods to identify them and state their purpose.

But I won’t read them. I don’t trust comments in code. To paraphrase Dr. House: Comments lie. Code doesn’t. I know from experience, because I’ve been the “next guy” — and I’m nobody’s friend.