You may already know that, but ASP.NET
2.0 introduces a new Code directory (or Application_Code, the name is not final yet
) that enables you to just deploy the source files of your libraries, and they will get compiled on-the-fly. What you may not know is that you can extend this by creating your own build providers.
When I first learned about the extensibility of the auto-compilation, I immediately thought about how an Object/Relational mapping tool could take advantage of it and generate the DAL transparently on-the-fly from the XML mapping file. It would make it marvelously transparent and easy to use, update and manage. An additional bonus is that any change to the xml file would immediately result in Visual Studio Intellisense picking up the change and displaying the new types. Just perfect.
The possibilities are endless. For example, a business rule engine could use it, or a form generator.
Play with it, invent great new applications, and if you find anything limiting you in doing so, just tell us about it. Now is the right time.
It is vitally important that we optimize all the images we ship as resources in the framework: these images will potentially be downloaded several times on each of the pages our users build using the controls that use them.
Even a few bytes can make a significant difference and alter the perception of the performance of ASP.NET applications. We also have a chance to contribute in making the web as a whole a faster, or a slower place.
It is the same for all web developers: the size of your images contribute to the user experience of your web site and to the perception of its performance. Reducing their sizes can help you make better use of your bandwidth and that of your users.
This walkthrough uses Photoshop, but you should find similar optimization settings on your own favorite image processing software.
To save an optimized version of your image, you'll need to select File/Save for web.
You’ve got a few options there that you can manipulate. Try all settings until you’ve reached what you think is the most compact size for your image that does not degrade its appearance.
I recommend that you zoom so that you can see the pixels. It’s easier to see degradations this way. But always zoom back to 100% before you decide to keep your settings to check the final appearance at the real size. The zoom setting is in the bottom left corner of the window.
You can also use the tabs on top of the window to see the original uncompressed image and the compressed version side-by-side (2-up tab). On the bottom of the compressed image’s view, you can see the final size of your image, as well as an estimation of the time it will take to download on a crappy modem. You can change how crappy the modem is by using the little right-pointing arrow in a circle on the top-right corner of the previews.
If you want to have access to the compression parameters, you’ll have to click on the compressed view so that it has a thick blue border.
Here are the settings you can use:
- Preset: ignore that.
- Image type: use GIF if your image is small and looks fine with less than 256 colors. Large photographic images should use JPEG. For JPEG, the parameters will be different (basically, it's just a question of compression level and is easier to optimize than GIF: just pick the compression that does not degrade your image). PNG is not supported by all browsers.
- Lossy: ignore that.
- Palette type: you can try different settings. I always use Adaptative because it tries to use a color palette that fits the original colors of the image and not some predefined palette. It helps to prevent dithering.
- Colors: this is the most important setting. On small images, the palette itself can take an important proportion of the final image size. Changing it can in some cases reduce the size of an image from 800 bytes to around 50. Try the lowest setting that does not degrade the image too much.
- Dithering pattern: if you use 0 dithering, you don’t need to set that. If you don’t, just try them and select the one that works for you.
- Dither: I always use zero here. Dithering is introducing noise in the image in the same way that colors or gray levels are produced in a newspaper. It looks ok when seen from afar, but is really ugly up close. It looks better to increase the palette size a little than to introduce dithering. I also suspect that dithered images are harder to compress and result into larger files. Not sure about it, though.
- Transparency: in many web images, we need transparency, so check this if it is the case. To select which color will be considered transparent, select the eyedropper tool on the left side of the window and select the right color directly in the image. It will select the same color in the palette. Click on the checkerboard-like small icon below the palette (Maps selected color to transparent) and the color will disappear from the preview to show the background checkerboard. You can repeat for several colors if you want.
- Matte: Choose None. This is the color Photoshop will consider is the background color the transparency should be calculated against: for the image transparency to look better, it anti-aliases border pixels so that the edge looks smoother. We can’t use that in our own images because we can’t know the background color in advance. So we have to choose none here even though it degrades the quality a little on the borders. If you're a web developer and you use a fixed style sheet, you may know in advance the background color the image will be displayed over. Use this color here.
- Transparency dither: choose “no transparency dither”
- Interlaced: don’t check that. It was only useful for large images at the time when modems were 9800bps.
- Web snap: this is to try to coerce the palette into being closer to the so-called web palette. This web palette is supposed to be a palette that all devices should be able to display correctly. I usually don’t use that feature. Your call here.
Finally, you can click on the “preview in default browser” icon to view the final results.
Press Save to save the final image.
Of course, you may find that your own settings will work better in your particular case. Experiment and keep what works best for you, as always.
Why do we still have this stupid NumLock key on modern keyboards? Who still uses it with all of the unlocked keys duplicated about half a centimeter to the left? Hello? Keyboard designers? Please get rid of it now. Everybody hates seeing the cursor go crazy when all they wanted to do was to type a number.
Now, the people who design keyboards at Microsoft
have recently come up with a new way to torture us: the F Lock key. They've decided that we needed new fixed function keys for common tasks such as save or print. This is all very well and I'm sure that having access to these functions with just one keystroke and without having to know complex ctrl key combinations is very useful to disabled persons. But why did they have to put these on our function keys
?? Just add new keys, but don't replace useful keys that we're used to. Of course, the new key meanings are on by default and you need to hit F Lock to restore the old F keys. And naturally, every time you reboot, you have to hit it again.
Die, F Lock, die!
Actually, why not make these lock keys real switches if you really want to keep them? After all, they're a matter of personal preference that you just want to set once and forget about. So they could be real switches that you can't accidentally hit. That would be so much better, and it would get rid of the stupid problem that wireless keyboards have which is that they can't display the status of these keys for power consumption reasons.
Well, in fact, they could also be software settings in the keyboard drivers for all I know.
Finally, what's with the PrtScn key? Whenever I want to do a screen copy, I have to figure out some strange combination of F Lock, Ctrl, Alt and Shift to get the right result. And what does SysRq mean? Does any application still react to ScrLk?
If you've used the beta version of ASP.NET
2.0 a little, the Menu
controls in particular, you may have noticed that the datasources they consume are different from those that GridView
use. But of course, Menu
have to use hierarchical data sources, whereas other controls use tabular data sources.
Tabular data sources that you get out of the box are mainly SqlDataSource
. Of course, you can also build your own data source (more on this in later posts). The nice thing is that with ObjectDataSource
, you can potentially get data from any data store.
Now, for hierarchical data sources, you've got XmlDataSource
and you've got SiteMapDataSource
, and... and that's it. So if you want to populate a Menu or TreeView
from a database, you'll pretty much have to do it from code.
... This control I've developed on my free time (which is mainly composed of an aggregation of my serious work's compilation time) composes several tabular data sources into one hierarchical data source using relations.
<%@ Page Language="C#" debug="true" %>
<%@ Register Namespace=MyControls.DataSources.CompositeHierarchicalDataSource TagPrefix=my %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<form id="form1" runat="server">
<my:CompositeHierarchicalDataSource runat=server ID=Composite1 RootViewName="Categories:DefaultView">
<asp:ObjectDataSource ID="Categories" Runat="server" TypeName="Categories"
<asp:AccessDataSource ID="SubCategories" Runat="server" DataFile="~/data/things.mdb"
SelectCommand="SELECT [Id], [CategoryId], [Name] FROM [SubCategories]"/>
<asp:AccessDataSource ID="Things" Runat="server" DataFile="~/data/things.mdb"
SelectCommand="SELECT [Id], [SubCategoryId], [Name], [Description], [Url] FROM [Things]"/>
<my:Relation ParentDataSourceId="Categories" ParentView="DefaultView" ParentColumns="value"
ChildDataSourceId="SubCategories" ChildView="DefaultView" ChildColumns="CategoryId"/>
<my:Relation ParentDataSourceId="SubCategories" ParentView="DefaultView" ParentColumns="Id"
ChildDataSourceId="Things" ChildView="DefaultView" ChildColumns="SubCategoryId"/>
<asp:Menu Runat=Server ID=myMenu DataSourceID=Composite1>
<asp:MenuItemBinding DataMember="Categories:DefaultView" TextField="text" ValueField="value" />
<asp:MenuItemBinding DataMember="SubCategories:DefaultView" TextField="Name" ValueField="Id" />
<asp:MenuItemBinding DataMember="Things:DefaultView" TextField="Name" ValueField="Id"
ToolTipField="Description" NavigateUrlField="Url" />
The nice thing is that you can in principle use any tabular data source to build your hierarchical data source. In principle only: this is still a proof of concept and is currently limited to SqlDataSources
whose views return DataViews
, and datasources whose views implement ITabularDataSourceView. Another problem it currently has is that it loads all of the data at one time. It would be nice to have lazy loading for populate on demand TreeView scenarios.
It's shared source, so you're free to use and modify the code as you wish. Enjoy!
In future posts, I'll explain how it works in details, which should make a nice tutorial on how to develop your own hierarchical data source (hint of other missing data sources: LdapDataSource, FileSystemDataSource).
GotDotNet CodePlex workspace for this data source can be found here:
His article is amazingly well documented and thought through. You can see that this guy has been thinking about building a new numbering system for years. Very impressive. And very geeky too, in a hilarious kind of way.
Unfortunately, his proposition for easier arithmetics has even less of a chance to be widely adopted as, say, the US has to adopt the hugely superior metric system
or Swatch has to impose its "internet time".
So it is a total waste of energy, totally useless, impressively time-consuming and funny at the same time.
And thus highly recommended reading.
A few things worth noting and objections, though:
- I would actually have loved a numeric system where 4233 sounds like "butthole sniff sniff". How boring would the solar system be if we didn't have Uranus?
- A complete tutorial with exercises and a diploma at the end would be great (there are exercises at the end of the paper, but that's not enough: I want to learn)
- As has been noted in the comments, the balanced ternary system
is surprisingly good too. Any chance of mixing the two for a balanced ternary bioctal system? And for a better name than that?
- I'll be saying bioctal too from now on instead of hexadecimal
- You're completely mad to spend so much time on trying to improve everyone's life whereas you should be working on your SWF/C# project
- If we forget about one of our fingers, how easier is it to count on them? Anything you can't do with the decimal system?
- Bioctal sounds like a french anti-acne medication, which is ok as geeks keep their acne quite late.