PDA

View Full Version : [PATCH] Prevent status frame from reloading all images



mcfly
2005-05-24, 03:13
I experimented a bit more with page reloading:

1. Using the "refresh" meta tag causes the browsers (Firefox /
Konqueror) to ommit the "If-Modified-Since" header when refreshing the
page. Images within the page will also be fully refetched because of the
missing "if-modified-since" header.

2. Using Javascript "location.reload(false)" will cause the browsers to
set the "if-modified-since" header and therefore give the server the
change to signal 304 (Not modified). Firefox will also re-GET the images
(with the "if-modified-since" header set, resulting in a 304 for the
images). Konqueror will NOT re-GET the images.

3. Using Javascript "location.href='...' is similar to case 2) but both
Konqueror and Firefox will not re-GET the images embedded in the page.

My conclusions:

1. meta "refresh" is evil for pages with a lot of static content ;-)
2. IMO this cannot be fixed in the "HTTP code" (as suggested by Michael)
since the server MUST resend the whole content if the
"if-modified-since" header is missing.

mherger
2005-05-24, 05:35
> 2. IMO this cannot be fixed in the "HTTP code" (as suggested by Michael)
> since the server MUST resend the whole content if the
> "if-modified-since" header is missing.

Yep, thought so after playing with the liveHTTPHeader extension in FireFox
:-/.

--

Michael

-----------------------------------------------------------
Help translate SlimServer by using the
StringEditor Plugin (http://www.herger.net/slim/)

fuzzyT
2005-05-24, 08:17
Michel Marti wrote:

> My conclusions:
>
> 1. meta "refresh" is evil for pages with a lot of static content ;-)
> 2. IMO this cannot be fixed in the "HTTP code" (as suggested by Michael)
> since the server MUST resend the whole content if the
> "if-modified-since" header is missing.

Interesting.

Looks like using a non-META-REFRESH method for browser update is going
to be the answer.

This does raise a question about the webUI-to-server communication
pattern.

In the existing model we are polling from the webUI for changes in
server state, and guessing at the best timing for this interval. Using
just the raw browser, we are pretty much stuck with this as it is a
request-response world. But what we'd ideally want is a way a change in
server state (new song, etc.) to fire an event that would trigger the
browser UI update. Maybe an AJAX type of approach would work here, or a
small Flash component that would just listen.

--rt

Dan Sully
2005-05-24, 08:28
* ron thigpen shaped the electrons to say...

>>My conclusions:
>>
>>1. meta "refresh" is evil for pages with a lot of static content ;-)
>>2. IMO this cannot be fixed in the "HTTP code" (as suggested by Michael)
>>since the server MUST resend the whole content if the
>>"if-modified-since" header is missing.

Vidur and I had a look at this about two months ago - and came to the same
conclusion. I had bent my head doing different tests, and tcpdumps. Tried
with Refresh: headers, no META, with JS, etc. Eventually we started digging
into the Mozilla source code, which appears to be buggy (I don't recall the
exact details, but I think a "never do a If-Modified-Since" flag was set if
refresh was also set). I believe your slight alteration to the JS refresh
might do the the trick (haven't tested yet).

In addition, I have code that implements ETags in the server, which is
basically a better If-Modified-Since. Another goal here was that since we
control the horizontal and the vertical - we can not rebuild a playlist page
(which is potentially expensive), and just send back a 304 to the browser.

ETag patch is attached if anyone wants to play with it.

-D
--
Welcome to hell. Here's your accordion.

mcfly
2005-05-24, 10:36
ron thigpen wrote:

> request-response world. But what we'd ideally want is a way a change in
> server state (new song, etc.) to fire an event that would trigger the
> browser UI update. Maybe an AJAX type of approach would work here, or a
> small Flash component that would just listen.

One possibility would be to send multipart responses (multipart/mixed) to the
client. This way, the server could actively push new pages to the client at any
desired point in time.

Jacob Potter
2005-05-24, 12:21
On 5/24/05, ron thigpen <ron (AT) fuzzsonic (DOT) com> wrote:
> Maybe an AJAX type of approach would work here, or a
> small Flash component that would just listen.

Like the ExBrowse2 skin, maybe? :)

- Jacob

Steve Baumgarten
2005-05-24, 12:39
Jacob Potter wrote:

> Like the ExBrowse2 skin, maybe? :)

I think this is surely the way to go. It's more work on both the client
and server side, but when you're all done you get a very
application-like user interface. People have been amazed at what Google
has been able to do with their maps site using AJAX, not to mention even
relatively small scale things like Google Suggest:

http://www.google.com/webhp?complete=1&hl=en

Go ahead and start typing. Watch the suggestions update in real time. Cool!

Of course you need a fairly recent browser for this to work. (I imagine
that's not a huge problem, and one can degrade gracefully in the absence
of a recent browser and do it the old fashioned way, just as the Default
skin currently does.)

ExBrowse2 is a great start. I alternate between it and Fishbone (my
first true love, as kdf saved me from the boring Default skin), but I
could certainly live without those all too frequent "let me fetch every
single image on the playlist page yet again" moments. I'm sure the
single-threaded server would be happier living without them, too.

Glad to see people talking about this pet peeve of mine, regardless of
the solution chosen.

SBB





Visit our website at http://www.ubs.com

This message contains confidential information and is intended only
for the individual named. If you are not the named addressee you
should not disseminate, distribute or copy this e-mail. Please
notify the sender immediately by e-mail if you have received this
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free
as information could be intercepted, corrupted, lost, destroyed,
arrive late or incomplete, or contain viruses. The sender therefore
does not accept liability for any errors or omissions in the contents
of this message which arise as a result of e-mail transmission. If
verification is required please request a hard-copy version. This
message is provided for informational purposes and should not be
construed as a solicitation or offer to buy or sell any securities or
related financial instruments.

fuzzyT
2005-05-24, 12:43
Jacob Potter wrote:

> Like the ExBrowse2 skin, maybe? :)

Is this how ExBrowse2 works?

(Sorry, but when I try it, it just seems to get stuck at "Loading...")

Curious, how did you implement the client side listener?

--rt

Jacob Potter
2005-05-24, 13:04
On 5/24/05, ron thigpen <ron (AT) fuzzsonic (DOT) com> wrote:
> Is this how ExBrowse2 works?
>
> (Sorry, but when I try it, it just seems to get stuck at "Loading...")

Erk. What browser are you using?

> Curious, how did you implement the client side listener?

It pulls an XML version of the status/playlist page every 5 seconds.
It sounds overly CPU-intensive, but SlimServer still takes less than
1% total CPU on my server (AthlonXP 2500, Debian). Then the
clients-side JS checks for changes and updates the page accordingly.

I just recently implemented drag-and-drop playlist rearranging.

- Jacob

fuzzyT
2005-05-24, 13:24
Jacob Potter wrote:

> Erk. What browser are you using?

Tried in both FF1.0.4 and IE6 on Win2000. I am at a remote location,
though one with a fast connection. H/W and S/W firewalls on the server
end. No problem with default skin. SS password in place, so HTTP-Auth
is in effect. What protocol/port does the .js/XML traffic flow on?

> It pulls an XML version of the status/playlist page every 5 seconds.

Ahh, so not a client listener scheme but a "check often and update UI
only on change scheme". Makes sense. How intensive is your checking
for XML changes on the client side? Are you using HTTP headers for
modified and size or parsing XML and looking for diffs? Seems you could
use the coming ETags functionality and just check for changes. Might be
some efficiency gains there: just an HTTP HEAD for the server to dish up.

> I just recently implemented drag-and-drop playlist rearranging.

Sound nice. I'll try again from the home network and see how it goes.

Thanks,

--rt

max.spicer
2005-05-24, 13:31
On 5/24/05, ron thigpen <ron (AT) fuzzsonic (DOT) com> wrote:
> Is this how ExBrowse2 works?
>
> (Sorry, but when I try it, it just seems to get stuck at "Loading...")

Erk. What browser are you using?
I just tried XBrowse2 for the first time. It initally sat "Loading..." for ages (1-2 minutes), but eventully displayed the interface. Now when I load it, it seems to appear in about 5 seconds. I'm using Firefox 1.0.4 on WinXP, with the server running 6.1 R3274.

Great skin, but I have to say that I'm not a fan of the Fishbone look. Still, the really cool javascript stuff and lack of annoying reloads more than makes up for it!

Max

mherger
2005-05-24, 13:35
> Great skin, but I have to say that I'm not a fan of the Fishbone look.

try Default2 - same technique as ExBrowse2, but Default's layout.

--

Michael

-----------------------------------------------------------
Help translate SlimServer by using the
SlimString Translation Helper (http://www.herger.net/slim/)

Jacob Potter
2005-05-24, 14:03
On 5/24/05, ron thigpen <ron (AT) fuzzsonic (DOT) com> wrote:
> Ahh, so not a client listener scheme but a "check often and update UI
> only on change scheme". Makes sense. How intensive is your checking
> for XML changes on the client side? Are you using HTTP headers for
> modified and size or parsing XML and looking for diffs? Seems you could
> use the coming ETags functionality and just check for changes. Might be
> some efficiency gains there: just an HTTP HEAD for the server to dish up.

It's actually not very optimised, just parsing the XML out into a
bunch of Javascript variables. Still, on my main system (also the
server), Firefox uses around 1.5% CPU with it running. Even on my old
Powerbook G4 400mhz it makes Firefox take up about 10%; Safari runs
around 5%.

There are definitely improvements to be had, but it works quite well
already. At the moment I'm more concerned with making the code more
reusable. Default2 is currently a complete fork of ExBrowse2, which is
definitely not ideal, so I'm putting together a library to merge the
common code.

Hope you like it,

- Jacob

max.spicer
2005-05-24, 14:47
> Great skin, but I have to say that I'm not a fan of the Fishbone look.

try Default2 - same technique as ExBrowse2, but Default's layout.
Sorted! I'm still getting quite large delays on first load though - I've just used it again after an hour of not doing so, and it took around 20 seconds to display the front page.

max.spicer
2005-05-24, 14:50
Actually, Default2 messes up a bit with long track names. My currently playing track is "5. 'Songs of Ariel: Come unto these yellow sands' by Frank Martin from 'Mass for Double Choir - The Sixteen - Harry Christophers' from Mass for Double Choir - The Sixteen - Harry Christophers by Frank Martin". This wraps and disappears behind "The current playlist: [...]". Not a major problem admittedly, but it spoils the look.

max.spicer
2005-05-24, 14:55
Actually, Default2 messes up a bit with long track names. My currently playing track is "5. 'Songs of Ariel: Come unto these yellow sands' by Frank Martin from 'Mass for Double Choir - The Sixteen - Harry Christophers' from Mass for Double Choir - The Sixteen - Harry Christophers by Frank Martin". This wraps and disappears behind "The current playlist: [...]". Not a major problem admittedly, but it spoils the look.

I've just noticed that the album and artist appears twice in that string. Something else is obviously messed up at the moment!

mcfly
2005-05-27, 14:33
Dan Sully wrote:
> ETag patch is attached if anyone wants to play with it.

Dan, The images still expire after an hour because of the following header in
latest HTTP.pm from trunk:

Cache-Control: max-age=3600, public

This is what RFC2616 states:

" The expiration time of an entity MAY be specified by the origin server using
the Expires header (see section 14.21). Alternatively, it MAY be specified using
the max-age directive in a response. When the max-age cache-control directive is
present in a cached response, the response is stale if its current age is
greater than the age value given (in seconds) at the time of a new request for
that resource. The max-age directive on a response implies that the response is
cacheable (i.e., "public") unless some other, more restrictive cache directive
is also present."

The patch below sets max-age to a half year, but maybe we could even drop either
max-age or expires?!?

Index: HTTP.pm
================================================== =================
--- HTTP.pm (revision 3296)
+++ HTTP.pm (working copy)
@@ -734,9 +734,9 @@
# this might do well to break up into methods
if ($contentType =~ /image/) {

- # images should expire from cache one year from now
+ # images should expire from cache one half year from now
$response->expires(time() + HALFYEAR);
- $response->header('Cache-Control' => sprintf('max-age=%d,
public', 3600));
+ $response->header('Cache-Control' => sprintf('max-age=%d,
public', HALFYEAR));
}

if ($contentType =~ /text/) {