Speed Perception

TL;DR: Please take the speedPerception challenge to help us confirm results about which web performance metrics best match human perception of speed.

Last summer, I was involved in a study called “SpeedPerception”, a large-scale web performance crowdsourced study focused on the perceived loading performance of above-the-fold content aimed at understanding what “slow” and “fast” mean to users. I am now involved in the second part of this study which aims to confirm (or refute) our findings.

SpeedPerception: the general idea

Traditional web performance metrics, like those defined in W3C Navigating Timing draft specification focus on timing each process along the content delivery pipeline, such as Time to First Byte (TTFB) and Page Load Time. SpeedPerception’s goal is to tackle the web performance measurement challenge by looking at it from a different angle: one which puts user experience into focus by focusing on the visual perception of the page load process. We show the user  sample video pairs of websites loading generated with http://www.webpagetest.org/ (WPT), and ask them which of the pair they perceive as having loaded faster.

In the first phase, we measured only Internet Retailer top-500 (IR500) sites in desktop size. Now we are testing whether the results we measured are true: in other words, do they only work for our IR500 sites on desktop? Will we get consistent results when testing  Alexa top-1000 (Alex1000) homepages? Will we see the same results if we test on mobile size screens with mobile lie-fi performance?

In this second phase, we’re testing both mobile and desktop versions of both IR500  and Alexa1000 website home pages. We’ve also added a way of measuring the user’s time to click so we can compare apples to apples.

The goal is to create a free, open-source, benchmark dataset to advance the systematic study of how human end-users perceive the webpage loading process: the above-the-fold rendering in particular. Our belief (and hope) is that such a benchmark can provide a quantitative basis to compare different algorithms and spur computer scientists to make progress on helping quantify perceived webpage performance.

Take the Speed Perception challenge !

How was SpeedPerception created?

Videos were created using  Patrick Meenan’s open-source WebPagetest (a.k.a WPT). We made 600+ videos of  2016 IR500 and Alexa-1000 home pages loading. The runs were done in February 2017. Videos were turned into gifs. Video pairs  were grouped using a specific set of rules to help limit bias and randomness. Everything is available on GitHub at https://github.com/pdey/SpeedPerception.

Open Source

Just like we did with the results of phase 1 of SpeedPerception, once the crowd-sourcing component generates a sufficient amount of user data, we will open source the dataset, making it available to the web performance community, along with the analysis of what we discover.

Please help us by taking the SpeedPerception Challenge now. Thanks.

Results from Phase 1

In phase 1, we discovered a combination of three values: an abbreviated SpeedIndex up to time to click (TTC) and an abbreviated Perceptual Speed Index up to TTC, in conjunction with startRender (or Render), can achieve upwards of 85%+ accuracy in explaining majority human A/B choices. Does the power of this new combination “model” hold true for all sites, or just our original data set? This is what we’re working on finding out.

If you’re interested in phase 1, here’s some more light reading:

 

Leak without a trace: Anonymous Whistle blowing

Instructions on how to leak data without getting caught

  1. Don’t leave digital traces while copying data.
  2. Write stuff down on a pad which belongs to you, and take it home.
  3. Photograph your screen. Don’t create files with copies of the data you are planning to exfiltrate on your work computer.
  4. If the data is on an internal web server, try to access what you are planning to leak in the form of multiple partial queries over a period of time, instead of as one big query.
  5. If you have large volumes of data, save it on a never-used-before USB drive and bring that home. Don’t ever use that USB drive for anything else again.
  6. Don’t use work-owned equipment to post from. Many employers have monitoring software installed, and will easily be able to see who posted what.
  7. Don’t use equipment where you’ve installed employer-supplied monitoring software to post.
  8. If you just read this, on equipment which might be monitored, wait a while before posting anything sensitive. Don’t give somebody who is watching a chance to correlate your seeing this with a post right after that.
  9. Install tor. You can get it at http://tor.eff.org. This is a special browser which is slow, but provides strong anonymity. It will prevent anybody at your ISP (if they’re watching) from knowing what sites you visit with it, and it will prevent any sites you visit from knowing what the IP address of your computer is. This will make it much harder for either of them to identify you.
  10. Use the Tor browser for posting your leak.
  11. You must follow these instructions to make sure tor really works: https://tor.eff.org/download/download-easy.html.en#warning.
  12. The instructions about never opening a downloaded file are vitally important — things like .doc and .pdf files can contain software which will expose who you are.
  13. The instruction about using an https version of a web site instead of the plain old http version is also very important. This is because while tor provides very strong anonymity, it doesn’t provide a secure connection to the web site — the https connection to the site does that.
  14. If you’re posting to a social site like twitter or reddit, or using an email account for it, you’ll need to set up a new account for posting your leak.
  15. If you’ve got an account which you have used when not on tor, then Google, twitter, reddit, etc. can identify the IP address of your computer from previous sessions.
  16. If you’ve ever posted anything on an account, there’s a good chance you’ve leaked information about yourself. Don’t take this risk, and just use a new account exclusively for leaking.
  17. Do NOT post files from standard editors, like Word, Excel, or photos from your camera. Most programs and recording equipment embed metadata in their files, like the identify of the creator, the serial number of a camera, and the likes in their files which can be used to identify you. Plain old .txt files are ok. Pretty much anything else risks your identity.
  18. When posting photos, be sure to use a metadata stripping tool like jhead for photos. Turn off photo syncing (e.g., iCloud).
  19. The secure drop systems used by some news outlets like ProPublica and the New York Times may be able to strip this kind of thing, but ask a journalist about your specific file format first.
  20. After posting the leak, you need to NEVER use that account for any purpose not directly tied to the leak, since you may make the mistake of giving away your identity.
  21. If you want to leak to the press (which may get broader coverage, but may also decide not to publish at all) organizations like ProPublica and the New York Times have special drop boxes set up to allow the posting.
  22. Details here:
    http://www.niemanlab.org/2017/01/how-easy-is-it-to-securely-leak-information-to-some-of-americas-top-news-organizations-this-easy/
    https://www.nytimes.com/newsgraphics/2016/news-tips/#securedrop

Web Performance Stats are Overrated

Note: A more polite version of this post originally appeared on Instart Logic’s blog

Who cares about performance?  Your customers, that’s who!  Speeding up your site by several seconds, or even by hundreds of milliseconds, will make your customers happy. Well, at least they’ll be less irritated.  That’s pure logic. I am not citing statistics. I am using common sense.

For example, a 50% decrease in file size — cutting bloat in half — has a greater impact on someone 2G mobile than on a T1 line. Common sense dictates the impact is greater on a 5Mb site than a 5Kb one, no matter the network speed as performance gains achieved by halving a 5Kb download may not even have a noticeable effect. Similarly, improving a 12s page load to 11s doesn’t have the same impact as improving a site from 3s down to 2s. The impact of a one second improvement depends on the original experience. This is obvious. It’s common sense.

Conclusions based on common sense are often accurate, but aren’t considered factual like conclusions based on statistics.  Statistics are often used to demonstrate something as fact, but a statistic is really only a fact about a piece of data. Mark Twain is credited with saying “Facts are stubborn things, but statistics are pliable.”

We discuss web performance statistics as if the web were a monolith, as if all web applications were uniform, like performance improvement effects are linear. They may not be represented by a simple exponential equation, but performance isn’t a simple science, and metric interpretation shouldn’t be assumed to be linear, or even accurate.

The statistic many web speeders quote “a one second delay in web page responsiveness leads to a 7% decrease in conversions, an 11% drop in pageviews, and a 16% decrease in customer satisfaction” is kind of bullshit today. This quote comes from a 2008 study: a study that came out a few months after the iPhone SDK was released and Android Market came into being, before either proliferated. When that study was conducted, the iPad and Android tablet were a few years off. As web speeders, we can’t quote a performance study that basically predates mobile. Yet, that’s what we’re doing.

While the customer satisfaction statistics might be BS, the conclusions are not. The longer the site takes to load, the less happy your customers will be, the more users will abandon your site, the lower your conversion rates, and the less money you’ll make. It’s not even that your customers will be unhappy — it’s that they may not be your customers anymore. That’s common sense, no matter what the actual percentages are.

Definitely give yourself a performance budget and test your site. Test your application throughout the development process. Optimize and right size your images, setting dimensions. Reduce DNS lookups. Reduce bloat, minimizing request size, GZipping all requests. Make fewer HTTP requests or serve content over HTTP/2, caching what you can. Basically, follow as many performance recommendations as you can.

Improve the performance of all of your content, not just your home page. Focus your energies on the critical path of your site. It’s obviously less important to optimize some pages, say the “libraries we use” page linked to from an “about us” page linked to from a political candidate’s website. But do realize users often enter your site thru a side door: for example, a product page, with the shopping cart experience being a necessity for all sales for an online store. In the case of eCommerce, optimizing your homepage might create the most “savings”, but will do little to improve user experience for your actual potential customers.

And never forget: improving the download speed is not enough: improving your site by one second delay won’t improve customer satisfaction if, once loaded, they’re met with an unresponsive UI.

Or maybe it will.

Let me go back to 2008 to test that out.

Working at Visa

Visa is a bastion of mediocrity with low morale. I had high hopes when I accepted a role at Visa Inc. in Foster City. I was hired to work on a front end components library, speak at conferences, etc.

Visa has a world famous brand name so even though the company is segregated, sexist and has the lowest employee morale, it will take a long time before all the cookies crumble. Visa is a good place to work if you are a staunch believer in nepotism and the caste system. Other than the regular paycheck, there is nothing good to say about working at Visa.

So why does engineering at Visa suck so bad?

  • Sexist: women hold specific roles and have limited to no chance of growth.
  • Racist: unless you’re Indian, you’re out of luck. Latinos are relegated to cleaning and food services. Being black is OK, as long as you are not African American. Being white is OK too, as long as you’re male.
  • Ageist: Not sure if they’re being cheap or ageist, but if you’re not of Indian descent, the best way to join Visa is as an intern / recent college grad. Anyone older, with experience, skills, and compensation to reflect that, forget it.
  • Cheap: They would rather hire 40 mediocre engineers at $40/hour than 5 excellent engineers at $120/hour. They’re getting rid of their quality contractors and backfilling with less than mediocre “warm bodies”. Pennywise. Pound foolish.
  • Bait and switch. Promised benefits then cut them when we signed on the dotted line. Visa cut the retirement plan (6% pay cut), they increased insurance co-pays by 20%. They required managers to give poor reviews so they didn’t have to give good bonuses, pay raises or stock. They don’t pay for anything: no snacks, no birthday cakes, no small touches to make staff feel valued.
  • Unethical: The $5,200 continuing education benefit they allegedly offer can only be used for college courses, not for conferences or workshops that professionals access as continuing education. They only hire college grads, so a ‘college class’ benefit is not an actual benefit.
  • Name droppers: Where you graduated from is important. What you know is not.
  • Moronic: The quantity of our code is more important than the quality of code. Any good Engineering leader should know a few lines of good code is better than many lines of bad code. At Visa, there are no good leaders. The metrics measure quantity not quality. That they have metrics itself is mind boggling.
  • Empire builders: Managers like to hire many people, building empires, to show their importance. They have no clue how to manage. No interest in managing.
    Just want to brown nose to their own higher-ups, and perhaps add value to their name so they can get a prestigious title, not realizing Visa is one of the few SF Bay Area companies that values nepotism over actual accomplishments.

My advice to potential employees is to go to GlassDoor and read all the reviews. Sort by date. Visa is a sponsor of Glassdoor, so the first review will likely be a positive one, possibly from an intern. You’ll see complaints. Compliments are either outliers or from recruiters and directors trying to obfuscate their abysmal record.

At Visa, the crappy staff stays on as long as they can just for the paycheck.  Go-getters, those with real talent, high tail it, if they made the mistake of joining at all. The odd decent engineers on the payroll are those too lazy to move on to better environments, or those who have had their souls crushed and now lack the confidence they should have. If you want to work with Directors eager to employ talentless seat warmers who wont detect incompetence, by all mean, Visa is always hiring.

animation-iteration-delay hack

While there is no such property as an `animation-iteration-delay`, you can employ the `animation-delay` property, incorporate delays within your keyframe declaration, or use JavaScript to fake it. The best method for ‘faking it’ depends on the number of iterations, performance, and whether the delays are all equal in length.

What is an animation iteration delay? Sometimes you want an animation to occur multiple times, but want to wait a specific amount of time between each iteration.

Let’s say you want your element to grow 3 times, but want to wait 4 seconds between each 1s iteration. You can include the delay within your keyframe definition, and iterate through it 3 times:

.animate3times {
    background-color: red;
    animation: yellow;
    animation-iteration-count: 3;
    animation-duration: 5s;
 }
@keyframes yellow {
 80% {
    transform: scale(1);
    background-color:red;
  }
  80.1% {
    background-color: green; 
    transform: scale(0.5);
  }
  100% {
    background-color: yellow;
    transform: scale(1.5);
  }
 }

Note the first keyframe selector is at the 80% mark, and matches the default state. This will animate your element 3 times, staying in the default state for 80% of the 5 second animation, or for 4 seconds, and moving from green to yellow and small to big over the last 1 second of the animation duration, before iterating again, stopping after 3 iterations.

This method works for infinite repetitions of the animation as well. Unfortunately, it is only a good solution if the iteration delay between each iteration is identical. If you want to change the delay between each iteration, while not changing the duration of the change in size and color, you have to write a new @keyframes definition.

To enable different iteration delays between animations, we could create a single animation and bake in the effect of three different delays:

.animate3times {
    background-color: red;
    animation: yellow;
    animation-iteration-count: 1;
    animation-duration: 15s;
 }
@keyframes yellow {
  0%, 13.32%, 20.01%, 40%, 46.67%, 93.32% {
    transform: scale(1);
    background-color:red;
  }
  13.33%, 40.01%, 93.33% {
    background-color: green; 
    transform: scale(0.5);
  }
  20%, 46.66%, 100% {
    background-color: yellow;
    transform: scale(1.5);
  }
 }

This method may be more difficult to code and maintain. It works for a single cycle of the animation. To change the number of animations or the iteration delay durations, another keyframe declaration would be required.

The animation-iteration-delay hack

There’s a solution that currently works that is not specifically allowed in the animation specification, but it isn’t disallowed, and it’s supported: you can declare an animation multiple times, each with a different animation-delay.

.animate3times {
    animation: yellow, yellow, yellow;
    animation-delay: 0, 4s, 10s;
    animation-duration: 1s;
 }
@keyframes yellow {
  0% {
    background-color: green; 
    transform: scale(0.5);
  }
  100% {
    background-color: yellow;
    transform: scale(1.5);
  }
 }

See http://codepen.io/estelle/pen/PqRwGj.

We’ve attached the animation three times, each with a different delay. In this case, each animation iteration concludes before the next one proceeds. If they overlap, while they’re concurrently animating, the values will be the values from the last declared animation.

See http://codepen.io/estelle/pen/gpemWW

Of course, you can also use JavaScript with animationstart, animationiteration and animationend eventlisteners that add or remove animation names or classes from your element.

Survey for US Developers’ Experience

I created a survey of developer experiences for US based developers.
While the results aren’t scientific in the the questions and optional answers were not all that well written, and the distribution may have been biases (only reached Twitter users), some of the results were indeed interesting, and may lead to me doing some further, more professional, study.

According to their own self reporting, men experience the following more than women do:

  • People assume more men developers have a CS degree (1.18)
  • People think men developers are very skilled at tech when they first meet them. (0.89)
  • People assume men  developers are good at math (0.80)
  • People make accurate judgements as to men developers ‘s skill set when they meet them (0.73)
  • Men developers sign up for conferences or RSVP for meetups and let their bosses and partners know the plans them made (0.65)
  • People assume men developers are gamers (0.59)
  • People listen to men developers  (0.54)
  • People assume male developers are straight (0.52)
  • Men developers  provide constructive criticism to others online (0.51)
  • People value men developers ‘s opinion (0.48)
  • People assume men  developers are correct (0.45)

According to their own self reporting, women experience the following more than men do:

  • People assume women developers are not technical when they meet them (2.22)
  • Women developers  are  told to be “nice” or to “smile” (1.98)
  • Women developers  have been called bossy (1.80)
  • Women developers  are the ones that makes sure they have a housesitter, babysitter, dogsitter, other so they can attend events such as conferences. (1.75)
  • Women developers have been called aggressive 1.65
  • People question women developers ‘s accuracy and/or knowledge (1.42)
  • Women  developers think about transportation to and from the venue before agreeing to attend events (1.25)
  • People explain women  developers ‘s own content to them, like their tweets and posts (1.18)
  • Women  developers go into work on the weekend (1.18)
  • People assume women  developers  know photoshop or have other design skills (1.14)
  • People comment on women developers ‘s appearance 1.12
  • Women  developers think about the different ages of their co-workers (1.06)
  • People interrupt women developers (1.00)
  • People are surprised to learn women developers are gamers  (0.98)
  • Women  developers think about what they are going to wear to work. (0.98)
  • People think women developers are administrative or custodial staff (0.95)

Lyrinė Tālrunis: “Telephone” with Lyric Translations

Last week I hacked together a mashup of HP’s IdolOnDemand‘s free Speech Recognition API and Google’s fee-for-service Translation API to create a Lyric Translator. Of course, I had to make the site responsive using VW units for text, and Flexbox for the layout. I also used a datalist to provide an optional list of usable media files. Then, tonight, I wrote a blog post explaining these components.

Enjoy!

The app

Lyrinė Tālrunis, or “Lyric Telephone”, does two things:

  1. It captures the text from an audio file using the free Speech Recognition API from HP IdolOnDemand,
  2. It then translates the captured text into from the original language into French, German, Spanish, Vietnamese, Russian and then back to the original language, enabling you to create new lyrics for — or a more entertaining interpretation of — your favorite songs.

The name is basically Lyrics, as in lyrics from songs, but you can use any media file, and ‘Telephone’ in reference to the game of telephone you learned in pre-K, where when a story gets passed to too many people (or languages) the original text gets morphed into something else.

As deployed, the app provides for two preloaded options of Rudolph the Red-nosed Reindeer and Frosty the Snowman, but you can include a link to any .wav or .mp3 file you find on line.

I’ll be expanding the application to allow for file uploads, and hope to implement uploading directly from your device’s microphone with:

<input type="file" accept="audio/*;capture=microphone">

For right now, simply find a song online, or even a video file, and include the full URL in the input box.

HP’s IdolOnDemand Speech Recognition API

IDOL OnDemand’s Speech Recognition API creates a transcript of the text in an audio or video file. It supports seven languages – including both US an UK English (yes, it will produce “colour” instead of “color” if you ask it to).

You do first need to register with IdolOnDemand to get an API Key. Then it’s a simple AJAX call.

The values you need create the request URL for the speech recognitio API include:

  • The encoded URI to your .wav or other audio of video file.
  • Your API Key
  • The language your file is in (defaults to en-US)

Here is how I created my URL:

  var apikey = YOUR_HP_API_KEY;
      url = document.getElementById('url').value,
      language = document.getElementById('lang').value, 
      query = 'https://api.idolondemand.com/1/api/sync/recognizespeech/v1' + '?';       
  query  += "&url=" + encodeURIComponent(url);
  query  += "&apikey=" + apikey;
  query  += "&language=" + ( language || "en-US");

Where url is the id of the input where the user enters the full path to the media file. The input has 3 default options for you to choose from, but you can enter any text you wish. This is explained in the <datalist> / list attribute section below.

The ‘lang’ is the ID of the <select> drop down that list the langage of the media file.

<select name="lang" id="lang">
  <option value="en-US">English (US)</option>
  <option value="en-GB">English (UK)</option>
  <option value="de-DE">German</option>
  <option value="es-ES">Español</option>
  <option value="fr-FR">Français</option>
  <option value="it-IT">Italiano</option>
</select>

The speech recognition API works for all the above languages and Chinese. Surprisingly, I can actually read and understand all of the languages above (don’t ask).  As I can’t read Chinese and wouldn’t be able to debug it, I didn’t include it in this app.  If you want to include Chinese as an option, please feel free to fork the app repo and add Chinese back in, but please use your own API key.

IDOL OnDemand’s Speech Recognition API uses the language code and the country subcode, so use the long form like “en-US” and not “en”. Don’t know what I am talking about (or have insomnia)? Read up on language tags.

Depending on the file size, your file can take a while to process, so make sure to let your user know something is happening, and make sure to handle errors in case it times out. For better user experience, when the button gets clicked, calling the API, the content of the button changes to a rotating pipe in the hopes of making a quick and easy spinner. (Check out the CSS file if you want to learn the animation, as I am not covering it here). The animation stops and the button returns to the original text when the text extraction of the media file is returned from the Speech API.

 var app = {
     ...
    
     init : function () {
	     // add eventHandler to button
        document.getElementById('doThis').addEventListener('click', function(){
          app.submitToHP();
          app.changeButton();
        });
      },

      // get the words from the original media file
      // the `data` object contains default values & the `apikey`
      submitToHP : function () {
        data.url = document.getElementById(
url').value || data.url;
        var query = data.request_url + '?';
            query += "&url=" + encodeURIComponent(data.url);
            query += "&apikey=" + data.apikey;
            query += "&language=" + document.getElementById('lang').value || "en-US");

        var request = $.ajax(query, function(e) {
                // successfully sent - no actions
              })
            .done(function(e) {
                // response received - handle it
                app.acceptResponse(e.document[0].content);
              })
            .fail(function(e) {
                // error - handle it
                app.acceptResponse('Oops, something went wrong.');
              })
            .always(function(e) {
                // finished - stop button animation
                app.revertButton();
            });
      },
      ... // continues

The reqest returns a JSON object:

{
  "document": [
    {
      "content": "the media speech is here"
    }
  ]
}

So we grab that content with:

e.document[0].content

where e is the response.

The other functions included, but not described include:

  • app.changeButton() — changes button to a spinner
  • app.revertButton() — resets the button to original behavior
  • app.acceptResponse(e.document[0].content) — writes text to the page, and initiates translations, which are done via the Goole Translate API

Google Translate API

I tried finding a good, free, intuitive, easy to use, translation API, but came up empty handed. Sorry Microsoft, you have too many steps, and I couldn’t just “dive right in.” I do, however, have the Yandex translation API on my list of things to look up. It looks like it might be a good free alternative to Google’s fee-for-service translation API.

Time is money, and I was already familiar with the Google Translate API, which is the main reason I chose it. Again, fork me repo to try something different.

The request URL for Google Translate API looks something like this:

var request_URL = "https://www.googleapis.com/language/translate/v2?key=" +  
  YOUR_GOOGLE_API_KEY +
  "&source=" + from +
  "&target=" + to +
  "&q=" + encodeURIComponent(text);

Where you use your own Google API Key, the ‘from’ is the original language, the ‘to’ is the language you want to translate to, and the text you encode with encodeURIComponent(text) is the return value from the Speech Recognition API, what we captured as e.document[0].content above.

As we are translating from the original language to French, German, Spanish, Vietnamese, Russian and then back again to the original language, we are calling the Google API 6 times. The important information is how to create the link for Google’s REST API. You can take a look at the source code to see how I iterate thru the various languages and call the AJAX call for each translation.

CSS3 Values

The page is full responsive. On larger devices, the font is larger. This is done without @media queries. I know. I know. Media queries are all the rage. But they’re not always necessary. CSS3 provides responsive features that enable the creation of responsive content without having to define where your design splits. The browser can do it for you.

In this case, it’s the VW, or viewport width unit, that makes the site naturally responsive. The VW unit is relative to the viewport width: the viewport width is 100vw. If you don’t know all your length units, my 4 year old post needs some updating.

  h1 {
    line-height: 30vh;
    font-size: 8vw;
  }

The above CSS snippet reads “the line height should be 30% of the viewport height. The font size should be 8% of the viewport width”

As the viewport narrows, the font-size will shrink. Yes, it will get illegible if the viewport is too narrow, but no phone is narrow enough to make that illegible. That size is relatively huge, and will even be legible on new watches. And the height shrinks, so does the line height, meaning the h1 will never be taller than 30% of the height of the viewport.

I used VW and VH for the height of the blue header and containers for the translation content: even when empty, the articles will be 40% of the document height.

The content in the button and the input also grow and shrink as the viewport grows or shrinks. vh and vw are very well supported, though vmax, the maximum value of the viewport width and height, and vmin, the lesser of those 2 values, is not fully supported.

CSS Flexible Box Layout Module

CSS Layout is fun! No. Seriously. It is. Just use flexbox.

body {
  display: flex;
  flex-direction: column;
  flex: 1 0 300px;
}
header, article {
  flex: 3;
  min-height: 40vh;
}
footer, main {
  flex: 1; 
  max-height: 10vh;
}
main, article {
  display: flex;
  justify-content: space-around;
  align-items: center;
}
section {
  flex: 1;
}
@media screen and (max-width: 500px) {
  main, article {
    flex-wrap: wrap;
  }
}

Above is just part of the CSS. I’ve posted the CSS relevant to the flexible layout of the document. You’ll note that the layout has four vertical sections: the header, main section with the buttons, the articles where the translations go, and the footer.

The body CSS code block above makes the body a flex container, and the header, main, article and footer all flex items. The flex-direction is column, so they’re one on top of another instead of row, which would put the parts side by side.

The main and article are not only flex items, but they, in turn, are also flex containers. The default flex-direction is row, so the children of the main and the children of the article will be laid out side by side within their parent. We have two flex items within the article (the original text result from the Speech API and the final result processed thru 5 translations.) These will be side by side, and will always be of equal height. They will not wrap by default, but if the width of the screen is 500px wide or less, the row of content can wrap, which means the translation can land below the text capture, and the input can land below the button, which can fall below the language selection.

This project is to show a very simple example of flex layout, and is not meant as a full flexbox tutorial. To learn more about flexbox, I have an open source flexbox tutorial you can play with. There you can see that justify-content: space-around; means that the extra space around the items will be evenly distributed around each item, and all the other flexbox, including several not included in this demonstration.

Datalist element and list attribute

Take a look at the input on the page. You’ll note, in modern browsers, there is a little arrow on the right, which if clicked, shows an autocomplete. This effect is achieved using the HTML5 list attribute along with the <datalist> element and that element’s nested <options>.

<input type="url" list="urls" id="url" placeholder=" URL of .wav file">
    
<datalist id="urls">
  <option value="http://estelle.github.io/audiotranslator/data/frosty.wav">Frosty</option>
  <option value="http://estelle.github.io/audiotranslator/data/rudolph.wav">Rudolph</option>
  <option value="http://estelle.github.io/audiotranslator/data/tet.wav">Test File</option>
</datalist>

In this example, we have an <input> of type url, with a list attribute. The value of the list attribute is the value of the ID of the datalist element. This associates the urls datalist with the input. If a browser doesn’t support datalist, it will simply not show the datalist. Totally progressive enhancement: the form control is still usable in Netscape 4.7

If the browser does support datalist, a drop down menu of the options will show when the input has focus. It will only show the values that are still potentionally valid. If you enter ‘h’, all the values will still show. ANy other character, and the options will no longer be valide options, and they will no longer be displayed. I have a tutorial on web forms, which demonstrates the inclusion of datalist on text, url, email, number, color, range, date and time input types.

Future of the app

Here are some ideas I have for expanding the application. Please fork and do it for me :D

  • File upload option
  • Drag and Drop from desktop to upload file
  • Audio Capture directly from your device
  • Inclusion of original <audio> for your listening pleasure

Binders full of Women

You’re looking to improve the diversity of your technical conference. Well, let me google that for you!

Two years ago, I organized a conference called Confident-Coding. We had an open CFP, but only self-identified women responded to it. In one week, 12 women applied to speak.  You’re saying that not a single woman replied to your CFP? You’re obviously doing it wrong.

Only women applied to speak at my conference because of where I promoted the CFP. Where are you announcing your CFP? Reddit? If you promote your conference or job to white males, you’re only going to get white males applying.

With Confident-Coding, I successfully proved a point: If you only promote a CFP to an insular group of people, you are only going to get members of that population to apply.

The Conference wasn’t actually intended as a woman-only event. I just wanted to show it was possible to find AMAZING female presenters.

I promoted the conference thru my regular channels of promoting conferences: I asked my multi-gender network to promote it for me. The interesting thing: most of the cis-men who promoted it did so as a women’s conference. There was nothing that read “women only” on the website. They assumed it was “women only” because of the demographics of the speakers.

Yes, all male lineups look to us women just like all female lineups look to you men.

How do you think your male-only conference makes me feel?

“So, if this all female lineup is for women only, are all male lineups for men only?” I asked.

“Well, that’s different,” was the response I heard from the clueless ones.

“Holy shit, you’re right” was the response I heard from those for whom this was a teachable moment.

Yes, all male lineups look to us women just like all female lineups look to you men.

Are you intentionally leaving out entire segments of the population? Yes, you need a diverse lineup. (see Ashe Dryden, and more from Increasing Diversity at Your Conference also by Ashe Dryden). And, no, don’t ask me to do the job of finding your speakers for you.
Please do your own research instead of asking us to do it for you. Sorry to be snarky, but I already have 3 jobs. Yes, being a woman in tech is 2 jobs. There’s the tech part, and the woman part. I code for 40+ hours per week. That’s my first job. I am also writing 2 books and speaking at a multitude of conference: that’s my second job — which, admittedly, most engineers may not have. My third job? I spend an inordinate amount of time identifying potential speakers for conference organizers who don’t take the extra 5 minutes to do it themselves.

Are you intentionally leaving out entire segments of the population?

“If it takes 5 minutes,” you ask, “why is it a full time job?” It takes 5 minutes to find the right people to refer. It takes a couple hours to compose the email explaining that just blasting these other people who also have 2 full time jobs is not going to work. Then I spend another couple hours making my original email sound more polite than this post.

I take the time in my email response to teach conference and meetup organizers how to ask these not-so-random strangers to speak, and to inform the recipients that this wouldn’t be such a difficult issue for them if they actually had female or otherwise non-cis-white-male developers and developer evangelists at their place of employment whom they can ask. Yes, it’s fine to ask your own co-workers to help you find developers: they’re paid. Don’t have women and non-cis-white-male co-workers? Please hire some. Not only will it improve your working environment and your product, but then you can ask them, instead of expecting all the rest of us “women in tech” whom you haven’t employed, to do it for free.

When we spend that 5 minutes searching, the hours writing the email, and the days writing these blog posts, or educating you on Twitter, that’s time we are not spending writing books/talks or ‘coding for cash.” It costs us money.

Don’t just identify potential female speakers, make sure you ask them to present correctly. For example, only ask me to speak if you’re interested in what I have to say. Tell me why I am of interest. Don’t let me assume that it’s just because you haven’t filled your boob quota.

And don’t just look for boobs. Do you think because you have 20% white women and 80% white men, your conference or employer experience is diverse? Nope. Sorry. Even if you live in Australia, where the population is 92% caucasian, you’re still not reflective of society. You’re still not inclusive. Not even close.

Diversity isn’t just a male versus female thing: it’s a people thing.

You already know if you have no speakers who identify as female, you’re doing it wrong. But you should also know, if all your speakers are cis-gendered white men and women, you’re still doing it wrong. You can still improve. If all you’re speakers were born in the 1980s, you’re doing it wrong? The more diverse your lineup, the more diverse your attendee base will be. The more diverse your conference, the more interesting the conversation will be.

Do you know what an all under 30 line up look to those who are over 60? It looks just like what a lineup of all 60+ year olds would look like to someone under 30. Yes, ageism is rampant in our industry too.

An all young white male lineup looks to a non-young-white male similar to what a lineup of all eldery Korean women would look to a young white male. No, it’s not “different.” Young, white, straight male is not a norm. It is only the norm for those who are young, white, straight men. Leave out the age, and in the US, it is the norm for about 26% of the population. That leaves out 74% of the population. Why are you intentionally leaving out 74% of the population?

It’s not just about your male to female ratio. It’s about gender, age, race, sexual orientation, body size, social comfort levels, technical abilities, income, everything! Different perspectives provide for much more interesting conversations.

But don’t just pull speakers from other conferences. We don’t need to hear more of the same prominent voices. There’s little value in the view that only those who have spoken before are those who are worth listening to. Instead of asking the same speakers to give the same talk (that is available on Youtube), find out who those speakers listen to. Look at the speakers you were intending to ask: who do they follow on Twitter? Who do their followers follow? Found someone great with imposter syndrome? Take the extra time to encourage them. They’re still said no? Look at who they follow, there may be an uncut gem in there.

Now that you know you have a problem, it’s time for you to solve it. (Yes, you. Sorry, I can’t do it for you.)

There’s little value in the abysmal view that only those who have spoken before are those who are worth listening to.

Ask diverse people in your own company where to target diverse speakers (and where to help recruit other diverse employees). Ask them to cross promote to their LGBT chat list, breast-feeding support group, and women in tech groups. Do you think some of those groups are irrelevant? You likely don’t realize what the average technical woman thinks of Reddit!

Ask your eldest employee. Ask your youngest employee. Ask the transgender woman in your DevOps team. Ask the Latino man in your front end team. And, if you don’t have transgender, Latino or African American persons in your organization in positions of responsibility, fix that too. For example, pay your interns. This will ensure that your interns can be there on merit — yes, that’s a faux “meritocracy” we don’t really have–not just because they can be there because they have a wealthy parent who can fund their eternal education.

Remember, being your personal Google is not part of the job description of any other employees in your agency. When you ask them (and you should), you are burdening them with additional responsibilities. They just did you a favor. Don’t forget to appreciate that appropriately, and return the favor somehow.

Go thru open networks to find diverse speakers. If you get rejected by the 10 most popular female presenters in your industry, keep asking? If you asked the 10 most popular men in your industry and they said no, would you cancel the event or would you continue to looking? Same thing!

If you asked the 10 most popular men in your industry and they said no, would you cancel the event?

Find the top 20 speakers you want for your conference, of all genders, and look at the people they talk to or RT on Twitter and other social media: likely, you’ll find an abundance of qualified people to target. When you ask them to speak, be very specific about why you asked them. I don’t reply to recruiters — for jobs or CFPs — if it’s all about them and not about me. Nope, not narcissistic. I just don’t want to put more thought and time into answering their email than they spent on their initial request.

Make sure your developer evangelism team is diverse, and has no bad apples. Even if he’s an awesome, funny speaker, get rid of the douchebag that discourages other people from applying or staying on in the role. Not getting enough diversity in your application pool? (If you didn’t have an open application procedure, you really fucked up.) Where are you posting?

  1. Do NOT post your job or CFPs to YCombinator or Reddit, because that is what your application pool will look like.
  2. Do NOT “ask your friends” only: they tend to look like you and have similar life experiences.
  3. Do NOT try to target your event for ninjas, cowboys or hipsters.
  4. Do NOT promote your conference as a party. Don’t promote the drinking. Have (and announce that you are going to have) quiet spaces, non-alcoholic beverages on par with the alcoholic ones[1], etc. in addition to the MANDATORY code of conduct.
  5. And, for goodness sakes, do NOT have strippers or “booth-babes” at your event.

There are resources all of the Internet. Take the time to look for them.

P.S. Pay all your employees what they are worth, not more to people simply because they asked for it. Otherwise, you’re compensating people for being assertive not skilled.

[1] If you are serving wine and beer in plastic cups, serve water, juice and soda in those cups too. If the beer is in glass bottles, serve high end non-alcoholic drinks in glass bottles: Perrier, Mexican Coca-Cola, even IBC Root Beer (in the USA), whatever. Make your non-alcoholic drinks on par with the alcoholic ones. If you’re offering cocktails, offer mocktails and fresh squeezed orange juice.

Understanding Synchronous vs Asynchronous

To get a file or data from a server or issue a JavaScript command synchronously, we issue the command to get the file/data from the operating system or other JS function and we wait for the answer. In the meantime, our single browser UI thread is occupied. The server or Javascript cannot execute anything else. If our program is a web server and we get another request for a different file from a different user, our program cannot process that second request until the first file is read. This is why you need to be careful when you issue synchronous commands on a node server or in the JavaScript in your user’s browser.

When requesting an asynchronous file read, the command to get the file from the operating system is issues. Being asynchronous, everything continues along on its way, and no one is being held up while waiting for the server response. But, since the program has moved along without waiting, what happens when the response finally happens? When making asynchronous requests, we specify a callback function, which is simply a function that is called when an asynchronous request is responded to.

Asynchronous servers are considered scalable, as they can handle multiple synchronous users without much if any degradation in performance. For this reason, in node, use fs.readFile() which is asynchronous instead of the synchronous fs.readFileSync().