8 Mbits on the left lane
Web development, Google, NAS, PHP, HD DVD, HTML, Canon HV20, Firefox, phone, Drobo
Flexible HTML layouts are designs that adapt to the user screen and browser window by not using "hard" width and height: using CSS, sizes are set in percentage and not in pixels. In a time and age where users have screens ranging from 320x240 pixels (PDA and smart-phones) to 2540x1600, I think this is a great quality for any web site to have. Flexible layouts however are harder to do, because it's hard to get them to look pretty at varying screen sizes (large resolutions tend to make the page look empty, and at small resolutions it might look too crowded).
There's another hurdle that goes with making flexible layouts: getting form fields to be as flexible as other elements isn't as easy as it's supposed to be. Normally, all you have to do is set a CSS rule such as input, textarea { width: 100% } and your field is supposed to stretch to the width of its containing element. Well, as I found out this week, neither Firefox nor Internet Explorer (6 or 7) can get this right.
It's the least buggy of the bunch, but it still has issues with textarea elements set to 100%. The trick is to go for a slightly lower value like 99% or maybe a bit lower depending on your situation. As it turns out, this also helps with Internet Explorer.
Both the 6 and 7 version have issues. The 6 is the worst and I have had great difficulties to get fields to flex properly. In the end I've found a hack that puts different CSS for version 6 and other more modern browsers (including version 7). I've always refused to use any non-standard trick to apply different CSS rules to different browser, but this one is 100% standard and quite clean:
input, textarea { width: 30em }
input[type="text"], textarea[id="IdOfTextarea"] { width: 99% }
With these rules, all elements are first sized to 30em, then browsers who are compatible with attribute selectors will apply the following line to elements with the proper name, type or whatever attribute you use to select them.
However I've still had difficulties going on with Internet Explorer 7 and textarea. Adding a style="width: 100%" to a container such as a div has managed to get the thing right.
I've recently gotten to work a bit on optimizing my site for search-engines, and more specifically how to have the best URL possible for search engines. Making your site user-friendly and accessible is a good way to get high ranking in search engines, and having clean and well layed-out URL will certainly help both your users and your ranking. However after searching through the forums I learned a few tricks:
Dynamic URL: pages such as article.php?id=3 are properly indexed, however search engine prefer static ones like Article-3.html.
URL keywords: keywords in URL do count, even more so if they are inside the domain name itself (but nowadays all good domains with valuable keywords are taken...). That's why most blogging platforms use the article title to build the URL, eventhough it makes it very hard to type manually.
URL depth count: it seems search engines penalize pages that are too deep in a directory structure. That was an issue for me because like many people I was using mod_rewrite to cleanly pass parameters to scripts (such as script.php/param1/param2/param3/ ).
Dashes are the word separator: another problem was that I was separating keywords in URL with underscore. I went this route because it is easier to read in the address bar, however it turns out that to Google, a dash is seen as a keyword separator whereas the underscore is just another character.
Of course I could have just changed the URLs and be done with it, with the old one returning a "404 Not Found" error. However, besides breaking external links, this will hurt ranking in search engine because the new URL will be considered like new pages, and might be considered duplicate content.
The fix to this is a permanent redirect, which is understood properly by search engines as "the page you look for has moved, but is otherwise the same thing". mod_rewrite can do just that, using something like :
RewriteRule ^old_url.html$ new-url.html [R=301,L]
You would obviously use regular expressions to handle multiple redirects within this single line. In my situation, regular expressions were not flexible enough to do my rewrite. I needed to process the old URL in something like PHP to be able to find the new URL and do a proper redirect. I found two roads to get there: the first is to use the RewriteMap instruction in mod_rewrite, which gives you the option of using some external program of your choice to handle URL rewriting. The other was a bit simpler, it involved changing this in the .htaccess file:
RewriteRule ^regexp_for_old_url$ fixit.php [L]
Which would silently have all old URLs handled by fixit.php. This would be a simple PHP script to do the rewriting work:
<?php
$newURL=$_SERVER["REQUEST_URI"];
// Process $newURL here
header('HTTP/1.1 301 Moved Permanently');
header('Location: '.$newURL);
die();
?>
Job's done !
There are probably over a 100 different PHP template engines out there (the most famous one being Smarty). Templates are a good concept: keep the presentation and layout in one file, keep the business logic in another (and data storage in a third: the database). Use a simple and straightforward language to make templates, so that any graphics designer or HTML artist can use it, and leave the messy programming to something and someone else. Yes, templates are good with Java, C#, Python or whatever language you can think of. But not PHP.
Why is that ? Well here's a hint: PHP stands for "Hypertext Preprocessor". That sounds an awful lot like the description of a HTML template engine. And in fact, PHP is a sort of template engine: it was designed as a simple and straightforward language that even a graphic designer could use, and that you put directly inside your HTML to control the output (just as any other template language does). So what all those PHP template engine do is run a template engine on top of another template engine. Duh!
Consider for example this lines of a Smarty template:
{$title}
{include file='header.tpl'}
{if $a}
Hello
{else}
Bye
{/if}
And now the same thing in PHP:
<?php
echo($title);
include('header.php');
if ($a)
echo('Hello');
else
echo('Bye');
?>
I mean, what's the point of reinventing the wheel ?
Template engines requires the learning of a new syntax, slow down stuff (because you need to parse and process the template) and basically, as any extra layer of complexity does, increase the chances of hitting a bug or a security hole while making debugging harder. They only make sense in languages where outputting HTML is hard and painful. Is that the case with PHP ? Obviously not.
Of course, I'm not saying you should not separate presentation and logic. But you can do that without having to drop PHP: write a main PHP page with the presentation and include the logic in external files, or do the opposite and handle the output with templates written in plain PHP and HTML. Or do both and keep everything in neatly organized files.
In my first installement of Fast Web Sites I mentioned the possibility of using a script to serve several Javascript (or CSS) files together to gain speed. Here's a simple and rough PHP script that could do such packaging:
header('Cache-Control: max-age=3600, must-revalidate');
header('Content-type: text/javascript');
ob_start('ob_gzhandler');
if ($_REQUEST['f'])
{ $tab=explode(' ',trim($_REQUEST['f']));
foreach ($tab as $file)
if (preg_match('/^([0-9a-z_\-]+\/)*[0-9a-z_\-]+\.js$/i',$file)) readfile($file);
}
The script is supposed to be installed in the directory where Javascript files are stored. In order to use it you would do something like this to serve up 3 different Javascript files at once:
<script src="/javascripts/script.php?f=file1.js+file2.js+file3.js" type="text/javascript"></script>
A few words on the code :
Adapting the script for CSS should be trivial. As it turns out, Rakaz explains and develop the same idea, and goes even further by using mod_rewrite to present a clean URL that hides the packaging script.
There's a bunch of HTML tags we use all the time, sometimes too much, like div which some people feel they must put around every possible other tag. Then there are some that we rarely use, for lack of opportunity or lack of knowledge. But if you have any commitment to making your web pages easy on users, search engines and peoples with disabilities, then you might want to have a second look at the followings:
<abbr title="Abbreviation">Abbr.</abbr>
The abbreviation tag is used to mark-up... abbreviations. Use the title attribute to give the full word that you abbreviate (browsers will usually render it in a way that let's people find out about it).<acronym title="Personnal Computer">PC</acronym>
Works pretty much like the abbr tag, except this one is for acronyms (you do know the difference, right ?).<label for="username">Your user name</label>
The label tag is used to mark a portion of HTML as the label for a specific form field (text, checkbox, etc.). It's very useful for blind people as their web browser will be able to figure out what each form field is about, even if labels are not located next to their relevant field. For a graphic browser like Firefox, clicking on the label content puts the focus on the relevant field. Use the for attribute to give the id if the form field you want to label.<address>John Doe, 12345 main Street, Somewhere</address>
Well this one is self explanatory. HTML inside it (line breaks and such) is of course allowed.<fieldset><legend>About you</legend>...</fieldset>
The fieldset tag is used to group relevant parts of form fields together. If you have for example a big form with a section for the user, a section for his preference, etc. then you can group fields into fieldsets, and use the legend tag to name the section (saddly the default visual effect looks much better in Internet Explorer than Firefox, but you can style this tag with CSS).<del>Some deleted stuff</del>
The s and strike tags are deprecated because they carry no semantic information and you can render striked text with CSS. But if you want to mark something as deleted (and not just text either), there's the del tag that by default renders text as strikethrough.<... lang="fr">du texte en français</...>
OK this one is not a tag but an attribute that most HTML tags support. The lang attributes lets you define part of your page as written in another language, and since it is also available on the html tag, to also defines the default language of your whole page (important for search engines).<tbody>...</tbody>
Tables have been around for a while, but few people use the thead, tbody and tfooter that marks which row(s) represent the head, body and footer of their table (for example Firefox makes use of them when printing tables over multiple pages).<noscript>Turn on your Javascript !</noscript>
The noscript tag lets you display something if (and only if) the browser doesn't support Javascript (or has it turned off). Rather than letting users with such browsers in the cold because your nifty scripts can't run, you can use this tag to give them an alternate content to see.<button type="submit" name="submit_button" value="1">My pretty button</button>
Everybody has gotten used to making form buttons with the input tag. However these buttons are text only and requires some CSS trickery to make them a bit pretty. Well the button tag is another way of doing form buttons, but it has the advantage of accepting any HTML (including images) within it, so you can be more creative.This post will be the first of a long series focusing on optimizing Web sites and more specifically, those developed with AMP (Apache, MySQL and PHP). Optimizing web sites is important for two reasons:
Let's start with the client side.
The most obvious thing you might want to optimize is file size.
HTML: there's not much to save here, you might want to skip on line feeds and indentation, but that's going to hurt legibility and make maintenance harder. Of course you should hand-write your HTML code and not use a visual editor, as they tend to add a lot of cruft.
CSS: there are a few things you can do here. The first one is to have your classes and styles well organized, because it'll translate into fewer classes and fewer properties. Do not forget that you can use several classes on an element. If several elements share some properties, you should be able to define these properties with a single rule that applies to all of them.
Secondly, you can shave off a few tricks using allowed CSS shortcuts. For example the rule { border-style: solid; border-width: 1px; border-color: #ffffff; } is the same as {border:solid 1px #fff}.
JPEG: you should obviously save your JPEG with a optimizing tool. Most good graphic packages have one. I've found out that progressive JPEG tend to be a bit smaller. Play around with the settings to see which size/quality ratio you can go with. Every picture will require different settings - those with red areas or red tones tend to show more compression artifacts and need more bytes, others have large blurry area that can be heavily compressed. If your graphic program adds EXIF or IPTC headers to your JPEG files, you can also strip those (using for example PlainViewer).
PNG: here too some graphical optimization tool should be used for saving. You'll want to see if a using a palette might save you some space or not, and if so how many colors you can limit yourself to. Once you are done with that there are some extra tools that can optimize further your file such as AdvanceComp which strip useless data and find a more optimal compression method.
GIF: the only reason to use GIF is for small animations (or very tiny pictures of a handful of bytes). Otherwise, use PNG which offers better compression.
Javascript: you can gain a lot of space by using a code compacter such as Dojo ShrinkSafe or Packer (keep your original files for maintenance, because the compacted version will be impossible to read for a human). Many AJAX libraries are also available in compacted form either directly or through third parties.
More than file size, having too many related files (images, stylesheets, etc.) are what can make a page seem "slow" to load up (because each file requires a round-trip between the client and server). Obviously you should try to group your stylesheets and javascripts together into as few files as possible.
One issue you might have with this strategy is that pages will end up loading content that they don't need. If some pages need file A and B, and some other need B and C, and all those weight a lot of bytes and it's not very efficient to group and load A, B and C everywhere since each page only needs a subset. The solution to this problem is to write some simple server side script (PHP or other) to fetch your CSS and Javascript and package it in single file.
So instead of having :
<link rel="stylesheet" href="A.css" type="text/css"/>
<link rel="stylesheet" href="B.css" type="text/css"/>
You would have:
<link rel="stylesheet" href="styles.php?group=AB" type="text/css"/>
For graphics, I highly recommend the use a technique called CSS sprites, which groups several pictures into a big one and use CSS to grab and display them. It's especially efficient for all those little images that you might use in a GUI (buttons, rounded corners, etc.) as you can replace dozens of images with a single one.
The order you link your files into your Web page matters for Javascript. Indeed, the browser will load all Javascript by order of appearance and meanwhile blocks further processing of the page and other elements. A suggested work around is to stuff all your Javascript loading at the end of the page rather than the beginning (technically speaking it will not improve total load times, but the user will get to see something faster).
On the client side a good tool is the FireBug extension for Firefox, which has a "Net" tab that shows you the order in which each element is loaded and how long it takes.