Archive for the '(x)HTML(5)' Category

x-webkit-speech input and textareas

Saturday, August 6th, 2011

New hotness, speech input. (The demo, the demo)

You get an input:

<input>

You add an x-webkit-speech attribute

<input x-webkit-speech>

And voila!

Or if you don't have a recent Chrome version, here's what these who have a recent Chrome version see:

Nice.

Textareas

Speech inputs - gotta love them. But in textareas - you can't have them. So you can put an input and a textarea and copy over the content.

html:

<textarea id="txt"></textarea>
<input x-webkit-speech id="mike"/>

With some CSS you can remove the border, add pointy cursor, etc make it look like not an input.

#mike {
    font-size: 25px;
    width: 25px;
    height: 25px;
    cursor:pointer;
    border: none;
    position: absolute;
    margin-left: 5px;
    outline: none;
    background: transparent;
}
#txt {
    height: 150px;
    width: 150px;
}

Finally a little JavaScript to a/ unfocus the input and b/ carry over the content from the input to the textarea

var mike = document.getElementById('mike');
mike.onfocus = mike.blur;
mike.onwebkitspeechchange = function(e) {
    //console.log(e); // SpeechInputEvent
    document.getElementById('txt').value = mike.value;
};

That's all there is. Click over to the demo.

Here's what you should see in Chrome:

You can see that console.log() there - it's definitelly worth exploring. The thing is a SpeechInputEvent type of object is passed to the handler of the onwebkitspeechchange event. This object has some interesting properties, such as the array results[] which is number of guesses what you've said and confidence (0 to 1 it seems) in the guess.

Enjoy and go ahead and add these all over the place! :)

 

Lazy HTML evaluation

Wednesday, June 8th, 2011

#7 This post is part of the Velocity countdown series. Stay tuned for the articles to come.

Some time ago Google talked about using a sort of lazy JavaScript evaluation which especially helps mobile devices. The idea was to comment out a chunk of JavaScript you don't need right away and serve it this way. Later, when you need it, you get the content of the commented code and eval() it. More here and here.

At the last Fronteers conference I had the pleasure of chatting with Sergey Chikuyonok, who is so great and (among other things) is responsible for coming up with zen coding and writing a bunch of deep articles on image optimization for Smashing Magazine. So he told me he experimented with similar lazy HTML evaluation and it proved to be incredibly helpful for mobile devices. Not only the overall experience is faster but the initial rendering happens sooner and we all know how important that is.

Sergey is a busy person and chances of him writing about his experiment in English seemed pretty low at the time, so I decided to do an experiment on my own and see what happens. Meanwhile he did write about it so I forgot all about my findings, but here they are now.

Long document

I took one big HTML document - The adventures of Sherlock Holmes, which is half a megabyte or about 200K gzipped. Page A is the document as-is, plus some JS for measurements.

Page B (lazy) is the same page but with about 95% of its content commented out. The remaining 5% is a whole chapter so there's plenty of time to deal with the rest while the user is reading. After onload and a 0-timeout I take the commented markup (conveniently placed in <div id="lazy-daze">) and strip the comments. Then take the "unwrapped" time after another 0-timeout to let the browser repaint the DOM and regain control.

The overall skeleton of the lazy page is like so:

<!doctype html>

<html>
<body>
  <h1>THE ADVENTURES OF<br/>
  SHERLOCK HOLMES</h1>
  ...
  ... to chat this little matter over with you.</p>

  <div id="lazy-daze">
  <!--
    <p>II.</p>
    <p>
    At three o’clock precisely ...
    ... she has met with considerable success.</p>
  -->
  </div>

<script>


window.onload = function () {

    setTimeout(function(){

        var daze = document.getElementById('lazy-daze'),
            inner = daze.innerHTML;

        daze.innerHTML = inner.substring(4, inner.length - 4);

        setTimeout(function(){
            // take end time... 
        }, 0);

    }, 0);
};

</script>
</body></html>

Experiment

All the files are here:
http://www.phpied.com/files/lazyhtml/

We have the plain normal document - http://www.phpied.com/files/lazyhtml/sherlock-plain.html
And the lazy one - http://www.phpied.com/files/lazyhtml/sherlock-lazy.html

In order to run the experiment you just go to
http://www.phpied.com/files/lazyhtml/start.html
And click "Go nuts". This will load each of the two documents 20 times and take a few time measurements. "Go nuts" again and you'll get 20 more data points.

The time measurements I take are:

  • "plain" - unload to onload of the base version
  • "lazy" - unload to onload of the lazy version NOT including unwrapping it. This should be quicker than the plain version
  • "unwrapped" - unload to onload plus time to unwrap and rerender - this is expected to be bigger than "plain" because the browser has to render twice and is therefore doing more work
  • DOM loaded "plain" - unload to DOMContentLoaded instead of onload
  • DOM loaded "lazy"

Then I take the same 5 measurements but instead of starting at unload of the previous page, it starts at the top of the documents, as soon as a timestamp can be taken with JavaScript. This will exclude DNS, establishing connection, time to first byte...

Results

Here are the results from back when I did the experiment originally last year, using iPhone 2 (with iOS 3.2 or thereabouts)

I ran this experiment over Wifi and again over 3G.

First striking thing - it takes the about the same time to load the plain old page over Wifi and over 3G. For the smaller, "lazy" document, there is a difference, but there's virtually none for the plain base page. The guess here is that the rendering and its cost in terms of memory and CPU is far greater than the actual download time. In other words it takes longer to render than it does to download an HTML. At least in this class of phones. This guess is confirmed when you look at the time from the top of the documents, when the request overhead is removed:

With or without the request time - it's all pretty much the same.

The next striking thing - and how about that lazy document! It renders 3-4 times faster than the whole plain document. Not bad.

And one more surprise - lazy+unwrap time is less than the plain old document. Now that's interesting. It appears faster to split the task into two and do the whole double-rendering, which should've been slower because it's extra work. I guess that poor phone really chokes on the long document.

The same I found is true in Firefox, but almost the difference is negligible.

iPhone 4

I repeated the experiment tonight on iPhone 4 and wifi. And boy, is there a difference. What used to take 13 seconds is now under 3s.

The lazy + unwrap time is more than the plain time, which was to be expected.

Rendering that initial lazy document is still 2-3 times faster that waiting for the whole document.

The numbers:

  • 2765 plain (2014 DOM)
  • 1268 lazy
  • 2995 lazy+unwrap

Ignoring the request overhead:

  • 2200 plain (1421 DOM)
  • 715 lazy
  • 2423 lazy+unwrap

And one last run/observation - on the 3G and iPhone 4 there isn't much benefit of lazy-evaluation and empty cache. The request seems much more expensive. unload to onload 4.9s where document top to onload is 2.5. When the request overhead is out of the picture than lazy eval wins again - 1.7s compared to 2.5s

Parting words

  • Lazy HTML FTW?
  • Who the heck loads an entire book in a page?! Well it may happen. It may not be a whole book, but just a lot of markup. The entire book gzipped was 219K. A hefty document, but have you seen some of those news sites?
  • Possible use case - blog comments. Lots and lots of blog comments. Or posts.
  • If you're going to lazy-load something and get it with an ajax request, why not save yourself the request and ship with another chunk of html
  • This was a simple layout task. Just a bunch of text. I'm guessing there could be much more complicated pages and layouts to render. And rendering is what takes the time it seems.
  • Drawbacks a plenty because of the hidden content - accessibility, SEO.

Thoughts? Anyone want to run the test on Android or any other phone/device/tab/pad/whathaveyou? The guess is that the newer/powerful the device the smaller the difference. But it will be nice to know.

 

a DOCTYPE is all it takes

Friday, July 25th, 2008

At a lunch conversation about quirks vs standards mode, the question was raised: but what if you don't have those kinda important tags such as <html> or <body>? is this going to be quirks mode?

Well, the following test case shows that a DOCTYPE is all it takes in order to have standards mode rendering. Was this a Cinderella song: "We all need a little DOCTYPE, just a little helper, ooh and it will be alright" :)

» Run test example

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

hello

<script type="text/javascript">
alert("Quirks? " + document.compatMode);
</script>
 

When client-only validation is good for business

Sunday, April 13th, 2008
You should never never ever rely on client-side validation only. Client-side validation is for enhancing user experience, server-side is the validation. This is a rule, never to be broken. But here's a funny story how skipping the server-side validation actually helped.

This is a real story, but the actual names have been replaced in XXX, just not to make other people look bad :D

There is this site called xxxxxxxxx.com that charges you $XX membership access. Having just moved from Canada, last year I didn't have a US credit card to pay the fee and tried to use my Canadian visa. Problem: the input field for postal code (zip code) accepts 5 characters only, since the zip codes in US a like 90404, 90066 and so on. A Canadian postal code is like H0H-0H0 or H0H0H0, six characters. So seemed like I couldn't pay online. Or could I?

Checking the source code with Firebug gives me this:

client.png

From here it's trivial to change maxlength attribute of the input. Even with IE it's super easy just to type in the address bar something like:
javascript:document.getElementsByName('XXXXXXX')[0].maxLength = 100;

So I did change it, typed my Canadian CC#, Canadian postal code and submitted the form, crossing fingers that the developers who built the site were too pressed by deadlines to do a proper server-side validation. Lo and behold, it worked!

At the end with the help of an innocent client-side tweak I got what I needed (membership), xxxxxxxx.com got more business, and everybody's happy.

There's a lesson in this: sometimes being too strict in data validation for things that don't matter is just in your way.
And another: don't assume all your potential clients are from US.

 

The Front-end Cerberus

Thursday, October 25th, 2007

Some smart guys picture the distinction of content (HTML), presentation (CSS) and behaviour (JavaScript) as a three-legged stool. This is totally fine, but can't we draw a more heroic picture of today's Front-end developer?

frontend-cerberus.jpg

I found the image here, if anyone knows the original author, let me know so I can give proper credit.

BTW, I never knew what Cerberus meant until 15 minutes ago. The thing is that where I come from, we used this name to refer to some of the teachers that weren't very nice to us at school :)

 

HTML2DOM

Thursday, September 14th, 2006

Here's this HTML-2-DOM service - http://www.html2dom.com What it does is pretty simple - you paste some HTML code and the output is JS script code that uses DOM functions to produce the same result. Could be useful when you're working on an AJAX-style app that generates new content using JavaScript.

I build this simple script, inspired by this great book I was reading - "Build Your Own AJAX Web Applications". In the book, the author sometimes starts with writing up what is the HTML code for the result you want to achieve, and then goes ahead with giving the DOM code. Because, you know, DOM code can be quite verbose and sometimes a bit hard to follow. So I thought, why not write up a simple tool to automate this HTML to DOM transition.

The code is not complicated at all, it just takes the HTML, treats it as an XML document, then loops through all the elements of the XML doc and all the attributes for each element. The script is here, hopefully reusable and you can grab it for your own projects if you wish. You can check the source of html2dom.com's index page for an example how to use the html-2-dom class.

Some limitations of the script (that I know of) are result of the fact that I'm treating the HTML as XML document. So you might get some errors if the HTML you paste is not well-formed, with all closed tags and so on. Also you cannot use &nbsp; and other entities, because XML doesn't know about them. What XML knows is only the pre-defined 5. And last, out of the different node types, my script understands only three - element, attribute and comment. I think it's enough for the practical purposes I was aiming at, even the comment type is a bit of a stretch.

So enjoy and as always, any feedback is welcome!

 

IE script tag problem

Tuesday, October 18th, 2005

Issue:
The page not displayed in IE. "View Source" shows the full source, <title> is displayed OK, but the page is not blank. White screen of death. Nothing.

Cause:

<script type="text/javascript" src="some.js" />

Solution:

<script type="text/javascript" src="some.js"></script>

Comments:
It's probably this whole thing with the current support of XHTML. Most browsers (in their forgiveness for HTML authoring errors) interpret XHTML as HTML with some weirdly placed slashes and other noise. So for example they see <br /> as a slightly broken <br>. More about this here.
In the case above probably IE needs the end </script> tag and because it cannot find it, it treats the whole HTML document as JavaScript, apparently broken. Hence the white page with OK source and OK HTML title.

... And while on the script tag subject, "language" is not a valid XHTML Strict attribute for <script>.