(Domino) Show and Tell - Very large websites and methods - "Conditional Compilation of HTML/CSS/Javascript"

hootsThursday_BLU.jpgI had the pleasure a few weeks ago to encounter an extraordinarily large web application, hosted on Lotus Domino. Without divulging company confidential information (and getting my sorry ass sued off), this application is huge and these techniques are used to solve a number of different development issues. (So full credit to the chaps at this unnamed company - you know who you are. Beers are on me. And any mistakes in this text are obviously my own..). In my many years of code auditing, its now very infrequently that I go "ooooh!" at some technique. This is one of those techniques.

In general, when developing small or medium sized web sites, the existing Domino event infrastructure is probably adequate. There's an HTML Header form event that allows you to stuff HTML header information (such as Meta Tags, Javascript includes, CSS includes) and a Javascript header event that allows you to stuff javascript. This approach works well for small sites, but quickly becomes unwieldy should the amount of information in these fields exceed a few hundred lines. In particular, you may wish to share Javascript information between forms, and therefore use a Javascript script library and "include" that in the HTML header. Typically, a web developer would attempt to reduce the number of "@dblookup" style look-ups that execute on Form opens as this negatively impacts performance. So far, so best practices.

(Actually Javascript Script Libraries must be one of the most under-utilised Domino constructs that I've came across. Not only does it allow you to stuff all your Javascript in one place -because its coming from a fixed URL, there's a degree of caching on the client, thus improving performance).

This starts to become unwieldy when you have applications in excess of several thousand lines of HTML or Javascript. Very complex applications have different sets of priorities - where the number of @dblookups may be slightly less critical than being able to assemble large amounts of content-specific HTML, CSS and Javascript. This may be the case in very large web-based domino applications where there is a large number of developers, or a large number of applications/forms and you require consistency between all applications.

Thousands of lines of Javascript ? Am I mad ? Well. Yes and No. Highly interactive, non-server refresh applications. Welcome to Web v2.0. Some good news and some bad news. Web v2.0 is something us Domino chappies have been doing for the last 15 years in our "fat" domino client. The downside ? I did say Thousands and thousands of lines of Javascript. Am I the only person in the world who hates it with a passion ? Oh - for a DECENT javascript debugger, eh ? (Honestly - has anyone got a good professional IDE for Javascript ? No - I dont mean the MS javascript debugger. Even the firefox one isn't great)

Back to reality. In the HTMLHeader information section of a form, instead of hard-coding HTML information, you may choose to do a @Dblookup instead, to a central HTML/CSS/Javascript repository. The DbLookup would open this repository, and them use form-context information (such as form name, or workflow state) to get all HTML/CSS/Javascript relating to this context.

This "central" repository would be a lotus notes database on a domino server (obviously), containing a lookup view, and a number of documents. Each document might have an "html" text field (for instance), which contains fragments of HTML, CSS or Javascript. This means that each HTML/CSS/code fragment could be tested in isolation and then re-used between applications in this environment.

Assuming our repository was called "repository.nsf", our look-up view was called "lookup" and each document in that (sorted) view was referenced by type, Form and workflow status (separated with exclamation marks). Our "html" text field is exposed in the second column. Your HTML Head form directive might look like:

   html := @DbLookup("":""; "":"repository.nsf"; "lookup"; "html"&"!"&form&"!"&status; 2);

   CSS := @DbLookup("":""; "":"repository.nsf"; "lookup"; "css"&"!"&form&"!"&status; 2);

   Javascript := @DbLookup("":""; "":"repository.nsf"; "lookup"; "javascript"&"!"&form&"!"&status; 2);

   html & @newline &

   "<Style>" & @newline &

   CSS & @newline &

   "</style>" & @newline &

   "<cscript language=\"javascript\" type=\"text/javascript\">" &

   Javascript & @newline &


So far, so good.

(Bear in mind that we can use normal Domino trickery to make this repository view work for us in terms of information sharing. So a common html meta tag might be exposed to ALL forms, etc, etc)

Performance wise - is this really bad ? Well, thinking about it, the Domino server would almost certainly have this view (and the textual summary information) cached in memory. Whilst the first lookup or two might be "slow", I'm fairly sure that this would be sufficiently quick. One major downside in this case is that there is NO caching of CSS and Javascript information on the client. This - especially on very large systems - is a major consideration. Producing 300k+ HTML pages for every HTML form, for instance - is not something you might wish to do lightly. In some cases - say the application is using SSL - you might find that your corporate standard of Internet Explorer 6 doesn't actually cache "https" static information such as script or CSS..

Simple idea - "conditional compilation of HTML/CSS/Javascript" - but powerful. Just remember - there are important performance considerations you have to justify before this technique pays for itself..