By Peter Bell

Is it Worth Being Able to CF Flush?

Ben Nadel posted an interesting piece the other day about his requirements for a page rendering system. One of the things he was looking for was an approach that allowed you to defer as much processing as possible to allow for at least partial page rendering as quickly as possible to give the perception of shorter load times on the basis that users consistently report lower perceived load times for pages that start to render quickly even if the total page load is the same or even slightly longer.

There are two issues that need to be addressed when looking to implement such a solution. CF locations and dependent content areas . . .

CF Locations
There is no point starting to render a page that you won’t end up displaying. If someone just filled out an admin form you have no idea whether you’re going to cflocation to a list with a “success” message or redisplay the form with an error until you’ve processed the form.

Dependent Content Areas
Content areas are not always independent. I first came across this problem when I developed a system back in the 90’s where users logged in and I couldn’t figure out why it still said “Hello Guest” in the top bar even though the user had just been successfully authenticated. Refreshing the page solved the problem. After a while I finally figured out that because I was rendering the page sequentially, at the time the top bar was rendered, the user hadn’t been authenticated yet, so it was displaying the wrong content (it should have been “Welcome #FirstName# #LastName#”) until the page was refreshed. You can come across similar problems when you have a shopping cart “number of items” in the topbar or sidebar that (depending on your site layout) could be rendered before the main content area.

A Pragmatic Approach
I’m with Ben in that all of the applications I develop (I don’t do portals) have a primary dynamic content area and then 0..n secondary dynamic areas. When you play with this problem for a while you realize that all you need to do is to run the controller for the primary content area before you start rendering the page. You can then render the page top down and your render methods for the other dynamic content areas just call their own independent controllers (which still have access to a request scoped object, session data and the like) to call the model to get the data to populate those content areas.

Conclusion
I don’t know that I’d go to too much trouble to “solve the cf flush problem” as it smacks a little to me of premature optimization. However, it just so happens that the requirements to solve this map pretty well with the way the LightBase rendering engine and controller were going anyway, so I’m going to drop in support for flushing partial page content within the framework. In my experience it is usually the primary content area that takes most of the processing time, so I’m not sure I’ll gain much, but there doesn’t seem to be much of a downside and it is interestingly a return to the old component based (as opposed to page based) MVC apps I used to write in VB and the new ones that people are starting to write in Flex.

Any thoughts?!

Comments
In some past apps I used CFFLUSH as it was a long running query and a large report. I soon learned that using that method is really just a fallacy (in my opinion). If your query or report takes that long to run that you require CFFLUSH to keep the user informed, then you should build a caching mechanism or a reports queuing system.

I also don't see the relevance of whether it is portal or single dynamic area, your code to render the display should never take that long that CFFLUSH is necessary. (We've all waited on a long running Portlet causing a hold up in the render of a Portal, very annoying).

Please remember that this is drawn from the kind of Apps that I do, both Portal apps pulled in via a web proxy and standalone apps. I'm sure CFFLUSH has many uses but I just don't need it 99.9% of the time if truth be told.

Cheers
# Posted By dc | 12/8/06 7:34 AM
As far as premature optimization, you may very well be onto something :) I don't what it is... there is just something so comforting about CFFlush... it some sort of siren's call for me or something.

But, now that I take a step back and look at WHERE I actually use CFFlush, there might be a fairly good compromise. CFFlush use cases, for me, break up into two areas:

1. Flushing sections of a page

2. Flushing intermediary parts of a complicated algorithm.

Let me touch on point 2 since it is the most dynamic. The idea here is that if I had some massive table to display, or a page that had a 1000 div's on it (perhaps this an interface problem???), it would be nice to call CFFlush after every Div, or after every X number of divs or table rows (not sure how count( cfflush ) affects performance). Take my blog for example, on search/listing type pages, since my blog entries tend to be a bit wordy (I haven't implemented the "MORE" link stuff yet), I CFFlush after every blog entry. If I have 10 on a page, that's 10 CFFlush tag (plus others that I have). When I load this page, I perceive it to load faster. Does it? Who knows.

But anyway, I stray from my discussion; The point is, point 2 is going to be hard to incorporate in any system where you build a page template using variables. HOWEVER, point 2 really only comes into play maybe 5% of the time, if that! So, certainly, that is not the best hand in a trade-off.

That brings me back to point 1, the flushing of general sections of a page. This idea happens to jive quite nicely with ANY framework. Even with a framework that does all processing up front and all rendering at the end, you can still flush parts of the page:

<!-- Header code. -->
<cfflush />
#Page.Render( "navigation" )#
<!--- Left column. --->
<cfflush />
#Page.Render( "secondarynavigation" )#
<cfflush />
#Page.Render( "main" )#
<cfflush />
<!--- Right column (ex. related items). -->
<cfflush />
<!-- Footer code. -->

I am not saying that all of those CFFlushs are required/recommended. My point here was to point out that even in a tail-end rendering system, CFFlush can still be used successfully to flush pages for a perceived optimization.

So, when it comes down to it, I might be starting to lean more towards the tail end template rendering. Now that I understand that CFFlush *can* still be used (and I can sleep soundly at night) I can certainly be more comfortable with it. After all, I don't want to let a 5% use case scenario hold me back too much in terms of flexibility and overall progress.

BUT, then again, even if, as in my example, my blog listing page is only a 5% use case scenario, it is, for my site, the most popular section. So, while it is not the most prevalent (code wise), it is certainly the most prominent (usage wise). Hmmmmm and Uggg!
# Posted By Ben Nadel | 12/8/06 7:37 AM
Hi Ben,

Here is my questions, though. The value of cfflushing is to get the page down to you quicker, so typically it works best if you start to render the site template and flush it and then do stuff that takes a long time (like db queries). If you're not doing anything that's going to take at least a couple of hundred milliseconds after your flush, there is no point (that I can think of) to HAVE the flush.

Where the flushing would be cool is if you have say a right bar pulling from a web service. In LightBase I could set it up to process the main content area, then render the page, flushing before each dynamic content area, so if your right bar ran long, it wouldn't matter as I'd have rendered the rest of the page already. However the key here is that you MUST NOT PROCESS the sidebar until you've rendered and flushed the rest of the page - otherwise you're still going to be waiting 2 seconds for the web service to respond and then will be flushing before the 3ms it takes to render the processed content for that area - which wouldn't help at all. So you need to have a traditional type-I MVC controller with components in the view calling their own little controllers (think AJAX metaphor in a static HTML page).

Must admit I haven't used cfflush in the 10 years I've been developing CF apps, but nice to know LightBase would be capable of such optimization if it made sense for a given use case. Don't see how you could do it in a system that does all processing first and then starts to render.
# Posted By Peter Bell | 12/8/06 8:08 AM
Hi David,

I tend to agree and it is not something I've ever used, but I could see the value if you're pulling from remote systems for certain content areas as it'd remove their potential latency from your primary content and template load time which could be nice for some use cases.
# Posted By Peter Bell | 12/8/06 8:12 AM
Oldie but goodie,

<cfdump>
<cflog>
<cfflush>

It's Friday, blame Andy for this comment.
# Posted By tony Petruzzi | 12/8/06 8:33 AM
Peter,

I see what you are saying. If you have to do a lot of processing, you are sitting around waiting no matter what (if you do all processing up front). That is why I am not crazy about all processing up front.

Now, we are only attacking this issue from one side - the ColdFusion side. Let's take a look at it from another point of view - the browser rendering. The issue that jumps to mind is the javasciprt tag, <script>. From what I have read (and this may be wrong, or have changed in recent times) every time the browser hits a Script tag, it basically halts rendering so that it can parse the script tag. Once this is done, it continues rendering. When you consider this, CFFlushing parts of document can have an impact. If you force the server to flush content to the browser right after the close HEAD tag, you are giving the browser as much time as possible to hault rendering and parse the script tags in the head BEFORE the browser gets around to flushing the rest of the primary content.

If this is indeed true, here are the possibilities:

1. You flush the html head and the browser has time to process the head and script tags. Then, when the rest of the content is flushed, the browser is immediately ready to start rendering.

2. You flush the html head and the browser is NOT done processing the head and script tags. Then, when the rest of the content is flushed, the browser will not render yet and there will be more delay.

3. You do NOT flush the html head and the browser. There is a longer delay before content is flushed (as it is buffer size determined). Once the browser does finally receive the content it then has to stop, parse Script tags, then continue to render.

If you let the server arbitrarily flush content, then my gut feeling says that the time required to fully render a page would longer. If you flush the head before the content, there is a *higher* chance that the browser will be available for futher rendering (without script parsing) by the time the rest of the content is flushed. Of course, I could be WAAAAAAY off on this. But, I just want to raise the point that while we might be trying to develop interface-agnostic applications, we do have to acknowledge that we are building html interfaces most of the time (these days). There are two bottle necks in a web application - the server AND the client.

Now, this might smell of premature optimization (as some of my stuff tends to)... but at the same time, if there are tips that we can have that can improve performance in small ways, what is the harm of using them; I don't think that that is premature.
# Posted By Ben Nadel | 12/8/06 8:38 AM
Hey Tony,

Nice to see a little bit of the Friday spirit!
# Posted By Peter Bell | 12/8/06 8:49 AM
Hi Ben,

Interesting as always, but I'm not sold! What isn't being mentioned here is the amount of time between the cfflush and the page rendering being completed. I just don't see that getting the head to the browser 3ms quicker is going to save you anything more than 3ms and while I'm a good New Yorker and always in a rush, even I don't bitch about 3ms - my response time just isn't that fast.

It would be interesting to see some tests done showing that actual difference in time between the point in time that you flush and the point in time that the last element of the page is rendered and sent out as I just can't think of any practical case where there would be a non-trivial delay (I don't know what a person might perceive - but I'd think it would have to be into the hundreds of milliseconds) other than remote calls (database or web services). I do still like to know that I would be able to support the approach if I wanted to though.

Only comment on premature optimization would be one of focus. I think it is always good to know and understand more about what might drive the performance of your app. The trick is to make sure that it is (for me at least) 5 or 10% of your thinking at most (unless you're in the business of helping others to optimize the performance of their web apps). The reason is that everything has a cost and the cost of premature optimization is the opportunity cost of what else you might have been able to add in terms of features, elegance or maintainability if you'd spent the time on that. However, that is from a business perspective. If it is fun, go for it. And keep up the great posts though. I always continue to enjoy and learn from them!
# Posted By Peter Bell | 12/8/06 8:59 AM
I am glad you are not sold. That is what makes open discussion so nice: it allows me to use other to keep me grounded :) I am not completely sold either. In fact, while discussing this, I am starting to see more benefits to template/variable driven rendering. Right now, I am not sold either way. I am only more comfortable with my traditional approach as it is what I am used to.

But also, one final thing to touch on... the idea of best case and worst case scenarios. I think we are arguing over a best case scenario. If a page builds in 60ms and has small content, who care when anything on it is flushed. I agree, the difference to the user will be imperceivable. But that is best case scenario. Let's also consider Worst case scenario: someone accidentally clicks on a link that they didn't mean to. Now, it's not just a case of page rendering, it's a case of "oh crap, how fast can I navigate AWAY form the page I just requested". Now, sure, a user could hit the back button, but I find that most people I watch do not do this. They will sit and wait for a page to load before they navigate away. Now, worst case scenario, they click on link that happens to go to a page that has a ton of content. By flushing early, we *might* give the user more time to evaluate and use a primary navigation module.

Now I know times have changed and browsers are MUCH better than they used to be, so in part, this mode of thinking might be outdated. It used to be that things like tables wouldn't render early because the browser needed to know all the rows and what not before it would know how to properly render column widths and what not. I think this has gotten much better though (so this conversation might be moot).

But anyway, the point is, best case scenario, there is NO difference to the user whether or not we use CFFlush. Worst case scenario, the user doesn't have to wait as long (and potentially not get peeved at the site). It seems like there is no downside to using CFFlush for tail-end rendering: it either works OR has no effect.

As far as spending time actually thinking about this stuff... if you think of the ColdFusion "collective" someone among us has to be wasting time figuring this stuff out ;)
# Posted By Ben Nadel | 12/8/06 9:16 AM
If you take a step back and ignore the question of CFFlush need/use couldn't this same question be posed of other tags/features. Even those yet to come? In other words, in the world of building applications shouldn't the system that drives everything be built to be as limitless as possible and as such allow things such as CFFlush or at least not inherently prevent such.

In my mind the ideal framework, app, system, whatever gets in the way as little as possible to allow for flexibility and the solving of issues not previously considered.
# Posted By Joshua Cyr | 12/8/06 9:29 AM
Hi Joshua,

Conceptually I agree, but in practice you don't know to get out of the way of something unless you hve some inkling of what the something might be. The most innocent design decisions can cause huge problems down the line as variabilities appear or requirements are found that were just never considered. For example, imagine if you'd never heard of i18n or thought about it. If you wrote a framework then no matter how smart you were it'd probably be very hard to internationalize because it never even entered your head to think about resource bundles. One of the things I've been playing with recently is looking at a lot of things I don't do now but will need to do soon (like Flex and internationalization) to ensure my design decisions for LightBase will work with them OK.
# Posted By Peter Bell | 12/8/06 10:11 AM
Hi Ben,

All makes sense. And I'm very glad that you and Michael do spend all the time you do on such things as I've pointed out before as I'm usually fascinated by what you come up with and always too lazy, unimaginative or busy (busy is my story and I'm sticking to it :->) to do the same experiments for myself.
# Posted By Peter Bell | 12/8/06 10:13 AM
No doubt about that, but we do know about cfflush. Point being if the goal is to get out of the way and be as flexible as possible then the answer to this entries title question seems clear.

You can't always know how to get out of the way. Just look at me in the mall at xmas, no matter what I am in someones way. But I know if I keep my arms down and movement with the flow I help minimize the exposure. Then again, don't you sometimes just want to jump about and cause a scene? ;-)
# Posted By Joshua Cyr | 12/8/06 10:20 AM
Pete,

Let's make a pact.... you come up with the high-level, really useful, stuff and I'll cover all the premature optimization :) It's all about team work!

But seriously, I tend to concentrate on minor details, because I have trouble understanding big-picture ideas. I can't see the forest, so i focus on the trees, so to speak. Oh well... we all have strengths :)
# Posted By Ben Nadel | 12/8/06 10:21 AM
@Joshua, Agreed 100% which is why I'm going to support the use case. Nice to know I'm not the only one who wants to "rumble in the Mall" on occasions just for the heck of it!

@Ben, Luckily it's all useful and I probably take the position I do on PO because I was never smart enough to figure out HOW things work - only to marshall them at a high level to do the stuff I wanted!
# Posted By Peter Bell | 12/8/06 10:30 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.005.