-
Notifications
You must be signed in to change notification settings - Fork 477
Open
Description
In a situation when page loads or internet connection are slow, clicking multiple links within a short period of time should only load the last link clicked.
When prefetch is disabled, Turbo works correctly by canceling pending requests issued by previous clicks.
When prefetch is enabled however, all requests issued by clicks will run to completion. The page will re-render on each completed request resulting in flickering. And the last link clicked is not guaranteed to be the one visible when all requests complete.
In the following example, there are 3 links that take 2s,6s, and 4s to load. Clicking them consecutively in that order will result in the slowest page being opened last, even though it was a second click, not the last one.
Screen recording of example
turbo-screen-recording-optimized.mov
Example with Rails
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails"
gem "puma"
gem "propshaft"
gem "turbo-rails"
end
require "action_controller/railtie"
class App < Rails::Application
config.load_defaults "7.1"
config.consider_all_requests_local = true
config.turbo.draw_routes = false
routes.append do
root to: "application#index"
end
end
$template = DATA.read
class ApplicationController < ActionController::Base
include Rails.application.routes.url_helpers
def index
sleep(params[:sleep].to_i) if params[:sleep].present?
render inline: $template, formats: :html
end
end
App.initialize!
Rack::Server.new(app: App, Port: 3000).start
__END__
<html>
<head>
<script type="importmap">
{
"imports": {
"@hotwired/turbo-rails": "<%= asset_path("turbo.js") %>"
}
}
</script>
<script type="module">
import "@hotwired/turbo-rails"
</script>
</head>
<body>
<h1>page <%= (params[:page].present? ? params[:page] : 'root').upcase %></h1>
<%= link_to "root", root_path %>
<div data-turbo-prefetch="false">
<h2>without prefetch</h2>
<ol>
<li><%= link_to "slow", root_path(page: 'slow', sleep: 2) %></li>
<li><%= link_to "slowest", root_path(page: 'slowest', sleep: 6) %></li>
<li><%= link_to "slower", root_path(page: 'slower', sleep: 4) %></li>
</ol>
</div>
<div>
<h2>with prefetch</h2>
<ol>
<li><%= link_to "slow", root_path(page: 'slow', sleep: 2) %></li>
<li><%= link_to "slowest", root_path(page: 'slowest', sleep: 6) %></li>
<li><%= link_to "slower", root_path(page: 'slower', sleep: 4) %></li>
</ol>
</div>
</body>
</html>Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels