Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Blogs

photo

Lotus Nut

74 Entries |  Chris Whisonant
Updated 
Ratings 6     Comments 103
photo

TexasSwede

70 Entries |  Karl-Henry Martinsso...
Updated 
No Ratings 0     Comments 61
photo

.Domino Frame...

88 Entries |  Peter Presnell
Updated 
Ratings 2     Comments 80
photo

Big A** Mutan...

42 Entries |  Michael Smelser
Updated 
Ratings 1     Comments 41
photo

McGarelGrammi...

13 Entries |  Mike McGarel
Updated 
Ratings 1     Comments 13

Dogear Bookmarks

Yellow is the New Blog

Blog Authors:  Tim Tripcony  

Previous |  Main  | Next

I still have one concern about Dojo

Tim Tripcony  |     |  Tags:  javascript performance  |  Comments (0)
In anticipation of the release of Domino 8.5, I've been familiarizing myself with Dojo, which thus far has mostly consisted of identifying syntactical differences between it and other frameworks I'm already familiar with. My conclusion is that it's not all that different; one of the two most noticeable differences is the inclusion of additional parameters in the actual markup to indicate to Dojo how certain tags should be handled. In this example, for instance, the author adds to a div a parameter of "dojoType" with a value of "dijit.form.DropDownButton": this tells Dojo that, upon load, it should render something that looks and behaves like a drop-down button where that div is placed, using the innerHTML of the first span it contains as the label for the button. That's fine. I like that: you can determine from the markup how the page should "look" to the user. Granted, I'd rather see them take a semantic approach, but meh.

The other difference, however, is simultaneously cool and troubling. Every "official" example or demo I've seen includes just the base dojo.js file in the markup, then in a custom script loads in everything else the page will need via the dojo.require() syntax. In the previously linked example, for instance, there are function calls similar to the following:

dojo.require("dijit.Dialog";);

Why? Because the base Dojo file only includes core functions - such as XHR, array extensions, and the like... as well as a capacity for dynamically loading other script files. Rather than load the entire framework and only use a small fraction of its capability on any given page, dojo.require() allows you to tell the browser precisely what you need and, therefore, only load that. This should enhance performance by minimizing the amount of data the browser needs to download in order to provide the functionality your page requires...

...in theory. In practice, not necessarily. Some have compared this dynamic loading to Java's import statement, and there are certain similarities. When compiling a Java application, import tells the compiler which classes to load, and excludes everything else. Dojo also uses namespacing to provide clarity regarding what is being included. But the difference is that Java is compiled, and JavaScript is interpreted: when you click Save in Eclipse, therefore, it "builds" everything: the resulting class file is aware of everything it needs to be in order for your application to run. A web page, on the other hand, must download each file individually. As I'm sure I've mentioned before (ah, yes, here it is), a powerful way to improve the performance of any web page is to minimize the number of HTTP requests; although Yahoo's list of recommendations keeps growing, that's still their number one guideline. If, for example, you have 10 script files that are 20 KB each, and one 200 KB file that combines all of them, the browser will load the 200 KB file faster than it would load the 10 separate files, even though the same amount of data is exchanged. That's the primary reason I wrote JSFactory and still use it nearly every day (especially lately). Dojo, on the other hand, takes the opposite approach: I added the Dialog example to an application I'm working on (and no other Dojo functionality), and the result was 35 separate HTTP requests, ranging from 3 KB to a mere 84 bytes. I kid you not: one file it loaded was common.js:

({"buttonOk":"OK","buttonCancel":"Cancel","buttonSave":"Save","itemClose":"Close"})

That's the entire script file. That's ridiculous. I'm logged into Domino, so the LtpaToken cookie sent back to the server via a request header allowing it to decide whether or not I have access to that file is larger than the content sent back once it determined that I did have access to it. Dojo has a reputation for being slow, but it's mostly undeserved: I've found that, once the page has loaded, dijit responsiveness is roughly equivalent to widgets in other frameworks. But this dynamic loading that (I assume) is intended to streamline initial page load, in fact, has the opposite effect, and by the time the user is allowed to interact with the page, the impression of "slow" has already been established.

So what's a developer to do? Well, it's easy, actually... again, in theory. Dojo includes a custom build packaging system. So all you have to do is have a copy of the Dojo library on your local computer, write a build profile that designates which modules you would otherwise be importing via dojo.require() statements (heck, you can even include your own custom script files), and then run a shell script (or a batch file, for the majority of you who would be running this from Windows... though the tutorial assumes Linux and mentions the Windows option as an afterthought), and voila: you have a single (combined, compressed, and otherwise optimized) script file that you can then reference in your web page... assuming you've placed it somewhere on the server (either by adding/updating a file resource in a Domino database or moving it directly into the server's folder structure). Sounds a lot like JSFactory, doesn't it (other than automating the step where it updates your Domino file resource)?

But there are a couple minor caveats. First, you must have a copy of the Dojo source (which you can download here), not the built version that's automatically included on the server with Domino 8.5; second, any time the mixture of modules you need (or the content of any custom script) changes, you have to run the build again, and update the server's copy of the file. In other words, this can become very tedious.

Here's what I'd recommend:
  • Use Aptana (or your favorite JavaScript IDE; mine is Aptana for various reasons, one of which is that it supports auto-suggest for Dojo and several other frameworks) to write all custom JavaScript code that doesn't need to be generated dynamically. This keeps your source in a folder the Dojo build script can reference.
  • Create a build profile that includes a reference to all of the Dojo modules that you're using - plus your custom code - which you'll update whenever that module list changes. For bonus points, write an Aptana script that monitors all files in your project for save events and updates the dependency list automatically based on which dojo.require() statements it finds.
  • If you're running Windows, place a .bat file for each project on your desktop that cd's to the Dojo build scripts folder and runs the build batch using your profile for the project. If you're using the Desktop toolbar, you can then update the build from anywhere with two clicks: one to view your desktop as a menu, and one to launch the build process.
  • Create a project profile in JSFactory that includes just the build output file as the source. There's no need to specify a minified output, since Dojo will already have minified the source, but if you've configured your server to support GZIP, you can enable that option. Then with a single click in your Notes 8 sidebar, you can update the desired file resource element with the contents of your latest build.
At my earliest convenience (read: February) I'm going to update JSFactory to automate the middle steps, so your process would be: write the code in an IDE, click "Build Selected" in JSFactory... done. And just a reminder: if you've already bought JSFactory, you own it; assuming you kept the download link, it'll automatically point to the new version once that's released.

SnTT: PIM Slap - tab-based frame navigation

Tim Tripcony  |     |  Tags:  sntt  |  Comments (0)
If you haven't already seen Chris Blatnick's recent post about universal toolbars, now would be a good time to take a gander. Similarly, if you aren't familiar with Nathan's embedded frameset technique, you may want to check that out as well.

I've been working on an application that, like many Notes apps, contains about 20 views. Okay, point taken: unlike most Notes apps, it only  contains about 20 views. But rather than using the traditional hierarchical outline, I decided to try breaking the interface up into visual sections: the outline on the left only contained 5 links, each to an "area" of the application. Each link would load a form that contains a tabbed-table, with each tab containing an embedded view. I demo'ed this interface to the client, and they liked it - it gives them a bit more visual context than the usual "cram a link to every view into the same outline" approach. Particularly because I can toss into the upper right corner of each "area" form a 32x32 version of the 16x16 icon for the outline entry that loads that area. Ties the whole interface together rather nicely, I feel.

This was all well and good until a last-minute requirement implied a need for the last tab of the last area to contain a frameset rather than just a view. No problem, I thought, I'll just embed it using Nathan's approach... I know that works. But once I had, I encountered a limitation I hadn't seen before: since this application also functions as a mail-in database, the reason I wanted a frameset was to allow the users to view the application's Inbox, but also create custom folders for organizing messages the application receives. Despite setting the correct target frame in every location I could think of (frame properties for the folder outline frame, outline properties for the embedded folder outline, even the outline entries themselves), no matter what, clicking on a folder name would launch a new tab instead of replacing the current folder with the new folder in the correct frame.

I ended up using an entirely different approach. This area of the application is now a frameset instead of a form. The top frame contains the form with the tabbed table, but the tabs no longer contain the corresponding embedded views and framesets... just one field each, named predictably: "launchFrameset_X" ( where "X" is the suffix of the frameset associated with the tab; i.e. "frameset-Mail" is associated with the tab containing the field "launchFrameset_Mail" ). The bottom frame contains the "default" view - the one associated with the first tab. Finally (as far as interface is concerned), the frameset is borderless, and the top frame's height is set to a fixed pixel count to obscure everything below the top border of the tabbed table; the result is that it looks identical to how it did before, except that now the default view not only fills the space horizontally, but can fill the available vertical space as well. So far, so good? To get a feel for what this looks like, here's a screenshot of a separate example database I created (which I call "PIM Slap"... I know, always pushing the boundaries of good taste) that uses this technique (click to embiggen):

image

So we end up with an interface that crams all of our PIM (plus the Notes Welcome page and an internal frameset stolen from Blatnick) into a single tab-driven context. This whole mess can then be nested into a larger frameset - in the case of the application I was previously describing, a frameset like this one is launched via an outline entry associated with its contents.

Finally, to explain how switching tabs actually changes the content of another frame. It's actually fairly straightforward, but I'd never seen this approach used before, so it was a pleasant surprise when the idea dawned on me: when clicking a tab in a form, if that tab contains at least one editable field, the first one Notes "finds" (i.e. not hidden or disabled) gets auto-focused... onFocus is a field event... we can bind to field events. Each tab's field's onFocus event calls a LotusScript function defined in the globals of the form:

Function switchFrame ()
    Dim targetFrameset As String
    
    If (formLoaded) Then
        Let targetFrameset = "frameset-" & Strright(workspace.CurrentDocument.CurrentField, "launchFrame_")
        Call workspace.SetTargetFrame("frame-Target")
        Call workspace.OpenFrameSet(targetFrameset)
    End If
End Function



NOTE: formLoaded is just a Boolean we toggle to True in the postOpen of the form; it seems that, as the form is loading, the first tab is already selected, so its field gets the focus, which triggers the event, but the target frame hasn't been rendered yet, so Notes doesn't know it exists. As a result, we can't allow this event to target the other frame until we know the form has already fully loaded... which is why we load the default view in the bottom frame; we can thus skip loading it via the tab field for now.

In summary, when any tab is clicked, the form auto-focuses the field that tab contains, its onFocus event is fired, which determines which field has focus, what its name is, and therefore what content to load into the bottom frame. As long as all frame names are unique, this allows for fairly deep nesting without any unpleasant side effects. Nothing too revolutionary, but again, I'd never seen this approach used before, so I wanted to share in case anyone else finds this useful.

The example database is available for download.

BAKAAAWK! Announcing Squawk: Microblogging for Dom...

Tim Tripcony  |     |  Tags:  microblogging domino  |  Comments (0)
imageA brand new addition to the BleedYellow portfolio is a "labs" version of a microblogging application for Domino called "Squawk". Although it has several integration points with Lotus Connections (for example, you do not need to register separately for this application - you can use your existing BleedYellow credentials - and your profile picture in Squawk is whatever picture, if any, you've uploaded to your BleedYellow profile), the application itself runs entirely on Domino.

Originally envisioned purely as a proof of concept demonstrating that Domino applications can scale massively if architected well, we've decided to host it on an ongoing basis as a BleedYellow service. And, when the time comes, if you'd like to purchase a copy to run in your own intra/extranet (with or without Connections integration)... I suspect we can arrange that.

Squawk is still in the alpha stages, but we wanted to share it with you in its infancy to make you a part of its development. Here's a brief summary of what currently works and what will at a later date:
  • Post a Squawk: like most micro-blogging applications, each post is limited to 140 characters.
  • Community Squawks: this is a global transcript of the last 20 Squawks from anyone in the BleedYellow community.
  • My Flock: search for people in the community; each search result will include the individual's name and profile picture (the Connections default image if they haven't uploaded one yet), and a subscribe/unsubscribe link based on whether or not they're already in your Flock. An icon for each member of your Flock will appear in a block on the right; hover over their icon to see their name, click their icon to view their latest Squawks.
  • Various links (Profile, Settings, Home, etc.) are either just placeholders or, for the time being, unnecessary: for example, the Home link is a bit superfluous, because at the moment, Squawk is a single-page Ajax application.
  • My Replies: we haven't wired these in yet, but at the moment our thinking is that @shortname will denote a Squawk as a reply to the individual with the matching shortname. We'll also be adding a reply icon that will automatically insert the shortname for you. But we're also going to be adding nicknames, so if you want to type @trip, for example, to reply to me, you can tell Squawk to treat that as a nickname for me. If you've defined a nickname for a member of your Flock, clicking the reply icon will insert the nickname you use for them instead of the default.
  • In a related feature, at some point we'll also be allowing you to create groups from your Flock and direct a Squawk just to a specific group or individual: for example, "hello world #test !dxl" would tag the Squawk as "test" and it would only display to members of my "dxl" group. We're also going to allow you to load a default set of groups based on which BleedYellow communities you're a member of and who else is a member of each.
  • Speaking of tagging, tags aren't clickable yet but of course will be later... in the meantime (and going forward), if you tag a Squawk with #bug or #feature, we'll use that feedback to improve this application.
So head on over to squawk.bleedyellow.com and check it out.

P.S. Interesting bit of trivia: Squawk instantiates a single view handle when the Community Squawks transcript is requested; searching for people to add to your Flock naturally performs a full-text search... every other function in Squawk ignores indexes entirely.

Previous |  Main  | Next
Skip to main content link. Accesskey S
IBM Lotus Connections Help Tools About

Tags

A tag is a keyword that is used to categorize an entry. To view the entries with a particular tag, click a tag name or enter a tag in the box.
The tag cloud indicates the frequency of tag use. Popular tags appear darkest. The slider control adjusts how many tags are displayed in the tag cloud.