You can reload fragments from the server periodically. This will pick up changes made by other users, or by background tasks.
The .unread-count
fragment below shows the number of unread message.
You can use [up-poll]
to refresh the counter every 30 seconds:
<div class="unread-count" up-poll>
2 new messages
</div>
You may set an optional [up-interval]
attribute to set the reload interval in milliseconds:
<div class="unread-count" up-poll up-interval="10000"> <!-- mark: up-interval -->
2 new messages
</div>
If the value is omitted, a global default is used. You may configure the default like this:
up.radio.config.pollInterval = 10000
The element will be reloaded from the URL from which it was originally loaded.
To reload from another URL, set an [up-source]
attribute on the polling element:
<div class="unread-count" up-poll up-source="/unread-count"> <!-- mark: up-source -->
2 new messages
</div>
A target selector will be derived from the polling element.
For example, the following element will be polled with the selector #score
:
<div id="score" up-poll> <!-- mark: score -->
Score: 1400
</div>
When you see an error Cannot poll untargetable fragment
, Unpoly cannot derive a good
selector that identifies the element. In that case, set a unique [id]
or [up-id]
attribute.
By default polling will not render server responses with an error code, even when the response contains a matching fragment. After the configured interval, the server will be polled again.
In order to any response that contains a matching fragment,
set an [up-fail=false]
attribute:
<div class="download-status" up-poll up-fail="false"> <!-- mark: up-fail -->
Download not ready yet.
</div>
This will update the fragment with any response that contains
a .download-status
element, even when that response has a 4xx or 5xx status code.
When polling encounters a fatal error (like a timeout or loss of network connectivity), it will try again after the configured interval.
By default polling will pause while the fragment's layer is covered by an overlay.
When the layer is uncovered, polling will resume.
To keep polling on background layers, set [up-if-layer=any]
.
Polling will also pause automatically while the browser tab is hidden. When the browser tab is re-activated, polling will resume.
When at least one poll interval was spent paused in the background and the user then returns to the layer or tab, Unpoly will immediately reload the fragment. You can use this to load recent data when the user returns to your app after working on something else for a while. For example, the following would reload your main element after an absence of 5 minutes or more:
<main up-poll up-interval="300_000">
...
</main>
Client-side code may prevent a polling request by preventing an up:fragment:poll
event
on the polling fragment:
up.on('up:fragment:poll', function(event) {
// Don't reload a fragment that contains a playing video
let video = event.target.querySelector('video')
if (video && !video.paused) {
event.preventDefault()
}
})
The server will be polled again after the configured interval, emitting another up:fragment:poll
event.
To not use a polling response that has already been received, use the up:fragment:loaded
event or [up-keep]
attribute.
When polling a fragment periodically we want to avoid rendering unchanged content. This saves CPU time and reduces the bandwidth cost for a request/response exchange to about 1 KB (1 packet).
A good way to detect unchanged content is to deliver the initial fragment
with an ETag
header. An ETag is a hash of the data that was used to produce the HTML:
HTTP/1.1 200 OK
ETag: "x234dff"
<html>
...
<div class='messages'>
...
</div>
...
</html>
When Unpoly polls the fragment, it echoes the ETag in an If-None-Match
header:
GET /messages HTTP/1.1
If-None-Match: "x234dff"
The server can compare the ETag from the request with the ETag of the underlying data.
If no more recent data is available, the server can skip rendering and
respond with 304 Not Modified
. No response body is required.
HTTP/1.1 304 Not Modified
See Conditional requests for more details and examples.
When an update is skipped, Unpoly will try to poll again after the configured interval.
There are multiple ways to stop the polling interval:
[up-poll]
attribute.[up-poll="false"]
attribute.up.radio.stopPolling()
with the polling element.