Patch #44569
openDisable Bullet (gem) unused eager loading detection in development
Description
Bullet (gem) unused eager loading detection makes pages that preload many records very slow in development. For example, in a project with about 4000 members, the project overview and the Log time page take several seconds or more (development mode, SQLite, response time measured with curl):
| Bullet enabled (current development default) |
Unused eager loading detection disabled (this patch) |
Bullet disabled (for reference) |
|
|---|---|---|---|
| Project overview | 10.2 s | 1.1 s | 0.45 s |
| Log time page | 16.5 s | 1.7 s | 0.29 s |
This detection runs after each request, and its cost grows with the square of the number of preloaded records. This is a known issue in Bullet (https://github.com/flyerhzm/bullet/issues/616), closed as stale without a fix.
The following patch disables only the unused eager loading detection. N+1 query detection, the main purpose of adding Bullet in #42555, and counter cache detection stay enabled.
diff --git a/config/environments/development.rb b/config/environments/development.rb
index d41e817f3d..ea7983d7fc 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -64,5 +64,6 @@ Rails.application.configure do
Bullet.enable = true
Bullet.rails_logger = true
Bullet.skip_user_in_notification = true
+ Bullet.unused_eager_loading_enable = false
end
end
Related issues
Updated by Holger Just 20 days ago
- Related to Feature #42555: Adds the Bullet gem to detect query problems such as N+1 and improve performance added
Updated by Holger Just 20 days ago
I'm not sure if the usefulness of bullet's log output during unrelated development is useful enough in general to outweigh the performance impact even (even with this patch applied).
Maybe it would be useful to guard the entire bullet setup behind an environment variable or a configuration.yml setting (with bullet being disabled by default)? People interested in the output can then enable bullet on their own.
Updated by Takenori TAKAKI 17 days ago
Thank you, Holger Just. I agree, and I have changed the approach: with the updated patch, Bullet is disabled by default in development and is enabled only when the REDMINE_ENABLE_BULLET environment variable is set. When enabled, Bullet runs with its default settings, including the unused eager loading detection.
bin/rails server # Bullet disabled (default) REDMINE_ENABLE_BULLET=1 bin/rails server # Bullet enabled
diff --git a/config/environments/development.rb b/config/environments/development.rb
index d41e817f3d..cd5bcbf54b 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -61,7 +61,7 @@ Rails.application.configure do
# config.action_cable.disable_request_forgery_protection = true
config.after_initialize do
- Bullet.enable = true
+ Bullet.enable = ENV['REDMINE_ENABLE_BULLET'].present?
Bullet.rails_logger = true
Bullet.skip_user_in_notification = true
end
Since the patch no longer touches the unused eager loading detection, the subject could be changed to something like "Disable Bullet by default in development".