PERF: Precompile child theme stylesheets. (#13040)

PERF: Precompile child theme stylesheets. (#13040)

Previously, we only precompiled the CSS for parent themes but not for the child themes. As a result, the CSS for child themes were being compiled during the first request which made the respond time high for that request.

diff --git a/lib/stylesheet/manager.rb b/lib/stylesheet/manager.rb
index 91f449c..86e2552 100644
--- a/lib/stylesheet/manager.rb
+++ b/lib/stylesheet/manager.rb
@@ -164,13 +164,23 @@ class Stylesheet::Manager
     themes.each do |id, name, color_scheme_id|
       targets.each do |target|
         theme_id = id || SiteSetting.default_theme_id
-        next if target =~ THEME_REGEX && theme_id == -1
-        cache_key = "#{target}_#{theme_id}"
 
-        STDERR.puts "precompile target: #{target} #{name}"
-        builder = self.new(target, theme_id)
-        builder.compile(force: true)
-        cache[cache_key] = nil
+        if target =~ THEME_REGEX
+          next if theme_id == -1
+
+          theme_ids = Theme.transform_ids([theme_id], extend: true)
+
+          theme_ids.each do |t_id|
+            builder = self.new(target, t_id)
+            STDERR.puts "precompile target: #{target} #{builder.theme.name}"
+            next if builder.theme.component && !builder.theme.has_scss(target)
+            builder.compile(force: true)
+          end
+        else
+          STDERR.puts "precompile target: #{target} #{name}"
+          builder = self.new(target, theme_id)
+          builder.compile(force: true)
+        end
       end
 
       theme_color_scheme = ColorScheme.find_by_id(color_scheme_id) || ColorScheme.base
diff --git a/spec/components/stylesheet/manager_spec.rb b/spec/components/stylesheet/manager_spec.rb
index ef21907..b82d49f 100644
--- a/spec/components/stylesheet/manager_spec.rb
+++ b/spec/components/stylesheet/manager_spec.rb
@@ -485,6 +485,27 @@ describe Stylesheet::Manager do
       Theme.update_all(user_selectable: false)
       user_theme = Fabricate(:theme, user_selectable: true, color_scheme: scheme1)
       default_theme = Fabricate(:theme, user_selectable: true, color_scheme: scheme2)
+
+      child_theme = Fabricate(:theme).tap do |t|
+        t.component = true
+        t.save!
+        user_theme.add_relative_theme!(:child, t)
+      end
+
+      child_theme_with_css = Fabricate(:theme).tap do |t|
+        t.component = true
+
+        t.set_field(
+          target: :common,
+          name: :scss,
+          value: "body { background: green }"
+        )
+
+        t.save!
+
+        user_theme.add_relative_theme!(:child, t)
+      end
+
       default_theme.set_default!
 
       StylesheetCache.destroy_all
@@ -492,7 +513,8 @@ describe Stylesheet::Manager do
       Stylesheet::Manager.precompile_css
       results = StylesheetCache.pluck(:target)
 
-      expect(results.size).to eq(22) # (2 themes x 8 targets) + 6 color schemes (2 custom theme schemes, 4 base schemes)
+      expect(results.size).to eq(24) # (2 themes x 8 targets) + (1 child Theme x 2 targets) + 6 color schemes (2 custom theme schemes, 4 base schemes)
+
       core_targets.each do |tar|
         expect(results.count { |target| target =~ /^#{tar}_(#{scheme1.id}|#{scheme2.id})$/ }).to eq(2)
       end
@@ -507,7 +529,7 @@ describe Stylesheet::Manager do
       Stylesheet::Manager.precompile_css
       results = StylesheetCache.pluck(:target)
 
-      expect(results.size).to eq(28) # (2 themes x 8 targets) + (1 no/default/core theme x 6 core targets) + 6 color schemes (2 custom theme schemes, 4 base schemes)
+      expect(results.size).to eq(30) # (2 themes x 8 targets) + (1 child Theme x 2 targets) + (1 no/default/core theme x 6 core targets) + 6 color schemes (2 custom theme schemes, 4 base schemes)
 
       core_targets.each do |tar|
         expect(results.count { |target| target =~ /^(#{tar}_(#{scheme1.id}|#{scheme2.id})|#{tar})$/ }).to eq(3)

GitHub sha: 958b56dc

This commit appears in #13040 which was approved by davidtaylorhq and SamSaffron. It was merged by SamSaffron.