From 74d7ee7cddc6e6d99efd131a0d7635d819f6814f Mon Sep 17 00:00:00 2001 From: unidevel Date: Thu, 16 Jan 2025 11:54:37 +0000 Subject: [PATCH] Fix webpack file size warnings on entrypoints in presto-ui --- presto-ui/src/components/ClusterHUD.jsx | 1 + presto-ui/src/components/LivePlan.jsx | 5 ++- presto-ui/src/components/QueryDetail.jsx | 2 + presto-ui/src/components/QueryList.jsx | 1 + presto-ui/src/components/QueryPlanView.jsx | 3 +- presto-ui/src/components/QueryStageView.jsx | 2 +- presto-ui/src/components/QueryViewer.jsx | 4 +- presto-ui/src/components/SQLInput.jsx | 4 +- presto-ui/src/components/StageDetail.jsx | 5 ++- presto-ui/src/components/WorkerStatus.jsx | 2 + presto-ui/src/components/WorkerThreadList.jsx | 2 + presto-ui/src/d3utils.js | 34 ++++++++++++++ presto-ui/src/embedded_plan.jsx | 4 +- presto-ui/src/index.jsx | 6 ++- presto-ui/src/lazy.jsx | 27 +++++++++++ presto-ui/src/plan.jsx | 4 +- presto-ui/src/query.jsx | 4 +- presto-ui/src/query_viewer.jsx | 4 +- presto-ui/src/res_groups.jsx | 4 +- presto-ui/src/sql_client.jsx | 5 ++- presto-ui/src/stage.jsx | 4 +- presto-ui/src/timeline.jsx | 4 +- presto-ui/src/utils.js | 21 --------- presto-ui/src/webpack.config.js | 45 +++++++++++++------ presto-ui/src/worker.jsx | 6 ++- 25 files changed, 150 insertions(+), 53 deletions(-) create mode 100644 presto-ui/src/d3utils.js create mode 100644 presto-ui/src/lazy.jsx diff --git a/presto-ui/src/components/ClusterHUD.jsx b/presto-ui/src/components/ClusterHUD.jsx index 80e9768a520d5..8e1634a756910 100644 --- a/presto-ui/src/components/ClusterHUD.jsx +++ b/presto-ui/src/components/ClusterHUD.jsx @@ -293,3 +293,4 @@ export class ClusterHUD extends React.Component { } } +export default ClusterHUD; \ No newline at end of file diff --git a/presto-ui/src/components/LivePlan.jsx b/presto-ui/src/components/LivePlan.jsx index 04fb189eb86da..7463d1a196d67 100644 --- a/presto-ui/src/components/LivePlan.jsx +++ b/presto-ui/src/components/LivePlan.jsx @@ -18,7 +18,8 @@ import ReactDOMServer from "react-dom/server"; import * as dagreD3 from "dagre-d3"; import * as d3 from "d3"; -import {formatRows, getStageStateColor, initializeGraph, initializeSvg, truncateString} from "../utils"; +import {formatRows, getStageStateColor, truncateString} from "../utils"; +import {initializeGraph, initializeSvg} from "../d3utils"; import {QueryHeader} from "./QueryHeader"; type StageStatisticsProps = { @@ -359,3 +360,5 @@ export class LivePlan extends React.Component { ); } } + +export default LivePlan; \ No newline at end of file diff --git a/presto-ui/src/components/QueryDetail.jsx b/presto-ui/src/components/QueryDetail.jsx index f584864e0d8b7..22f447d8f1327 100644 --- a/presto-ui/src/components/QueryDetail.jsx +++ b/presto-ui/src/components/QueryDetail.jsx @@ -1706,3 +1706,5 @@ export class QueryDetail extends React.Component { ); } } + +export default QueryDetail; \ No newline at end of file diff --git a/presto-ui/src/components/QueryList.jsx b/presto-ui/src/components/QueryList.jsx index 95a71a99e99a0..0a16757c5baf1 100644 --- a/presto-ui/src/components/QueryList.jsx +++ b/presto-ui/src/components/QueryList.jsx @@ -718,3 +718,4 @@ export class QueryList extends React.Component { } } +export default QueryList; \ No newline at end of file diff --git a/presto-ui/src/components/QueryPlanView.jsx b/presto-ui/src/components/QueryPlanView.jsx index 9159527a03131..3df228700cb75 100644 --- a/presto-ui/src/components/QueryPlanView.jsx +++ b/presto-ui/src/components/QueryPlanView.jsx @@ -20,7 +20,8 @@ import { StageStatistics, PlanNode } from './LivePlan'; import ReactDOMServer from "react-dom/server"; import * as dagreD3 from "dagre-d3"; import * as d3 from "d3"; -import { formatRows, getStageStateColor, initializeGraph } from "../utils"; +import { formatRows, getStageStateColor } from "../utils"; +import { initializeGraph } from "../d3utils"; export default function PlanView({show, data}) { const widgets = React.useRef({ diff --git a/presto-ui/src/components/QueryStageView.jsx b/presto-ui/src/components/QueryStageView.jsx index 7d9ceac924727..eff4554eaffaa 100644 --- a/presto-ui/src/components/QueryStageView.jsx +++ b/presto-ui/src/components/QueryStageView.jsx @@ -26,10 +26,10 @@ import { formatDuration, getChildren, getTaskNumber, - initializeGraph, parseDataSize, parseDuration } from "../utils"; +import { initializeGraph } from '../d3utils'; function getTotalWallTime(operator) { return parseDuration(operator.addInputWall) + diff --git a/presto-ui/src/components/QueryViewer.jsx b/presto-ui/src/components/QueryViewer.jsx index a2c04ba473c5f..baa1f05fa9733 100644 --- a/presto-ui/src/components/QueryViewer.jsx +++ b/presto-ui/src/components/QueryViewer.jsx @@ -88,4 +88,6 @@ export function QueryViewer() { ); -} \ No newline at end of file +} + +export default QueryViewer; \ No newline at end of file diff --git a/presto-ui/src/components/SQLInput.jsx b/presto-ui/src/components/SQLInput.jsx index 2942f7fe31641..8c0edd4ef7ed1 100644 --- a/presto-ui/src/components/SQLInput.jsx +++ b/presto-ui/src/components/SQLInput.jsx @@ -20,7 +20,9 @@ import SqlBaseListener from '../sql-parser/SqlBaseListener.js'; import Editor from 'react-simple-code-editor'; import { highlight, languages } from 'prismjs/components/prism-core'; import 'prismjs/components/prism-sql'; -import 'prismjs/themes/prism-okaidia.css'; +// Remove primsjs theme to avoid loading error with dynamic import +// move import 'prismjs/themes/prism.css' to sql-client.jsx +// import 'prismjs/themes/prism-okaidia.css'; import { clsx } from 'clsx'; import PrestoClient from "@prestodb/presto-js-client"; diff --git a/presto-ui/src/components/StageDetail.jsx b/presto-ui/src/components/StageDetail.jsx index b940ddc53e5d6..efec6659ba959 100644 --- a/presto-ui/src/components/StageDetail.jsx +++ b/presto-ui/src/components/StageDetail.jsx @@ -25,12 +25,11 @@ import { getChildren, getFirstParameter, getTaskNumber, - initializeGraph, - initializeSvg, isQueryEnded, parseDataSize, parseDuration } from "../utils"; +import { initializeGraph, initializeSvg } from "../d3utils"; import {QueryHeader} from "./QueryHeader"; function getTotalWallTime(operator) { @@ -643,3 +642,5 @@ export class StageDetail extends React.Component { ); } } + +export default StageDetail; \ No newline at end of file diff --git a/presto-ui/src/components/WorkerStatus.jsx b/presto-ui/src/components/WorkerStatus.jsx index d31759ef57461..4234d904c5aa9 100644 --- a/presto-ui/src/components/WorkerStatus.jsx +++ b/presto-ui/src/components/WorkerStatus.jsx @@ -426,3 +426,5 @@ export class WorkerStatus extends React.Component { ); } } + +export default WorkerStatus; \ No newline at end of file diff --git a/presto-ui/src/components/WorkerThreadList.jsx b/presto-ui/src/components/WorkerThreadList.jsx index 3e303008934f8..babc817364ff9 100644 --- a/presto-ui/src/components/WorkerThreadList.jsx +++ b/presto-ui/src/components/WorkerThreadList.jsx @@ -281,3 +281,5 @@ export class WorkerThreadList extends React.Component { ); } } + +export default WorkerThreadList; \ No newline at end of file diff --git a/presto-ui/src/d3utils.js b/presto-ui/src/d3utils.js new file mode 100644 index 0000000000000..7cba2d33e65f5 --- /dev/null +++ b/presto-ui/src/d3utils.js @@ -0,0 +1,34 @@ +/* + * Licensed 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 + * + * http://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. + */ + +import * as dagreD3 from "dagre-d3"; +import * as d3 from "d3"; + +// DagreD3 Graph-related functions +// =============================== + +export function initializeGraph(): any +{ + return new dagreD3.graphlib.Graph({compound: true}) + .setGraph({rankdir: 'BT'}) + .setDefaultEdgeLabel(function () { return {}; }); +} + +export function initializeSvg(selector: any): any +{ + const svg = d3.select(selector); + svg.append("g"); + + return svg; +} diff --git a/presto-ui/src/embedded_plan.jsx b/presto-ui/src/embedded_plan.jsx index 26834cfd342a8..ac340d2ea5597 100644 --- a/presto-ui/src/embedded_plan.jsx +++ b/presto-ui/src/embedded_plan.jsx @@ -1,7 +1,9 @@ import React from "react"; import ReactDOM from "react-dom"; -import {LivePlan} from "./components/LivePlan"; import {getFirstParameter} from "./utils"; +import lazy from "./lazy"; + +const LivePlan = lazy('LivePlan'); ReactDOM.render( , diff --git a/presto-ui/src/index.jsx b/presto-ui/src/index.jsx index e52b8ea2ccff2..2917fa2e2de7e 100644 --- a/presto-ui/src/index.jsx +++ b/presto-ui/src/index.jsx @@ -1,9 +1,11 @@ import React from "react"; import ReactDOM from "react-dom"; -import {ClusterHUD} from "./components/ClusterHUD"; -import {QueryList} from "./components/QueryList"; +import lazy from "./lazy"; import { PageTitle } from "./components/PageTitle"; +const ClusterHUD = lazy('ClusterHUD'); +const QueryList = lazy('QueryList'); + ReactDOM.render( , document.getElementById('title') diff --git a/presto-ui/src/lazy.jsx b/presto-ui/src/lazy.jsx new file mode 100644 index 0000000000000..b26bf615b562b --- /dev/null +++ b/presto-ui/src/lazy.jsx @@ -0,0 +1,27 @@ +/* + * Licensed 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 + * + * http://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. + */ + +import React, { Suspense, lazy } from 'react'; + +const LazyComponent = (filename: string) => { + const Component = lazy(() => import(`./components/${filename}`)); + const LazyWrapper = (props: any) =>( + Loading...}> + + + ); + return LazyWrapper; +} + +export default LazyComponent \ No newline at end of file diff --git a/presto-ui/src/plan.jsx b/presto-ui/src/plan.jsx index ac8da3d5b33a8..f32195f1e6581 100644 --- a/presto-ui/src/plan.jsx +++ b/presto-ui/src/plan.jsx @@ -1,9 +1,11 @@ import React from "react"; import ReactDOM from "react-dom"; -import {LivePlan} from "./components/LivePlan"; +import lazy from "./lazy"; import {PageTitle} from "./components/PageTitle"; import {getFirstParameter} from "./utils"; +const LivePlan = lazy('LivePlan'); + ReactDOM.render( , document.getElementById('title') diff --git a/presto-ui/src/query.jsx b/presto-ui/src/query.jsx index 6b11aa91272d7..b4dda101e18fb 100644 --- a/presto-ui/src/query.jsx +++ b/presto-ui/src/query.jsx @@ -1,8 +1,10 @@ import React from "react"; import ReactDOM from "react-dom"; -import {QueryDetail} from "./components/QueryDetail"; +import lazy from "./lazy"; import {PageTitle} from "./components/PageTitle"; +const QueryDetail = lazy('QueryDetail'); + ReactDOM.render( , document.getElementById('title') diff --git a/presto-ui/src/query_viewer.jsx b/presto-ui/src/query_viewer.jsx index 18150e7a0d12f..c86e4823d1f71 100644 --- a/presto-ui/src/query_viewer.jsx +++ b/presto-ui/src/query_viewer.jsx @@ -1,7 +1,9 @@ import { createRoot } from 'react-dom/client'; -import { QueryViewer } from "./components/QueryViewer"; +import lazy from "./lazy"; import { PageTitle } from "./components/PageTitle"; +const QueryViewer = lazy('QueryViewer'); + const title = createRoot(document.getElementById('title')); title.render(); diff --git a/presto-ui/src/res_groups.jsx b/presto-ui/src/res_groups.jsx index 5fcf9d9736553..6cee38b83883f 100644 --- a/presto-ui/src/res_groups.jsx +++ b/presto-ui/src/res_groups.jsx @@ -1,6 +1,8 @@ import { createRoot } from 'react-dom/client'; -import ResourceGroupView from "./components/ResourceGroupView"; import { PageTitle } from "./components/PageTitle"; +import lazy from "./lazy"; + +const ResourceGroupView = lazy('ResourceGroupView'); const title = createRoot(document.getElementById('title')); title.render(); diff --git a/presto-ui/src/sql_client.jsx b/presto-ui/src/sql_client.jsx index 629567af38bc5..298db5f963c2c 100644 --- a/presto-ui/src/sql_client.jsx +++ b/presto-ui/src/sql_client.jsx @@ -1,6 +1,9 @@ import { createRoot } from 'react-dom/client'; -import SQLClientView from "./components/SQLClient"; import { PageTitle } from "./components/PageTitle"; +import 'prismjs/themes/prism-okaidia.css'; +import lazy from "./lazy"; + +const SQLClientView = lazy('SQLClient'); const title = createRoot(document.getElementById('title')); title.render(); diff --git a/presto-ui/src/stage.jsx b/presto-ui/src/stage.jsx index 94794efbc01ab..47b77287b337d 100644 --- a/presto-ui/src/stage.jsx +++ b/presto-ui/src/stage.jsx @@ -1,7 +1,9 @@ import React from "react"; import ReactDOM from "react-dom"; -import {StageDetail} from "./components/StageDetail"; import {PageTitle} from "./components/PageTitle"; +import lazy from "./lazy"; + +const StageDetail = lazy('StageDetail'); ReactDOM.render( , diff --git a/presto-ui/src/timeline.jsx b/presto-ui/src/timeline.jsx index f4a6548c60a58..2ad5b6062a792 100644 --- a/presto-ui/src/timeline.jsx +++ b/presto-ui/src/timeline.jsx @@ -1,6 +1,8 @@ -import Splits from "./components/Splits"; import { PageTitle } from "./components/PageTitle"; import { createRoot } from 'react-dom/client'; +import lazy from "./lazy"; + +const Splits = lazy('Splits'); const title = createRoot(document.getElementById('title')); title.render(); diff --git a/presto-ui/src/utils.js b/presto-ui/src/utils.js index 0deaca252ca2b..9aeddcb70e481 100644 --- a/presto-ui/src/utils.js +++ b/presto-ui/src/utils.js @@ -13,9 +13,6 @@ */ //@flow -import * as dagreD3 from "dagre-d3"; -import * as d3 from "d3"; - // Query display // ============= @@ -196,24 +193,6 @@ export function addExponentiallyWeightedToHistory (value: number, valuesArray: n return valuesArray.concat([movingAverage]).slice(Math.max(valuesArray.length - MAX_HISTORY, 0)); } -// DagreD3 Graph-related functions -// =============================== - -export function initializeGraph(): any -{ - return new dagreD3.graphlib.Graph({compound: true}) - .setGraph({rankdir: 'BT'}) - .setDefaultEdgeLabel(function () { return {}; }); -} - -export function initializeSvg(selector: any): any -{ - const svg = d3.select(selector); - svg.append("g"); - - return svg; -} - export function getChildren(nodeInfo: any): any[] { // TODO: Remove this function by migrating StageDetail to use node JSON representation diff --git a/presto-ui/src/webpack.config.js b/presto-ui/src/webpack.config.js index 1cb6b3d7ed282..00f4ad37eab0c 100644 --- a/presto-ui/src/webpack.config.js +++ b/presto-ui/src/webpack.config.js @@ -13,16 +13,16 @@ module.exports = (env) => { const outputDir = 'target/webapp'; return { entry: { - 'index': path.join(__dirname, 'index.jsx'), - 'query': path.join(__dirname, 'query.jsx'), - 'plan': path.join(__dirname, 'plan.jsx'), - 'query_viewer': {import: path.join(__dirname, 'query_viewer.jsx'), filename: path.join(outputDir, 'dev', '[name].js')}, - 'embedded_plan': path.join(__dirname, 'embedded_plan.jsx'), - 'stage': path.join(__dirname, 'stage.jsx'), - 'worker': path.join(__dirname, 'worker.jsx'), - 'timeline': path.join(__dirname, 'timeline.jsx'), - 'res_groups': path.join(__dirname, 'res_groups.jsx'), - 'sql_client': path.join(__dirname, 'sql_client.jsx'), + 'index': './index.jsx', + 'query': './query.jsx', + 'plan': './plan.jsx', + 'query_viewer': {import: './query_viewer.jsx', filename: path.join(outputDir, 'dev', '[name].js')}, + 'embedded_plan': './embedded_plan.jsx', + 'stage': './stage.jsx', + 'worker': './worker.jsx', + 'timeline': './timeline.jsx', + 'res_groups': './res_groups.jsx', + 'sql_client': './sql_client.jsx', 'bootstrap_css': path.join(__dirname, 'static', 'vendor', 'bootstrap', 'css', 'bootstrap.min.external-fonts.css'), 'css_loader': path.join(__dirname, 'static', 'vendor', 'css-loaders', 'loader.css'), 'css_presto': path.join(__dirname, 'static', 'assets', 'presto.css'), @@ -34,7 +34,7 @@ module.exports = (env) => { plugins: [ new CopyPlugin({ patterns: [ - {from: "static", to: outputDir}, + {from: "static", to: path.join(__dirname, "..", outputDir)}, ] }), new HtmlWebpackPlugin({ @@ -82,8 +82,9 @@ module.exports = (env) => { extensions: ['.*', '.js', '.jsx'] }, output: { - path: path.join(__dirname, '..'), - filename: path.join(outputDir, '[name].js'), + path: path.join(__dirname, '..', outputDir), + filename: '[name].js', + chunkFilename: '[name].chunk.js', }, optimization: { minimize: mode === 'production', @@ -98,6 +99,24 @@ module.exports = (env) => { extractComments: false, }), '...'], + splitChunks: { + chunks: 'async', + maxSize: 244000, + minRemainingSize: 0, + minChunks: 1, + cacheGroups: { + defaultVendors: { + test: /[\\/]node_modules[\\/]/, + priority: -10, + reuseExistingChunk: true, + }, + default: { + minChunks: 2, + priority: -20, + reuseExistingChunk: true, + }, + }, + }, }, devServer: { static: { diff --git a/presto-ui/src/worker.jsx b/presto-ui/src/worker.jsx index e53ba842acf69..2409b87a73f97 100644 --- a/presto-ui/src/worker.jsx +++ b/presto-ui/src/worker.jsx @@ -1,9 +1,11 @@ import React from "react"; import ReactDOM from "react-dom"; -import {WorkerStatus} from "./components/WorkerStatus"; -import {WorkerThreadList} from "./components/WorkerThreadList"; +import lazy from "./lazy"; import {PageTitle} from "./components/PageTitle"; +const WorkerStatus = lazy('WorkerStatus'); +const WorkerThreadList = lazy('WorkerThreadList'); + ReactDOM.render( , document.getElementById('title')