From f134ba47f94f72013357b6b434217232318b2961 Mon Sep 17 00:00:00 2001 From: shangeyao Date: Sat, 27 Jun 2026 17:26:11 +0800 Subject: [PATCH] [Web UI] Split Monaco chunk and reduce idle app list polling Use adaptive 5s/2s polling on Flink and Spark app lists, split monaco-editor into its own chunk, and include query params in axios cancel keys. Generated-by: Cursor Co-authored-by: Cursor --- .../src/settings/pollingSetting.ts | 36 +++++++++++++++++++ .../src/utils/http/axios/axiosCancel.ts | 6 +++- .../src/views/flink/app/View.vue | 5 +-- .../src/views/spark/app/index.vue | 5 +-- .../streampark-console-webapp/vite.config.ts | 20 +++++++++-- 5 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 streampark-console/streampark-console-webapp/src/settings/pollingSetting.ts diff --git a/streampark-console/streampark-console-webapp/src/settings/pollingSetting.ts b/streampark-console/streampark-console-webapp/src/settings/pollingSetting.ts new file mode 100644 index 0000000000..b4bca0b252 --- /dev/null +++ b/streampark-console/streampark-console-webapp/src/settings/pollingSetting.ts @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const APP_LIST_POLL_IDLE_MS = 5000; + +export const APP_LIST_POLL_ACTIVE_MS = 2000; + +export type AppOptionApps = { + starting: Map; + stopping: Map; + release: Map; + savepointing?: Map; +}; + +export function getAppListPollInterval(optionApps: AppOptionApps): number { + const active = + optionApps.starting.size > 0 || + optionApps.stopping.size > 0 || + optionApps.release.size > 0 || + (optionApps.savepointing?.size ?? 0) > 0; + return active ? APP_LIST_POLL_ACTIVE_MS : APP_LIST_POLL_IDLE_MS; +} diff --git a/streampark-console/streampark-console-webapp/src/utils/http/axios/axiosCancel.ts b/streampark-console/streampark-console-webapp/src/utils/http/axios/axiosCancel.ts index 081233eaa8..5e872b972c 100644 --- a/streampark-console/streampark-console-webapp/src/utils/http/axios/axiosCancel.ts +++ b/streampark-console/streampark-console-webapp/src/utils/http/axios/axiosCancel.ts @@ -5,7 +5,11 @@ import { isFunction } from '/@/utils/is'; // Used to store the identification and cancellation function of each request let pendingMap = new Map(); -export const getPendingUrl = (config: AxiosRequestConfig) => [config.method, config.url].join('&'); +export const getPendingUrl = (config: AxiosRequestConfig) => { + const params = + config.params && Object.keys(config.params).length > 0 ? JSON.stringify(config.params) : ''; + return [config.method, config.url, params].join('&'); +}; export class AxiosCanceler { /** diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue index 99cea85a21..4468f3ca9c 100644 --- a/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue +++ b/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue @@ -57,6 +57,7 @@ import { useAppTableColumns } from './hooks/useAppTableColumns'; import AppTableResize from './components/AppResize.vue'; import { useRouter } from 'vue-router'; + import { getAppListPollInterval } from '/@/settings/pollingSetting'; defineOptions({ name: 'AppView', @@ -242,8 +243,8 @@ if (!getLoading()) { handlePageDataReload(true); } - start(); - }, 2000); + start(getAppListPollInterval(optionApps)); + }, getAppListPollInterval(optionApps)); onMounted(() => { // If there is a page, jump to the page number of the record diff --git a/streampark-console/streampark-console-webapp/src/views/spark/app/index.vue b/streampark-console/streampark-console-webapp/src/views/spark/app/index.vue index e0aa425074..79d1df6a4e 100644 --- a/streampark-console/streampark-console-webapp/src/views/spark/app/index.vue +++ b/streampark-console/streampark-console-webapp/src/views/spark/app/index.vue @@ -54,6 +54,7 @@ import { SparkApplication } from '/@/api/spark/app.type'; import { handleView } from './utils'; import { useRouter } from 'vue-router'; + import { getAppListPollInterval } from '/@/settings/pollingSetting'; defineOptions({ name: 'SparkApplication', }); @@ -221,14 +222,14 @@ const { start, stop } = useTimeoutFn(() => { if (errorCount.value <= 3) { - start(); + start(getAppListPollInterval(optionApps)); } else { return; } if (!getLoading()) { handlePageDataReload(true); } - }, 2000); + }, getAppListPollInterval(optionApps)); onMounted(() => { // If there is a page, jump to the page number of the record diff --git a/streampark-console/streampark-console-webapp/vite.config.ts b/streampark-console/streampark-console-webapp/vite.config.ts index 43075e0f89..d0edea7096 100644 --- a/streampark-console/streampark-console-webapp/vite.config.ts +++ b/streampark-console/streampark-console-webapp/vite.config.ts @@ -90,9 +90,23 @@ export default async ({ command, mode }: ConfigEnv): Promise => { rollupOptions: { maxParallelFileOps: 3, output: { - manualChunks: { - vue: ['vue', 'pinia', 'vue-router'], - antd: ['ant-design-vue', '@ant-design/icons-vue'], + manualChunks(id) { + if (id.includes('node_modules/monaco-editor')) { + return 'monaco-editor'; + } + if ( + id.includes('node_modules/vue/') || + id.includes('node_modules/pinia/') || + id.includes('node_modules/vue-router/') + ) { + return 'vue'; + } + if ( + id.includes('node_modules/ant-design-vue/') || + id.includes('node_modules/@ant-design/icons-vue/') + ) { + return 'antd'; + } }, }, },