rails-minify 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +38 -4
- data/lib/rails_minify/patches/action_text_plain_text.rb +3 -3
- data/lib/rails_minify/patches/omniauth_passthrough.rb +19 -10
- data/lib/rails_minify/railtie.rb +31 -7
- data/lib/rails_minify/version.rb +1 -1
- metadata +7 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bf98d2d12a8005e5ef2755cd6bba97a32122a7dd2514518e9a749d1ba367af00
|
|
4
|
+
data.tar.gz: 878a2fab37d90963eb4b4d5924d7b3437847672741471d84ea6cefc686cb7ca1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2baf13ba8db10c35cfaccfaf86b6c966b11555b9b232c1710da044a37dad166f96dee80cdc2380db98321a845c612e80f3a3648dbc515b31f9402a54bc393599
|
|
7
|
+
data.tar.gz: b26a83ac5f86fc456c18444e7eba578cb095fa897ee4bac9a508a10047a9164fc8d22197dc0ae6f7f2c7193ca32a437fe1b8fc35c7c9ab873d9091c936be57a0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.2 (2026-10-18)
|
|
4
|
+
|
|
5
|
+
- `minify:check` also fails on callback chains longer than `callback_limit` (default 5, `ApplicationController`'s callbacks excluded) and on model callbacks that save their own record again; `callback_limit_mode` and `callback_loops` set either to `:warn`. Works without the rest of rails-minify turned on; the manifest check runs only when there is a manifest.
|
|
6
|
+
- Requires activesupport-minimizer 0.1.1.
|
|
7
|
+
|
|
8
|
+
## 0.1.1 (2026-10-18)
|
|
9
|
+
|
|
10
|
+
- `:omniauth` isn't installed when OmniAuth already skips requests that can't be the strategy's (a public `Strategy#passthrough?`, as in the version proposed upstream); its own helper no longer shares that name.
|
|
11
|
+
|
|
3
12
|
## 0.1.0 (2026-10-18)
|
|
4
13
|
|
|
5
14
|
First release.
|
data/README.md
CHANGED
|
@@ -14,6 +14,19 @@ config.rails_minify.enabled = true
|
|
|
14
14
|
(`config.ar_minimizer.enums = false`, `config.rails_minify.patches = [:omniauth]`).
|
|
15
15
|
Ruby 3.4+, Rails 8.0, 8.1 and main.
|
|
16
16
|
|
|
17
|
+
Turn it on in tests too, so a call to a method strict mode removed fails in CI
|
|
18
|
+
rather than in production. In development, strict mode alone is enough: the
|
|
19
|
+
same errors show up while you work, and the compiling parts, which don't
|
|
20
|
+
follow code reloads, stay off.
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
# config/environments/test.rb
|
|
24
|
+
config.rails_minify.enabled = true
|
|
25
|
+
|
|
26
|
+
# config/environments/development.rb
|
|
27
|
+
config.ar_minimizer.slim = true # strict mode, without the rest
|
|
28
|
+
```
|
|
29
|
+
|
|
17
30
|
## Strict by default
|
|
18
31
|
|
|
19
32
|
Active Record defines, for every column, a reader, a writer and 19 more
|
|
@@ -57,7 +70,7 @@ For parts of Rails and common gems that redo work on every request.
|
|
|
57
70
|
Attachments that are Active Storage blobs, remote images or inline content
|
|
58
71
|
are cached too: a blob without a caption contributes its filename, which a
|
|
59
72
|
hit checks in one query (renamed or deleted: computed again). Other
|
|
60
|
-
attachables aren't cached. In
|
|
73
|
+
attachables aren't cached. In [Japan Voyage](https://japanvoyage.jp), 13% of all allocations on its
|
|
61
74
|
pages came from it, and guides with images another 4.5%.
|
|
62
75
|
* `:request_host`: `ActionDispatch::Request#host` runs a regexp substitution
|
|
63
76
|
on every call, port or not, and Rails reads it several times per request.
|
|
@@ -67,11 +80,13 @@ For parts of Rails and common gems that redo work on every request.
|
|
|
67
80
|
options on every request before looking at the path. Requests that can't
|
|
68
81
|
be OmniAuth's go straight to the app. Only when that's certain up front:
|
|
69
82
|
a session is present, not in test mode, no `other_phase` or callable
|
|
70
|
-
paths, and the strategy doesn't override how paths are matched.
|
|
83
|
+
paths, and the strategy doesn't override how paths are matched. Not
|
|
84
|
+
installed when OmniAuth already does this itself (it then has a public
|
|
85
|
+
`Strategy#passthrough?`, as in the version proposed upstream).
|
|
71
86
|
|
|
72
87
|
## Numbers
|
|
73
88
|
|
|
74
|
-
|
|
89
|
+
Japan Voyage, 132 production pages, with everything on (strict mode after
|
|
75
90
|
rubocop-minify's rewrites, all patches): identical HTML, and
|
|
76
91
|
1,561,283 → 1,224,141 allocations per pass (−21.6%). The machine was too
|
|
77
92
|
loaded for wall-clock times to mean much.
|
|
@@ -79,7 +94,26 @@ loaded for wall-clock times to mean much.
|
|
|
79
94
|
## Checks
|
|
80
95
|
|
|
81
96
|
* `bin/rails minify:census`: how much of the app runs compiled, and why the rest doesn't.
|
|
82
|
-
* `bin/rails minify:check
|
|
97
|
+
* `bin/rails minify:check` (for CI; works whether or not the rest of
|
|
98
|
+
rails-minify is on) fails on:
|
|
99
|
+
* callbacks naming methods that don't exist;
|
|
100
|
+
* callback chains with more than `callback_limit` (default 5) of the app's
|
|
101
|
+
own callbacks (Rails' and gems' don't count; controllers per action).
|
|
102
|
+
Callbacks inherited from `callback_limit_exclude` (default
|
|
103
|
+
`["ApplicationController"]`: time zone, locale, current user, the
|
|
104
|
+
per-request basics) don't count either. A base class over the limit is
|
|
105
|
+
reported once, with the classes that inherit it;
|
|
106
|
+
* model callbacks that call `save`, `update`, `touch`, ... on the record
|
|
107
|
+
they run for, which runs the chain again;
|
|
108
|
+
* an out-of-date manifest.
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
config.rails_minify.callback_limit = 8
|
|
112
|
+
config.rails_minify.callback_limit_exclude = ["ApplicationController", "Admin::BaseController"] # [] counts everything
|
|
113
|
+
config.rails_minify.callback_limit_mode = :warn # report, don't fail
|
|
114
|
+
config.rails_minify.callback_loops = :warn
|
|
115
|
+
config.rails_minify.allow_callback_loops = ["Trip#recalculate"] # guarded on purpose
|
|
116
|
+
```
|
|
83
117
|
|
|
84
118
|
## Things found that are app config, not patches
|
|
85
119
|
|
|
@@ -4,9 +4,9 @@ module RailsMinify
|
|
|
4
4
|
module Patches
|
|
5
5
|
# ActionText::Content#to_plain_text walks the whole HTML tree with
|
|
6
6
|
# Nokogiri on every call, and looks up the record behind every attachment:
|
|
7
|
-
#
|
|
8
|
-
# (excerpts, meta descriptions, cards). The text is computed
|
|
9
|
-
# distinct HTML and kept, up to MAX_BYTES of HTML.
|
|
7
|
+
# on Japan Voyage (japanvoyage.jp), 13% of all allocations on its pages
|
|
8
|
+
# came from it (excerpts, meta descriptions, cards). The text is computed
|
|
9
|
+
# once per distinct HTML and kept, up to MAX_BYTES of HTML.
|
|
10
10
|
#
|
|
11
11
|
# Without attachments the text depends on the HTML alone. An attachment
|
|
12
12
|
# adds its record's text: for Active Storage blobs "[caption]" (from the
|
|
@@ -3,20 +3,29 @@
|
|
|
3
3
|
module RailsMinify
|
|
4
4
|
module Patches
|
|
5
5
|
# Every OmniAuth strategy is a middleware that, on every request, dups
|
|
6
|
-
# itself (and its Hashie::Mash options) before looking at the path:
|
|
7
|
-
#
|
|
8
|
-
# on a login path. Requests that can't be OmniAuth's
|
|
9
|
-
# app; anything that might be (or that the strategy
|
|
10
|
-
# callable paths, other_phase, overridden path
|
|
11
|
-
# missing session, which OmniAuth reports) runs
|
|
6
|
+
# itself (and its Hashie::Mash options) before looking at the path: on
|
|
7
|
+
# Japan Voyage (japanvoyage.jp) about 35k allocations per pass over its
|
|
8
|
+
# pages, none of them on a login path. Requests that can't be OmniAuth's
|
|
9
|
+
# go straight to the app; anything that might be (or that the strategy
|
|
10
|
+
# decides at runtime: callable paths, other_phase, overridden path
|
|
11
|
+
# methods, test mode, a missing session, which OmniAuth reports) runs
|
|
12
|
+
# OmniAuth as before.
|
|
12
13
|
module OmniAuthPassthrough
|
|
13
14
|
# What decides whether a request is the strategy's. A strategy that
|
|
14
15
|
# overrides any of these decides for itself: always run it.
|
|
15
16
|
PATH_METHODS = %i[call! on_auth_path? on_request_path? on_callback_path? on_path? request_path
|
|
16
17
|
callback_path current_path path_prefix script_name].freeze
|
|
17
18
|
|
|
18
|
-
def self.install!
|
|
19
|
-
|
|
19
|
+
def self.install!(strategy = OmniAuth::Strategy)
|
|
20
|
+
return if upstream?(strategy) # OmniAuth does this itself
|
|
21
|
+
|
|
22
|
+
strategy.prepend(self) unless strategy < self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The same check in OmniAuth (sampokuokkanen/omniauth@skip-dup-off-auth-paths,
|
|
26
|
+
# proposed upstream) defines a public Strategy#passthrough?.
|
|
27
|
+
def self.upstream?(strategy = OmniAuth::Strategy)
|
|
28
|
+
strategy.public_method_defined?(:passthrough?) && !(strategy < self)
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
# Per strategy class: are all of PATH_METHODS OmniAuth's own?
|
|
@@ -28,14 +37,14 @@ module RailsMinify
|
|
|
28
37
|
end
|
|
29
38
|
|
|
30
39
|
def call(env)
|
|
31
|
-
return super unless
|
|
40
|
+
return super unless minify_passthrough?(env)
|
|
32
41
|
|
|
33
42
|
@app.call(env)
|
|
34
43
|
end
|
|
35
44
|
|
|
36
45
|
private
|
|
37
46
|
|
|
38
|
-
def
|
|
47
|
+
def minify_passthrough?(env)
|
|
39
48
|
return false if OmniAuth.config.test_mode || !env["rack.session"] || respond_to?(:other_phase)
|
|
40
49
|
return false unless OmniAuthPassthrough.standard_paths?(self.class)
|
|
41
50
|
|
data/lib/rails_minify/railtie.rb
CHANGED
|
@@ -69,15 +69,39 @@ module RailsMinify
|
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
desc "Fail on
|
|
72
|
+
desc "Fail on callback problems (missing targets, chains longer than callback_limit, " \
|
|
73
|
+
"callbacks that save their own record) and an out-of-date manifest"
|
|
73
74
|
task check: :environment do
|
|
74
75
|
app = prepare.call
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
options = app.config.rails_minify
|
|
77
|
+
routed = AsMinimizer::Check.routed_actions(app.routes)
|
|
78
|
+
failed = false
|
|
79
|
+
report = lambda do |title, items, mode|
|
|
80
|
+
next puts("#{title}: none") if items.empty?
|
|
81
|
+
|
|
82
|
+
puts "#{title}: #{items.size}#{" (warning)" if mode == :warn}"
|
|
83
|
+
items.each { puts " #{it}" }
|
|
84
|
+
failed ||= mode != :warn
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
missing = AsMinimizer::Check.callback_targets(routed: routed).select { it.status == :missing }
|
|
88
|
+
report.("callback targets naming no method", missing, :fail)
|
|
89
|
+
|
|
90
|
+
limit = options.callback_limit || 5
|
|
91
|
+
report.("callback chains with more than #{limit} of the app's callbacks",
|
|
92
|
+
AsMinimizer::Check.long_chains(limit: limit, root: app.root.to_s, routed: routed,
|
|
93
|
+
exclude: options.callback_limit_exclude.nil? ? ["ApplicationController"] : Array(options.callback_limit_exclude)),
|
|
94
|
+
(options.callback_limit_mode || :fail).to_sym)
|
|
95
|
+
|
|
96
|
+
report.("callbacks saving their own record",
|
|
97
|
+
AsMinimizer::Check.callback_loops(root: app.root.to_s, allow: Array(options.allow_callback_loops)), (options.callback_loops || :fail).to_sym)
|
|
98
|
+
|
|
99
|
+
if defined?(ArMinimizer::Census) && app.root.join("config/ar_minimizer.json").exist?
|
|
100
|
+
manifest = ArMinimizer::Census.manifest_state(app.root, ArMinimizer::Index.from_models)
|
|
101
|
+
puts "manifest: #{manifest}"
|
|
102
|
+
failed ||= manifest.start_with?("out of date")
|
|
103
|
+
end
|
|
104
|
+
abort if failed
|
|
81
105
|
end
|
|
82
106
|
end
|
|
83
107
|
end
|
data/lib/rails_minify/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-minify
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sampo Kuokkanen
|
|
@@ -44,6 +44,9 @@ dependencies:
|
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '0.1'
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: 0.1.1
|
|
47
50
|
type: :runtime
|
|
48
51
|
prerelease: false
|
|
49
52
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -51,6 +54,9 @@ dependencies:
|
|
|
51
54
|
- - "~>"
|
|
52
55
|
- !ruby/object:Gem::Version
|
|
53
56
|
version: '0.1'
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: 0.1.1
|
|
54
60
|
description: Turns on activerecord-, activesupport- and actionpack-minimizer, and
|
|
55
61
|
patches parts of Rails and common gems that redo work on every request (Action Text
|
|
56
62
|
plain text, Request#host, OmniAuth strategies).
|