mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2024-11-23 05:59:55 +00:00
perf: code-split the application (#2456)
Code-split the application (but without lazy loading, aka dynamic imports aka async modules, so all the assets are loaded on app load, not when requested: this is needed for ensuring an smooth experience over slow networks) Lighthouse performance score went from 66 to 77 There's still a lot of work to do, but this is a good start. Signed-off-by: Fernando Fernández <ferferga@hotmail.com>
This commit is contained in:
parent
ef55e263f5
commit
cf82a146ae
@ -10,10 +10,10 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>Jellyfin Vue</title>
|
||||
<script type="module" src="src/splashscreen.ts"></script>
|
||||
<script type="module" src="src/splashscreen.ts" fetchpriority="high"></script>
|
||||
<script type="module" src="src/main.ts"></script>
|
||||
</head>
|
||||
<body class="j-splash">
|
||||
<img src="./icon.svg" alt="Jellyfin Logo" loading="eager" decoding="async">
|
||||
<img src="./icon.svg" alt="Jellyfin Logo" loading="eager" decoding="sync">
|
||||
</body>
|
||||
</html>
|
||||
|
44
frontend/scripts/plugins/chunking.ts
Normal file
44
frontend/scripts/plugins/chunking.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
/**
|
||||
* Creates the Rollup's chunking strategy of the application (for code-splitting)
|
||||
*/
|
||||
export function JellyfinVueChunking(): Plugin {
|
||||
return {
|
||||
name: 'Jellyfin_Vue:chunking',
|
||||
config: () => ({
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
/**
|
||||
* This is the first thing that should be debugged when there are issues
|
||||
* withe the bundle. Check these issues:
|
||||
* - https://github.com/vitejs/vite/issues/5142
|
||||
* - https://github.com/evanw/esbuild/issues/399
|
||||
* - https://github.com/rollup/rollup/issues/3888
|
||||
*/
|
||||
manualChunks(id) {
|
||||
const match = /node_modules\/([^/]+)/.exec(id)?.[1];
|
||||
|
||||
if (id.includes('virtual:locales') || ((id.includes('vuetify') || id.includes('date-fns')) && id.includes('locale'))) {
|
||||
return 'localization/meta';
|
||||
}
|
||||
|
||||
if (id.includes('@intlify/unplugin-vue-i18n/messages')
|
||||
) {
|
||||
return 'localization/messages';
|
||||
}
|
||||
|
||||
/**
|
||||
* Split each vendor in its own chunk
|
||||
*/
|
||||
if (match) {
|
||||
return `vendor/${match.replace('@', '')}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
src="./icon.svg"
|
||||
alt="Jellyfin Logo"
|
||||
loading="eager"
|
||||
decoding="async">
|
||||
decoding="sync">
|
||||
<JTransition
|
||||
name="slide-y-reverse"
|
||||
appear>
|
||||
|
@ -18,6 +18,7 @@ import { defineConfig } from 'vite';
|
||||
import { entrypoints, localeFilesFolder, srcRoot } from './scripts/paths';
|
||||
import virtualModules from './scripts/virtual-modules';
|
||||
import { JellyfinVueAnalysis } from './scripts/plugins/analysis';
|
||||
import { JellyfinVueChunking } from './scripts/plugins/chunking';
|
||||
|
||||
export default defineConfig({
|
||||
appType: 'spa',
|
||||
@ -25,6 +26,7 @@ export default defineConfig({
|
||||
cacheDir: '../node_modules/.cache/vite',
|
||||
plugins: [
|
||||
JellyfinVueAnalysis(),
|
||||
JellyfinVueChunking(),
|
||||
Virtual(virtualModules),
|
||||
VueRouter({
|
||||
dts: './types/global/routes.d.ts',
|
||||
@ -64,7 +66,8 @@ export default defineConfig({
|
||||
compositionOnly: true,
|
||||
fullInstall: false,
|
||||
forceStringify: true,
|
||||
include: localeFilesFolder
|
||||
include: localeFilesFolder,
|
||||
dropMessageCompiler: true
|
||||
}),
|
||||
UnoCSS(),
|
||||
VueDevTools()
|
||||
@ -77,7 +80,6 @@ export default defineConfig({
|
||||
/**
|
||||
* Disable chunk size warnings
|
||||
*/
|
||||
chunkSizeWarningLimit: Number.NaN,
|
||||
cssCodeSplit: true,
|
||||
cssMinify: 'lightningcss',
|
||||
modulePreload: false,
|
||||
@ -89,28 +91,7 @@ export default defineConfig({
|
||||
index: entrypoints.index
|
||||
},
|
||||
output: {
|
||||
chunkFileNames: (chunkInfo) => {
|
||||
/**
|
||||
* This is the default value: https://rollupjs.org/configuration-options/#output-chunkfilenames
|
||||
*/
|
||||
return chunkInfo.name === 'validation' ? 'assets/common-[hash].js' : '[name]-[hash].js';
|
||||
},
|
||||
validate: true,
|
||||
/**
|
||||
* This is the first thing that should be debugged when there are issues
|
||||
* withe the bundle. Check these issues:
|
||||
* - https://github.com/vitejs/vite/issues/5142
|
||||
* - https://github.com/evanw/esbuild/issues/399
|
||||
* - https://github.com/rollup/rollup/issues/3888
|
||||
*/
|
||||
manualChunks(id) {
|
||||
if (
|
||||
id.includes('virtual:locales')
|
||||
|| id.includes('@intlify/unplugin-vue-i18n/messages')
|
||||
) {
|
||||
return 'assets/locales';
|
||||
}
|
||||
}
|
||||
validate: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user