From 63b98bff4d991a26b3a5dce881afbb870e54d737 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:18:50 -0500 Subject: [PATCH 1/9] soapbox.tsx: load some components async, reduce bundle size --- src/containers/soapbox.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/containers/soapbox.tsx b/src/containers/soapbox.tsx index d60f8eec0..eab298e34 100644 --- a/src/containers/soapbox.tsx +++ b/src/containers/soapbox.tsx @@ -13,11 +13,8 @@ import { loadInstance } from 'soapbox/actions/instance'; import { fetchMe } from 'soapbox/actions/me'; import { loadSoapboxConfig } from 'soapbox/actions/soapbox'; import * as BuildConfig from 'soapbox/build-config'; -import GdprBanner from 'soapbox/components/gdpr-banner'; -import Helmet from 'soapbox/components/helmet'; import LoadingScreen from 'soapbox/components/loading-screen'; import { StatProvider } from 'soapbox/contexts/stat-context'; -import EmbeddedStatus from 'soapbox/features/embedded-status'; import { ModalContainer, OnboardingWizard, @@ -42,9 +39,13 @@ import { generateThemeCss } from 'soapbox/utils/theme'; import { checkOnboardingStatus } from '../actions/onboarding'; import { preload } from '../actions/preload'; import ErrorBoundary from '../components/error-boundary'; -import UI from '../features/ui'; import { store } from '../store'; +const GdprBanner = React.lazy(() => import('soapbox/components/gdpr-banner')); +const Helmet = React.lazy(() => import('soapbox/components/helmet')); +const EmbeddedStatus = React.lazy(() => import('soapbox/features/embedded-status')); +const UI = React.lazy(() => import('soapbox/features/ui')); + // Configure global functions for developers createGlobals(store); From e229c4e2f199274b2f45124d8b5ae0455c2c4ac6 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:22:33 -0500 Subject: [PATCH 2/9] Make entrypoint extremely small! --- src/main.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.tsx b/src/main.tsx index 33b325dab..cd586aa25 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -22,10 +22,11 @@ import './styles/application.scss'; import './styles/tailwind.css'; import './precheck'; -import { default as Soapbox } from './containers/soapbox'; import ready from './ready'; import { registerSW } from './utils/sw'; +const Soapbox = React.lazy(() => import('./containers/soapbox')); + if (BuildConfig.NODE_ENV === 'production') { printConsoleWarning(); registerSW('/sw.js'); From e37b24ffe3213e6e4acf701703c56ae33bd7b8d6 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:37:19 -0500 Subject: [PATCH 3/9] Move SoapboxLoad into a separate file --- src/containers/soapbox-load.tsx | 99 +++++++++++++++++++++++++++++++++ src/containers/soapbox.tsx | 91 +----------------------------- 2 files changed, 102 insertions(+), 88 deletions(-) create mode 100644 src/containers/soapbox-load.tsx diff --git a/src/containers/soapbox-load.tsx b/src/containers/soapbox-load.tsx new file mode 100644 index 000000000..3ce9d29d4 --- /dev/null +++ b/src/containers/soapbox-load.tsx @@ -0,0 +1,99 @@ +import React, { useState, useEffect } from 'react'; +import { IntlProvider } from 'react-intl'; + +import { loadInstance } from 'soapbox/actions/instance'; +import { fetchMe } from 'soapbox/actions/me'; +import { loadSoapboxConfig } from 'soapbox/actions/soapbox'; +import LoadingScreen from 'soapbox/components/loading-screen'; +import { createGlobals } from 'soapbox/globals'; +import { + useAppSelector, + useAppDispatch, + useOwnAccount, + useLocale, +} from 'soapbox/hooks'; +import MESSAGES from 'soapbox/messages'; + +import { checkOnboardingStatus } from '../actions/onboarding'; +import { preload } from '../actions/preload'; +import { store } from '../store'; + +// Configure global functions for developers +createGlobals(store); + +// Preload happens synchronously +store.dispatch(preload() as any); + +// This happens synchronously +store.dispatch(checkOnboardingStatus() as any); + +/** Load initial data from the backend */ +const loadInitial = () => { + // @ts-ignore + return async(dispatch, getState) => { + // Await for authenticated fetch + await dispatch(fetchMe()); + // Await for feature detection + await dispatch(loadInstance()); + // Await for configuration + await dispatch(loadSoapboxConfig()); + }; +}; + +interface ISoapboxLoad { + children: React.ReactNode; +} + +/** Initial data loader. */ +const SoapboxLoad: React.FC = ({ children }) => { + const dispatch = useAppDispatch(); + + const me = useAppSelector(state => state.me); + const { account } = useOwnAccount(); + const swUpdating = useAppSelector(state => state.meta.swUpdating); + const { locale } = useLocale(); + + const [messages, setMessages] = useState>({}); + const [localeLoading, setLocaleLoading] = useState(true); + const [isLoaded, setIsLoaded] = useState(false); + + /** Whether to display a loading indicator. */ + const showLoading = [ + me === null, + me && !account, + !isLoaded, + localeLoading, + swUpdating, + ].some(Boolean); + + // Load the user's locale + useEffect(() => { + MESSAGES[locale]().then(messages => { + setMessages(messages); + setLocaleLoading(false); + }).catch(() => { }); + }, [locale]); + + // Load initial data from the API + useEffect(() => { + dispatch(loadInitial()).then(() => { + setIsLoaded(true); + }).catch(() => { + setIsLoaded(true); + }); + }, []); + + // intl is part of loading. + // It's important nothing in here depends on intl. + if (showLoading) { + return ; + } + + return ( + + {children} + + ); +}; + +export default SoapboxLoad; diff --git a/src/containers/soapbox.tsx b/src/containers/soapbox.tsx index eab298e34..84ba16831 100644 --- a/src/containers/soapbox.tsx +++ b/src/containers/soapbox.tsx @@ -1,17 +1,13 @@ import { QueryClientProvider } from '@tanstack/react-query'; import clsx from 'clsx'; -import React, { useState, useEffect, Suspense } from 'react'; +import React, { Suspense } from 'react'; import { Toaster } from 'react-hot-toast'; -import { IntlProvider } from 'react-intl'; import { Provider } from 'react-redux'; import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom'; import { CompatRouter } from 'react-router-dom-v5-compat'; // @ts-ignore: it doesn't have types import { ScrollContext } from 'react-router-scroll-4'; -import { loadInstance } from 'soapbox/actions/instance'; -import { fetchMe } from 'soapbox/actions/me'; -import { loadSoapboxConfig } from 'soapbox/actions/soapbox'; import * as BuildConfig from 'soapbox/build-config'; import LoadingScreen from 'soapbox/components/loading-screen'; import { StatProvider } from 'soapbox/contexts/stat-context'; @@ -19,10 +15,8 @@ import { ModalContainer, OnboardingWizard, } from 'soapbox/features/ui/util/async-components'; -import { createGlobals } from 'soapbox/globals'; import { useAppSelector, - useAppDispatch, useOwnAccount, useSentry, useSettings, @@ -30,44 +24,21 @@ import { useTheme, useLocale, } from 'soapbox/hooks'; -import MESSAGES from 'soapbox/messages'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; import { queryClient } from 'soapbox/queries/client'; import { useCachedLocationHandler } from 'soapbox/utils/redirect'; import { generateThemeCss } from 'soapbox/utils/theme'; -import { checkOnboardingStatus } from '../actions/onboarding'; -import { preload } from '../actions/preload'; import ErrorBoundary from '../components/error-boundary'; import { store } from '../store'; +import SoapboxLoad from './soapbox-load'; + const GdprBanner = React.lazy(() => import('soapbox/components/gdpr-banner')); const Helmet = React.lazy(() => import('soapbox/components/helmet')); const EmbeddedStatus = React.lazy(() => import('soapbox/features/embedded-status')); const UI = React.lazy(() => import('soapbox/features/ui')); -// Configure global functions for developers -createGlobals(store); - -// Preload happens synchronously -store.dispatch(preload() as any); - -// This happens synchronously -store.dispatch(checkOnboardingStatus() as any); - -/** Load initial data from the backend */ -const loadInitial = () => { - // @ts-ignore - return async(dispatch, getState) => { - // Await for authenticated fetch - await dispatch(fetchMe()); - // Await for feature detection - await dispatch(loadInstance()); - // Await for configuration - await dispatch(loadSoapboxConfig()); - }; -}; - /** Highest level node with the Redux store. */ const SoapboxMount = () => { useCachedLocationHandler(); @@ -146,62 +117,6 @@ const SoapboxMount = () => { ); }; -interface ISoapboxLoad { - children: React.ReactNode; -} - -/** Initial data loader. */ -const SoapboxLoad: React.FC = ({ children }) => { - const dispatch = useAppDispatch(); - - const me = useAppSelector(state => state.me); - const { account } = useOwnAccount(); - const swUpdating = useAppSelector(state => state.meta.swUpdating); - const { locale } = useLocale(); - - const [messages, setMessages] = useState>({}); - const [localeLoading, setLocaleLoading] = useState(true); - const [isLoaded, setIsLoaded] = useState(false); - - /** Whether to display a loading indicator. */ - const showLoading = [ - me === null, - me && !account, - !isLoaded, - localeLoading, - swUpdating, - ].some(Boolean); - - // Load the user's locale - useEffect(() => { - MESSAGES[locale]().then(messages => { - setMessages(messages); - setLocaleLoading(false); - }).catch(() => { }); - }, [locale]); - - // Load initial data from the API - useEffect(() => { - dispatch(loadInitial()).then(() => { - setIsLoaded(true); - }).catch(() => { - setIsLoaded(true); - }); - }, []); - - // intl is part of loading. - // It's important nothing in here depends on intl. - if (showLoading) { - return ; - } - - return ( - - {children} - - ); -}; - interface ISoapboxHead { children: React.ReactNode; } From 111428f46d1af3c49e49a96905aca2a56ffa6e41 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:39:37 -0500 Subject: [PATCH 4/9] Move SoapboxMount into a separate file --- src/containers/soapbox-mount.tsx | 105 +++++++++++++++++++++++++++++++ src/containers/soapbox.tsx | 100 +---------------------------- 2 files changed, 107 insertions(+), 98 deletions(-) create mode 100644 src/containers/soapbox-mount.tsx diff --git a/src/containers/soapbox-mount.tsx b/src/containers/soapbox-mount.tsx new file mode 100644 index 000000000..bbc911691 --- /dev/null +++ b/src/containers/soapbox-mount.tsx @@ -0,0 +1,105 @@ +import React, { Suspense } from 'react'; +import { Toaster } from 'react-hot-toast'; +import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom'; +import { CompatRouter } from 'react-router-dom-v5-compat'; +// @ts-ignore: it doesn't have types +import { ScrollContext } from 'react-router-scroll-4'; + +import * as BuildConfig from 'soapbox/build-config'; +import LoadingScreen from 'soapbox/components/loading-screen'; +import { + ModalContainer, + OnboardingWizard, +} from 'soapbox/features/ui/util/async-components'; +import { + useAppSelector, + useOwnAccount, + useSoapboxConfig, +} from 'soapbox/hooks'; +import { useCachedLocationHandler } from 'soapbox/utils/redirect'; + +import ErrorBoundary from '../components/error-boundary'; + +const GdprBanner = React.lazy(() => import('soapbox/components/gdpr-banner')); +const EmbeddedStatus = React.lazy(() => import('soapbox/features/embedded-status')); +const UI = React.lazy(() => import('soapbox/features/ui')); + +/** Highest level node with the Redux store. */ +const SoapboxMount = () => { + useCachedLocationHandler(); + + const me = useAppSelector(state => state.me); + const { account } = useOwnAccount(); + const soapboxConfig = useSoapboxConfig(); + + const needsOnboarding = useAppSelector(state => state.onboarding.needsOnboarding); + const showOnboarding = account && needsOnboarding; + const { redirectRootNoLogin } = soapboxConfig; + + // @ts-ignore: I don't actually know what these should be, lol + const shouldUpdateScroll = (prevRouterProps, { location }) => { + return !(location.state?.soapboxModalKey && location.state?.soapboxModalKey !== prevRouterProps?.location?.state?.soapboxModalKey); + }; + + /** Render the onboarding flow. */ + const renderOnboarding = () => ( + }> + + + ); + + /** Render the auth layout or UI. */ + const renderSwitch = () => ( + + {(!me && redirectRootNoLogin) && ( + + )} + + + + ); + + /** Render the onboarding flow or UI. */ + const renderBody = () => { + if (showOnboarding) { + return renderOnboarding(); + } else { + return renderSwitch(); + } + }; + + return ( + + + + + + } + /> + + + + {renderBody()} + + + + +
+ +
+
+
+
+
+
+
+ ); +}; + +export default SoapboxMount; diff --git a/src/containers/soapbox.tsx b/src/containers/soapbox.tsx index 84ba16831..63cfb3d9e 100644 --- a/src/containers/soapbox.tsx +++ b/src/containers/soapbox.tsx @@ -1,23 +1,10 @@ import { QueryClientProvider } from '@tanstack/react-query'; import clsx from 'clsx'; -import React, { Suspense } from 'react'; -import { Toaster } from 'react-hot-toast'; +import React from 'react'; import { Provider } from 'react-redux'; -import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom'; -import { CompatRouter } from 'react-router-dom-v5-compat'; -// @ts-ignore: it doesn't have types -import { ScrollContext } from 'react-router-scroll-4'; -import * as BuildConfig from 'soapbox/build-config'; -import LoadingScreen from 'soapbox/components/loading-screen'; import { StatProvider } from 'soapbox/contexts/stat-context'; import { - ModalContainer, - OnboardingWizard, -} from 'soapbox/features/ui/util/async-components'; -import { - useAppSelector, - useOwnAccount, useSentry, useSettings, useSoapboxConfig, @@ -26,97 +13,14 @@ import { } from 'soapbox/hooks'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; import { queryClient } from 'soapbox/queries/client'; -import { useCachedLocationHandler } from 'soapbox/utils/redirect'; import { generateThemeCss } from 'soapbox/utils/theme'; -import ErrorBoundary from '../components/error-boundary'; import { store } from '../store'; import SoapboxLoad from './soapbox-load'; +import SoapboxMount from './soapbox-mount'; -const GdprBanner = React.lazy(() => import('soapbox/components/gdpr-banner')); const Helmet = React.lazy(() => import('soapbox/components/helmet')); -const EmbeddedStatus = React.lazy(() => import('soapbox/features/embedded-status')); -const UI = React.lazy(() => import('soapbox/features/ui')); - -/** Highest level node with the Redux store. */ -const SoapboxMount = () => { - useCachedLocationHandler(); - - const me = useAppSelector(state => state.me); - const { account } = useOwnAccount(); - const soapboxConfig = useSoapboxConfig(); - - const needsOnboarding = useAppSelector(state => state.onboarding.needsOnboarding); - const showOnboarding = account && needsOnboarding; - const { redirectRootNoLogin } = soapboxConfig; - - // @ts-ignore: I don't actually know what these should be, lol - const shouldUpdateScroll = (prevRouterProps, { location }) => { - return !(location.state?.soapboxModalKey && location.state?.soapboxModalKey !== prevRouterProps?.location?.state?.soapboxModalKey); - }; - - /** Render the onboarding flow. */ - const renderOnboarding = () => ( - }> - - - ); - - /** Render the auth layout or UI. */ - const renderSwitch = () => ( - - {(!me && redirectRootNoLogin) && ( - - )} - - - - ); - - /** Render the onboarding flow or UI. */ - const renderBody = () => { - if (showOnboarding) { - return renderOnboarding(); - } else { - return renderSwitch(); - } - }; - - return ( - - - - - - } - /> - - - - {renderBody()} - - - - -
- -
-
-
-
-
-
-
- ); -}; - interface ISoapboxHead { children: React.ReactNode; } From 76578c64c535e40eddcf3a7a719a34a4e64a02b9 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:41:39 -0500 Subject: [PATCH 5/9] Move SoapboxHead into a separate file --- src/containers/soapbox-head.tsx | 53 +++++++++++++++++++++++++++++++++ src/containers/soapbox.tsx | 49 +----------------------------- 2 files changed, 54 insertions(+), 48 deletions(-) create mode 100644 src/containers/soapbox-head.tsx diff --git a/src/containers/soapbox-head.tsx b/src/containers/soapbox-head.tsx new file mode 100644 index 000000000..0039404e0 --- /dev/null +++ b/src/containers/soapbox-head.tsx @@ -0,0 +1,53 @@ +import clsx from 'clsx'; +import React from 'react'; + +import { + useSentry, + useSettings, + useSoapboxConfig, + useTheme, + useLocale, +} from 'soapbox/hooks'; +import { normalizeSoapboxConfig } from 'soapbox/normalizers'; +import { generateThemeCss } from 'soapbox/utils/theme'; + +const Helmet = React.lazy(() => import('soapbox/components/helmet')); + +interface ISoapboxHead { + children: React.ReactNode; +} + +/** Injects metadata into site head with Helmet. */ +const SoapboxHead: React.FC = ({ children }) => { + const { locale, direction } = useLocale(); + const settings = useSettings(); + const soapboxConfig = useSoapboxConfig(); + + const demo = !!settings.get('demo'); + const darkMode = useTheme() === 'dark'; + const themeCss = generateThemeCss(demo ? normalizeSoapboxConfig({ brandColor: '#0482d8' }) : soapboxConfig); + + const bodyClass = clsx('h-full bg-white text-base dark:bg-gray-800', { + 'no-reduce-motion': !settings.get('reduceMotion'), + 'underline-links': settings.get('underlineLinks'), + 'demetricator': settings.get('demetricator'), + }); + + useSentry(soapboxConfig.sentryDsn); + + return ( + <> + + + + {themeCss && } + {darkMode && } + + + + {children} + + ); +}; + +export default SoapboxHead; diff --git a/src/containers/soapbox.tsx b/src/containers/soapbox.tsx index 63cfb3d9e..5877cbd88 100644 --- a/src/containers/soapbox.tsx +++ b/src/containers/soapbox.tsx @@ -1,63 +1,16 @@ import { QueryClientProvider } from '@tanstack/react-query'; -import clsx from 'clsx'; import React from 'react'; import { Provider } from 'react-redux'; import { StatProvider } from 'soapbox/contexts/stat-context'; -import { - useSentry, - useSettings, - useSoapboxConfig, - useTheme, - useLocale, -} from 'soapbox/hooks'; -import { normalizeSoapboxConfig } from 'soapbox/normalizers'; import { queryClient } from 'soapbox/queries/client'; -import { generateThemeCss } from 'soapbox/utils/theme'; import { store } from '../store'; +import SoapboxHead from './soapbox-head'; import SoapboxLoad from './soapbox-load'; import SoapboxMount from './soapbox-mount'; -const Helmet = React.lazy(() => import('soapbox/components/helmet')); -interface ISoapboxHead { - children: React.ReactNode; -} - -/** Injects metadata into site head with Helmet. */ -const SoapboxHead: React.FC = ({ children }) => { - const { locale, direction } = useLocale(); - const settings = useSettings(); - const soapboxConfig = useSoapboxConfig(); - - const demo = !!settings.get('demo'); - const darkMode = useTheme() === 'dark'; - const themeCss = generateThemeCss(demo ? normalizeSoapboxConfig({ brandColor: '#0482d8' }) : soapboxConfig); - - const bodyClass = clsx('h-full bg-white text-base dark:bg-gray-800', { - 'no-reduce-motion': !settings.get('reduceMotion'), - 'underline-links': settings.get('underlineLinks'), - 'demetricator': settings.get('demetricator'), - }); - - useSentry(soapboxConfig.sentryDsn); - - return ( - <> - - - - {themeCss && } - {darkMode && } - - - - {children} - - ); -}; - /** The root React node of the application. */ const Soapbox: React.FC = () => { return ( From ed11c2bc2dddf3eba34387dcedeb7fc811516680 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:45:32 -0500 Subject: [PATCH 6/9] Move some top-level code from soapbox-load back into soapbox.tsx where it belongs --- src/containers/soapbox-load.tsx | 14 -------------- src/containers/soapbox.tsx | 12 ++++++++++++ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/containers/soapbox-load.tsx b/src/containers/soapbox-load.tsx index 3ce9d29d4..4c88f2a7e 100644 --- a/src/containers/soapbox-load.tsx +++ b/src/containers/soapbox-load.tsx @@ -5,7 +5,6 @@ import { loadInstance } from 'soapbox/actions/instance'; import { fetchMe } from 'soapbox/actions/me'; import { loadSoapboxConfig } from 'soapbox/actions/soapbox'; import LoadingScreen from 'soapbox/components/loading-screen'; -import { createGlobals } from 'soapbox/globals'; import { useAppSelector, useAppDispatch, @@ -14,19 +13,6 @@ import { } from 'soapbox/hooks'; import MESSAGES from 'soapbox/messages'; -import { checkOnboardingStatus } from '../actions/onboarding'; -import { preload } from '../actions/preload'; -import { store } from '../store'; - -// Configure global functions for developers -createGlobals(store); - -// Preload happens synchronously -store.dispatch(preload() as any); - -// This happens synchronously -store.dispatch(checkOnboardingStatus() as any); - /** Load initial data from the backend */ const loadInitial = () => { // @ts-ignore diff --git a/src/containers/soapbox.tsx b/src/containers/soapbox.tsx index 5877cbd88..e8b657d28 100644 --- a/src/containers/soapbox.tsx +++ b/src/containers/soapbox.tsx @@ -3,14 +3,26 @@ import React from 'react'; import { Provider } from 'react-redux'; import { StatProvider } from 'soapbox/contexts/stat-context'; +import { createGlobals } from 'soapbox/globals'; import { queryClient } from 'soapbox/queries/client'; +import { checkOnboardingStatus } from '../actions/onboarding'; +import { preload } from '../actions/preload'; import { store } from '../store'; import SoapboxHead from './soapbox-head'; import SoapboxLoad from './soapbox-load'; import SoapboxMount from './soapbox-mount'; +// Configure global functions for developers +createGlobals(store); + +// Preload happens synchronously +store.dispatch(preload() as any); + +// This happens synchronously +store.dispatch(checkOnboardingStatus() as any); + /** The root React node of the application. */ const Soapbox: React.FC = () => { return ( From 69d2911ee469af62a739e4772098706f3097b41f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:48:54 -0500 Subject: [PATCH 7/9] CHUNK ALL THE THINGS!!! --- src/containers/soapbox.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/containers/soapbox.tsx b/src/containers/soapbox.tsx index e8b657d28..b63e42f3b 100644 --- a/src/containers/soapbox.tsx +++ b/src/containers/soapbox.tsx @@ -10,9 +10,9 @@ import { checkOnboardingStatus } from '../actions/onboarding'; import { preload } from '../actions/preload'; import { store } from '../store'; -import SoapboxHead from './soapbox-head'; -import SoapboxLoad from './soapbox-load'; -import SoapboxMount from './soapbox-mount'; +const SoapboxHead = React.lazy(() => import('./soapbox-head')); +const SoapboxLoad = React.lazy(() => import('./soapbox-load')); +const SoapboxMount = React.lazy(() => import('./soapbox-mount')); // Configure global functions for developers createGlobals(store); From fe859593f7fdcfbc9c5482c77a177790c7839c36 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:51:25 -0500 Subject: [PATCH 8/9] Move soapbox.tsx and friends into src/init/ --- src/{containers => init}/soapbox-head.tsx | 0 src/{containers => init}/soapbox-load.tsx | 0 src/{containers => init}/soapbox-mount.tsx | 0 src/{containers => init}/soapbox.tsx | 0 src/main.tsx | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) rename src/{containers => init}/soapbox-head.tsx (100%) rename src/{containers => init}/soapbox-load.tsx (100%) rename src/{containers => init}/soapbox-mount.tsx (100%) rename src/{containers => init}/soapbox.tsx (100%) diff --git a/src/containers/soapbox-head.tsx b/src/init/soapbox-head.tsx similarity index 100% rename from src/containers/soapbox-head.tsx rename to src/init/soapbox-head.tsx diff --git a/src/containers/soapbox-load.tsx b/src/init/soapbox-load.tsx similarity index 100% rename from src/containers/soapbox-load.tsx rename to src/init/soapbox-load.tsx diff --git a/src/containers/soapbox-mount.tsx b/src/init/soapbox-mount.tsx similarity index 100% rename from src/containers/soapbox-mount.tsx rename to src/init/soapbox-mount.tsx diff --git a/src/containers/soapbox.tsx b/src/init/soapbox.tsx similarity index 100% rename from src/containers/soapbox.tsx rename to src/init/soapbox.tsx diff --git a/src/main.tsx b/src/main.tsx index cd586aa25..9073b6bf6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -25,7 +25,7 @@ import './precheck'; import ready from './ready'; import { registerSW } from './utils/sw'; -const Soapbox = React.lazy(() => import('./containers/soapbox')); +const Soapbox = React.lazy(() => import('./init/soapbox')); if (BuildConfig.NODE_ENV === 'production') { printConsoleWarning(); From c2098c33617c210df56ed76cf889a6efe4a1eb62 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 Oct 2023 18:53:23 -0500 Subject: [PATCH 9/9] Fix lodash imports to get rid of unnecessary extra chunk --- src/features/chats/components/chat-message.tsx | 2 +- src/features/quotes/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/chats/components/chat-message.tsx b/src/features/chats/components/chat-message.tsx index 9b65eabf9..c4134a48b 100644 --- a/src/features/chats/components/chat-message.tsx +++ b/src/features/chats/components/chat-message.tsx @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; import clsx from 'clsx'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; -import { escape } from 'lodash'; +import escape from 'lodash/escape'; import React, { useMemo, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; diff --git a/src/features/quotes/index.tsx b/src/features/quotes/index.tsx index 6ba38fe10..7b0d057fe 100644 --- a/src/features/quotes/index.tsx +++ b/src/features/quotes/index.tsx @@ -1,5 +1,5 @@ import { OrderedSet as ImmutableOrderedSet } from 'immutable'; -import { debounce } from 'lodash'; +import debounce from 'lodash/debounce'; import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { useParams } from 'react-router-dom';