diff --git a/atsf_server/web/features/performance/components/performance-page.tsx b/atsf_server/web/features/performance/components/performance-page.tsx
index 6e4e426f..0e9515fe 100644
--- a/atsf_server/web/features/performance/components/performance-page.tsx
+++ b/atsf_server/web/features/performance/components/performance-page.tsx
@@ -111,6 +111,13 @@ function isCacheLevelsValue(value: string) {
return /^\d{1,2}(?::\d{1,2}){0,2}$/.test(value.trim());
}
+function extractMainConfigLines(content: string, matcher: RegExp) {
+ return content
+ .split('\n')
+ .map((line) => line.trim())
+ .filter((line) => line && matcher.test(line));
+}
+
export function PerformancePage() {
const queryClient = useQueryClient();
const { user } = useAuth();
@@ -357,16 +364,6 @@ export function PerformancePage() {
const handleCacheSave = () => {
void runBusyAction('performance-cache', async () => {
- if (!isPositiveInteger(performanceFields.OpenRestyGzipMinLength)) {
- throw new Error('gzip_min_length 必须为大于 0 的整数。');
- }
- const gzipLevel = Number.parseInt(
- performanceFields.OpenRestyGzipCompLevel,
- 10,
- );
- if (Number.isNaN(gzipLevel) || gzipLevel < 1 || gzipLevel > 9) {
- throw new Error('gzip_comp_level 必须在 1 到 9 之间。');
- }
if (performanceFields.OpenRestyCacheEnabled) {
if (!performanceFields.OpenRestyCachePath.trim()) {
throw new Error('启用缓存时必须填写 proxy_cache_path 目录。');
@@ -388,18 +385,6 @@ export function PerformancePage() {
await saveOptionEntries(
[
- [
- 'OpenRestyGzipEnabled',
- String(performanceFields.OpenRestyGzipEnabled),
- ],
- [
- 'OpenRestyGzipMinLength',
- performanceFields.OpenRestyGzipMinLength.trim(),
- ],
- [
- 'OpenRestyGzipCompLevel',
- performanceFields.OpenRestyGzipCompLevel.trim(),
- ],
['OpenRestyCachePath', performanceFields.OpenRestyCachePath.trim()],
[
'OpenRestyCacheLevels',
@@ -439,6 +424,39 @@ export function PerformancePage() {
});
};
+ const handleGzipSave = () => {
+ void runBusyAction('performance-gzip', async () => {
+ if (!isPositiveInteger(performanceFields.OpenRestyGzipMinLength)) {
+ throw new Error('gzip_min_length 必须为大于 0 的整数。');
+ }
+ const gzipLevel = Number.parseInt(
+ performanceFields.OpenRestyGzipCompLevel,
+ 10,
+ );
+ if (Number.isNaN(gzipLevel) || gzipLevel < 1 || gzipLevel > 9) {
+ throw new Error('gzip_comp_level 必须在 1 到 9 之间。');
+ }
+
+ await saveOptionEntries(
+ [
+ [
+ 'OpenRestyGzipEnabled',
+ String(performanceFields.OpenRestyGzipEnabled),
+ ],
+ [
+ 'OpenRestyGzipMinLength',
+ performanceFields.OpenRestyGzipMinLength.trim(),
+ ],
+ [
+ 'OpenRestyGzipCompLevel',
+ performanceFields.OpenRestyGzipCompLevel.trim(),
+ ],
+ ],
+ 'OpenResty 压缩参数已保存。',
+ );
+ });
+ };
+
const handleTemplateSave = () => {
void runBusyAction('performance-template', async () => {
await saveOptionEntries(
@@ -495,6 +513,15 @@ export function PerformancePage() {
);
}
+ const cachePreviewLines = extractMainConfigLines(
+ preview.main_config,
+ /proxy_cache_path|proxy_cache_key|proxy_cache_lock(?:_timeout)?|proxy_cache_use_stale/,
+ );
+ const gzipPreviewLines = extractMainConfigLines(
+ preview.main_config,
+ /gzip(?:_| )/,
+ );
+
return (
-
- {busyKey === 'performance-cache'
- ? '保存中...'
- : '保存压缩与缓存'}
-
- }
- >
-
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyGzipEnabled: checked,
- }))
- }
- />
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheEnabled: checked,
- }))
- }
- />
-
-
+
+
+ {busyKey === 'performance-gzip'
+ ? '保存中...'
+ : '保存压缩设置'}
+
+ }
+ >
+
+
+
setPerformanceFields((previous) => ({
...previous,
- OpenRestyGzipMinLength: event.target.value,
+ OpenRestyGzipEnabled: checked,
}))
}
/>
-
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyGzipCompLevel: event.target.value,
- }))
- }
- />
-
+
+
+ 当前压缩预览
+
+ {gzipPreviewLines.length > 0 ? (
+
+ {gzipPreviewLines.join('\n')}
+
+ ) : (
+
+ 当前主配置预览中没有压缩指令。
+
+ )}
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyGzipMinLength: event.target.value,
+ }))
+ }
+ />
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyGzipCompLevel: event.target.value,
+ }))
+ }
+ />
+
+
-
-
-
+
+
+
+
setPerformanceFields((previous) => ({
...previous,
- OpenRestyCachePath: event.target.value,
+ OpenRestyCacheEnabled:
+ !previous.OpenRestyCacheEnabled,
}))
}
- placeholder="/var/cache/openresty/atsflare"
- />
-
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheLevels: event.target.value,
- }))
+ >
+ {performanceFields.OpenRestyCacheEnabled
+ ? '先关闭缓存'
+ : '先启用缓存'}
+
+
+ {busyKey === 'performance-cache'
+ ? '保存中...'
+ : performanceFields.OpenRestyCacheEnabled
+ ? '保存缓存设置'
+ : '保存为关闭状态'}
+
+
+ }
+ >
+
+
+
+
+ 缓存状态
+
+
+
+
+
+
+ `max_size` 会跟随 `proxy_cache_path`
+ 一起渲染,不会单独占一行。
+
+
+
+
+
+ 当前缓存预览
+
+ {cachePreviewLines.length > 0 ? (
+
+ {cachePreviewLines.join('\n')}
+
+ ) : (
+
+ 当前主配置预览中没有缓存指令。启用缓存并保存后,会出现
+ `proxy_cache_path ... max_size=...;` 这一行。
+
+ )}
+
+
+
+
+
-
-
-
+ >
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCachePath: event.target.value,
+ }))
+ }
+ placeholder="/var/cache/openresty/atsflare"
+ />
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCacheLevels: event.target.value,
+ }))
+ }
+ placeholder="1:2"
+ />
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCacheInactive: event.target.value,
+ }))
+ }
+ placeholder="30m"
+ />
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCacheMaxSize: event.target.value,
+ }))
+ }
+ placeholder="1g"
+ />
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCacheKeyTemplate: event.target.value,
+ }))
+ }
+ />
+
+
setPerformanceFields((previous) => ({
...previous,
- OpenRestyCacheInactive: event.target.value,
- }))
- }
- placeholder="30m"
- />
-
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheMaxSize: event.target.value,
- }))
- }
- placeholder="1g"
- />
-
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheKeyTemplate: event.target.value,
+ OpenRestyCacheLockEnabled: checked,
}))
}
/>
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheLockEnabled: checked,
- }))
- }
- />
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheLockTimeout: event.target.value,
- }))
- }
- placeholder="5s"
- />
-
-
-
- setPerformanceFields((previous) => ({
- ...previous,
- OpenRestyCacheUseStale: event.target.value,
- }))
- }
- />
-
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCacheLockTimeout: event.target.value,
+ }))
+ }
+ placeholder="5s"
+ />
+
+
+
+ setPerformanceFields((previous) => ({
+ ...previous,
+ OpenRestyCacheUseStale: event.target.value,
+ }))
+ }
+ />
+
+
-
-
+
+
) : (