From 9d87828ba79bae3bf8b4a8f8942306c342bec4a5 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 26 Sep 2024 00:55:02 +0000 Subject: [PATCH] www: don't reread CSS files With preloading, we usually read our CSS files in quick succession so they are unlikely to change in between loads. Thus we can save some syscalls and memory (assuming newer Perl with CoW scalars). Since our normal Perl code is only loaded once and ignores changes on the FS after startup, we'll treat our CSS the same way and assume they don't change after startup. --- lib/PublicInbox/WWW.pm | 48 ++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index 32d0410c6..6f7c30b93 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -565,6 +565,20 @@ sub get_attach { #
-formatted anyways.
 our $STYLE = 'pre{white-space:pre-wrap}*{font-size:100%;font-family:monospace}';
 
+sub _read_css ($$$) {
+	my ($fh, $mini, $fn) = @_;
+	my $ctime = 0;
+	my $local = PublicInbox::IO::read_all $fh; # sets _
+	if ($local =~ /\S/) {
+		$ctime = sprintf('%x',(stat(_))[10]);
+		$local = $mini->($local);
+	}
+	# do not let BOFHs override userContent.css:
+	return ($local, $ctime) if $local !~ /!\s*important\b/i;
+	warn "W: ignoring $fn since it uses `!important'\n";
+	();
+}
+
 sub stylesheets_prepare ($$) {
 	my ($self, $upfx) = @_;
 	my $mini = eval {
@@ -575,7 +589,7 @@ sub stylesheets_prepare ($$) {
 		sub { CSS::Minifier::XS::minify($_[0]) };
 	} || sub { $_[0] };
 
-	my $css_map = {};
+	my $css_map = $self->{-css_map} //= {};
 	my $stylesheets = $self->{pi_cfg}->{css} || [];
 	my $links = [];
 	my $inline_ok = 1;
@@ -598,24 +612,17 @@ sub stylesheets_prepare ($$) {
 				warn "ignoring $fn, non-ASCII word character\n";
 				next;
 			}
-			open(my $fh, '<', $fn) or do {
+			my ($local, $ctime);
+			if (my $rec = $css_map->{$key}) { # already loaded
+				($local, $ctime) = @$rec;
+			} elsif (open(my $fh, '<', $fn)) {
+				($local, $ctime) = _read_css $fh, $mini, $fn;
+				$css_map->{$key} = [ $local, $ctime ];
+			} else {
 				warn "failed to open $fn: $!\n";
 				next;
-			};
-			my $ctime = 0;
-			my $local = PublicInbox::IO::read_all $fh; # sets _
-			if ($local =~ /\S/) {
-				$ctime = sprintf('%x',(stat(_))[10]);
-				$local = $mini->($local);
-			}
-
-			# do not let BOFHs override userContent.css:
-			if ($local =~ /!\s*important\b/i) {
-				warn "ignoring $fn since it uses `!important'\n";
-				next;
 			}
 
-			$css_map->{$key} = $local;
 			$attr->{href} = "$upfx$key.css?$ctime";
 			if (defined($attr->{title})) {
 				$inline_ok = 0;
@@ -654,7 +661,7 @@ sub stylesheets_prepare ($$) {
 	} else {
 		$self->{-style_inline} = $buf;
 	}
-	$self->{-css_map} = $css_map;
+	$css_map;
 }
 
 # returns an HTML fragment with