diff --git a/changes/changelog.d/front-split-large-bundles.enhancement b/changes/changelog.d/front-split-large-bundles.enhancement new file mode 100644 index 000000000..cb53791b5 --- /dev/null +++ b/changes/changelog.d/front-split-large-bundles.enhancement @@ -0,0 +1 @@ +Split front large bundles into smaller chunks diff --git a/front/src/App.vue b/front/src/App.vue index 51bdf2a03..a323ade35 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -2,24 +2,24 @@ import type { QueueTrack } from '~/composables/audio/queue' import { useIntervalFn, useToggle, useWindowSize } from '@vueuse/core' -import { computed, nextTick, onMounted, ref, watchEffect } from 'vue' +import { computed, nextTick, onMounted, ref, watchEffect, defineAsyncComponent } from 'vue' import { useQueue } from '~/composables/audio/queue' import { useStore } from '~/store' -import ChannelUploadModal from '~/components/channels/UploadModal.vue' -import PlaylistModal from '~/components/playlists/PlaylistModal.vue' -import FilterModal from '~/components/moderation/FilterModal.vue' -import ReportModal from '~/components/moderation/ReportModal.vue' -import SetInstanceModal from '~/components/SetInstanceModal.vue' -import ServiceMessages from '~/components/ServiceMessages.vue' -import ShortcutsModal from '~/components/ShortcutsModal.vue' -import AudioPlayer from '~/components/audio/Player.vue' -import Sidebar from '~/components/Sidebar.vue' -import Queue from '~/components/Queue.vue' - import onKeyboardShortcut from '~/composables/onKeyboardShortcut' +const ChannelUploadModal = defineAsyncComponent(() => import('~/components/channels/UploadModal.vue')) +const PlaylistModal = defineAsyncComponent(() => import('~/components/playlists/PlaylistModal.vue')) +const FilterModal = defineAsyncComponent(() => import('~/components/moderation/FilterModal.vue')) +const ReportModal = defineAsyncComponent(() => import('~/components/moderation/ReportModal.vue')) +const SetInstanceModal = defineAsyncComponent(() => import('~/components/SetInstanceModal.vue')) +const ServiceMessages = defineAsyncComponent(() => import('~/components/ServiceMessages.vue')) +const ShortcutsModal = defineAsyncComponent(() => import('~/components/ShortcutsModal.vue')) +const AudioPlayer = defineAsyncComponent(() => import('~/components/audio/Player.vue')) +const Sidebar = defineAsyncComponent(() => import('~/components/Sidebar.vue')) +const Queue = defineAsyncComponent(() => import('~/components/Queue.vue')) + const store = useStore() // Tracks @@ -124,7 +124,3 @@ store.dispatch('auth/fetchUser') - - diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue index 0fa7379ec..0e21cc3e0 100644 --- a/front/src/components/Queue.vue +++ b/front/src/components/Queue.vue @@ -2,7 +2,7 @@ import type { QueueItemSource } from '~/types' import { whenever, watchDebounced, useCurrentElement, useScrollLock, useFullscreen, useIdle, refAutoReset, useStorage } from '@vueuse/core' -import { nextTick, ref, computed, watchEffect, onMounted } from 'vue' +import { nextTick, ref, computed, watchEffect, onMounted, defineAsyncComponent } from 'vue' import { useFocusTrap } from '@vueuse/integrations/useFocusTrap' import { useRouter } from 'vue-router' import { useI18n } from 'vue-i18n' @@ -17,11 +17,12 @@ import time from '~/utils/time' import TrackFavoriteIcon from '~/components/favorites/TrackFavoriteIcon.vue' import TrackPlaylistIcon from '~/components/playlists/TrackPlaylistIcon.vue' import PlayerControls from '~/components/audio/PlayerControls.vue' -import MilkDrop from '~/components/audio/visualizer/MilkDrop.vue' import VirtualList from '~/components/vui/list/VirtualList.vue' import QueueItem from '~/components/QueueItem.vue' +const MilkDrop = defineAsyncComponent(() => import('~/components/audio/visualizer/MilkDrop.vue')) + const { isPlaying, currentTime, diff --git a/front/src/main.ts b/front/src/main.ts index d7ffdbb7d..c24863ca8 100644 --- a/front/src/main.ts +++ b/front/src/main.ts @@ -8,6 +8,8 @@ import { createApp, defineAsyncComponent, h } from 'vue' import useLogger from '~/composables/useLogger' import useTheme from '~/composables/useTheme' +import '~/style/_main.scss' + import '~/api' // NOTE: Set the theme as fast as possible diff --git a/front/src/style/globals/_utils.scss b/front/src/style/globals/_utils.scss index 67423876f..ccb00ce7d 100644 --- a/front/src/style/globals/_utils.scss +++ b/front/src/style/globals/_utils.scss @@ -107,7 +107,7 @@ span.diff.removed { } .default-cover { - background-image: url("./assets/audio/default-cover.png") !important; + background-image: url("~/assets/audio/default-cover.png") !important; } .discrete { diff --git a/front/vite.config.ts b/front/vite.config.ts index 470917fcc..fe866ea67 100644 --- a/front/vite.config.ts +++ b/front/vite.config.ts @@ -54,6 +54,23 @@ export default defineConfig(({ mode }) => ({ '~': resolve(__dirname, './src') } }, + build: { + // https://rollupjs.org/configuration-options/ + rollupOptions: { + output: { + manualChunks: { + 'axios': ['axios', 'axios-auth-refresh'], + 'dompurify': ['dompurify'], + 'jquery': ['jquery'], + 'lodash': ['lodash-es'], + 'moment': ['moment'], + 'sentry': ['@sentry/vue', '@sentry/tracing'], + 'standardized-audio-context': ['standardized-audio-context'], + 'vue-router': ['vue-router'], + } + } + } + }, test: { environment: 'jsdom', globals: true,