What is Web 3.0?

I found this video today where Eric Schmidt (of Google) answers the question “what is web 3.0?”. The guy (with The Christian Look) who asks the question boldly asserts that we know what web 2.0 is… do we? Anyway,

“Web 2.0 is a term that corresponds to Ajax.”
My standard answer to “what is web 2.0?” would be something along the lines of “it’s about control of users and data“, i.e. you build a big web site where users can generate the content, market it, and pray you’ll be among the 1% that are somewhat successful. Then you capitalize on providing pieces of that data. Google if anyone should know that. Ajax (or whatever you choose to call it) is a technology that is certainly a part of the modern web, but really, aren’t pastel colors and rounded corners more important for a web 2.0 site? even if you build it with old-fashioned server-side scripts only. Ajax as a technology is an enabler, not a necessity.

“[Web 3.0] is a different way of building applications.”
Yes, maybe that too. The web by the time 3.0 comes around is bound to have some new technology – or rather some new uses of the technologies we have. And this will allow us to make applications in a different way. So the statement is trivially true, but it does not provide a definition or even a speculation of what web 3.0 will be like. Let’s move on…

“Web 3.0 will be applications that are pieced together.”
This is more interesting. Like mashups? I’m sure all of us computer software users would like to have that. But I’ll believe it when I see it: applications from different vendors cooperating. So far unix system tools are the only ones to come close to this ideal. Unfortunately, I don’t think this is realistic for web apps.

“The applications are relatively small”
Now this is one of my favorite pet peeves. I nagged a bit about this on my CSS Nite presentation as well: Right now, many people, and especially Apple, are thinking of web apps/widgets/gadgets as small, more-or-less useless applications for trivial tasks such as analog clocks or calculators, or something that in the very least is separated from the tasks of “real” applications. I don’t agree with this at all

Consider Mac OS with its Dashboard (even though it is a great reification of the ideal of web tech-based apps): you have a “normal” mode; your normal apps, running along in their windows as usual, and a “widgets” mode; your normal apps—no wait, these aren’t normal apps – these are widgets, special kind of apps made in a special, even naive, kind of way, to be run in a sandbox isolated from your normal desktop working environment. Even Opera has copied this thinking.

This is definitely how it is right now, so I can understand Apple’s decision. But I don’t think it’s how it will be, in the future, boys and girls. Web technology-based application will be just as common as other applications, I think. And in a few years they will be just as big as well. Many have tried to achieve this before – Java and Dotnet come to mind – but web technology has already won. I thought a lot about this, and I’ll write about it some time.

“The data is in the cloud”
I want some of what you’re smoking too dude, but there is no cloud. Data belongs to somebody, access is restricted, bandwidth is limited. The Internet is not a cloud (it’s a series of tubes).

There are a few more goodies in the video. Anyway, what will the web 3.0 be like? I mean, if you can figure that out now, you’ll be a billionaire. I think I have pretty decent idea, and I’ll continue writing about web 3.0 here in this blog. I think and hope that Google won’t be playing a big part in it. (They might be absorbed into something bigger, though).


Reducing Bandwidth Usage when Deploying Web Applications


by serving your JavaScript source code files as one big gzipped file. Nowadays when we’re getting more and more nice applications (and widgets, gadgets, mashups, and whatnots) running on the web, there’s a lot of talk about user experience and stuff, which involves the whole experience of using a web site. Good content, design, and fancy programming, of course make up the core of a good user experience. But we all wants sites to be quick and responsive to load too, right?

This trick is so simple and incredibly easy to pull off that you have no reason not to do it. There are essentially three things involved:

  1. Make apache serve .gz.js files with gzip transfer encoding
  2. Bundle up all your JavaScript files into one (or a few) big file(s)
  3. Gzip your One Big File(s)

Let’s go through these step by step…

1. Make apache serve .gz.js files with gzip transfer encoding
Gzip transfer encoding is great! The only bad thing about it is that on dynamic content, the web server will have to use up some processing power to compress the files on the fly, but in this case, we’re serving static JavaScript source files, so that’s not even an argument! (As for the client, if it’s got enough CPU to run your web app, it’s not gonna have any trouble doing a little unzipping…)

The easiest way to do this is to edit the .htaccess config file in the directory where you put your JavaScript files, or any directory above that one to make it more global. The only thing you have to do is add the following line:
AddEncoding x-gzip gz

This adds the gzip transfer encoding to apache for files with a “gz” file extension.

Notice the title says “.gz.js” though: by adding “.js” at the end, the files will be served correctly with the text/javascript mime type. Otherwise the browser might go berserk. That’s also why I wouldn’t recommend using “.js.gz”; it’ll get served with gzip transfer encoding alright, but not with the JavaScript mimetype.

This solution works even with clients that don’t support the gzip transfer encoding, because web browsers send an “accept-encoding” header that tells the server which encodings the client supports, so apache won’t use gzip transfer encoding if it’s not supported by the client.

2. Bundle up your JavaScript source file into one (or a few) big file(s)
This means simply appending all your source files to one file. Or a few files. I usually bundle up the libraries/utility code etc, i.e. code that you don’t change very often, into one file and the rest of the app into one file that gets updated more often. You can do this by copy-pasting in your text editor if you like, or make a script that does it. I usually have the whole deployment process automated on the server, which I’ll write about some other time perhaps.

Another good way to do it is using Dojo ShrinkSafe. ShrinkSafe will not only append all your source files into one big file, but also reduce the size even further by optimizing the JavaScript code. However, I have had problems with scripts not running correctly (in all browsers) after running them through ShrinkSafe, despite their claims of it being “safe”. I would especially recommend not using the “strip newline chars?” option. Anyway, the file size reduction the results from using ShrinkSafe is small compared to just gzipping the files (I’ll show you some numbers later) so if you’re afraid of regressions, don’t use it.

3. Gzip your One Big File(s)
Now that you’ve got one or two or so JavaScript files, you need to gzip them into a gzip file. You can use the command-line gzip tool on the server to do this, like:
gzip -n9c scriptfile.js > scriptfile.gz.js

The -n option means to not store the the original file name in the gzip file. No big deal if you do, but there’s no reason to do it either. -9 means maximum compression. I like doing things to the extreme! And -c means to write to standard output instead of modifying the source file, so we need to pipe it “>” to a .gz.js file at the end. Or you can use a UI tool such as 7-Zip that supports gzip compression. That’s just damn easy.

Then upload the .gz.js script file to your server, and change all your old <script> tags for every file you had to one pointing to it. I.e. like:
<script type=”text/javascript” src=”scriptfile.gz.js”></script>
That’s all there is to it!

Show Me The Numbers!
Let’s use my Minesweeper game for comparison. The code is served in two files: libs.gz.js containing Prototype and Scriptaculous core and Effects libraries, and minesweeper.gz.js containing the actual game. The breakdown of the files in these libraries before combining them is as follows (at the time of writing):

Original
libs.js: 95 kB + 3 kB + 38 kB = 135 kB
minesweeper.js: 3 + 9 + 9 + 4 + 2 = 25 kB

Shrunk
libs.js: 92 kB (32% smaller)
minesweeper.js: 13 kB (48% smaller)

Gzipped
libs.js: 30 kB (78% smaller)
minesweeper.js: 7 kB (72% smaller)

Shrunk + gzipped
libs.js: 27 kB (80% smaller)
minesweeper.js: 4 kB (84% smaller)

Now, add to that the fact that every HTTP request for a file incurs a 1 kB overhead in HTTP headers, and you get an original total amount transferred of 135 + 25 + 8 = 168 kB compared to 27 + 4 + 2 = 33 kB, i.e. a total saving of 135 kB, i.e. 80% less bandwidth used, not to mention that making two http requests is much faster than making eight http requests!

The next step would be to bundle up html, css, scripts, and everything you possibly can into one request… (In fact, I have scripts doing that automatically at runtime on some sites…) But you have to draw the line somewhere. There’s a definite trade off in maintainability, cachability, and compatibility of the site. So I’ll stop here.


Caching in Php

Php by default tries as hard as it can to make the web browser not cache pages. While I can understand the rationale behind this a bit, sometimes you want caching. Caching is actually a good thing! you know. It means faster load times and lower bandwidth and processing requirements.

So I was surprised by how hard it is to turn off this aggressive non-caching policy. I googled for a few minutes and browsed the php documentation without finding an easy way of doing it. Ok, so you can use the following code snippet to enable caching in php (the argument to the function is number of seconds the page is valid):

function send_cache_headers($expire) {
  header("Cache-Control: max-age=$expire");
  header("Pragma: cache");
  header("Expires: " . gmdate('D, d M Y H:i:s \G\M\T', time() + $expire));
}