perf: bundle flag icons instead of blocking on a CDN (#99)

index.html loaded two jsdelivr stylesheets synchronously in <head>, which
delayed first paint and failed outright on networks where the CDN is
unreachable. Drop font-logos (unused in src/) and bundle flag-icons
locally so Vite hashes the sprites and serves them from our own origin
with immutable cache headers.
This commit is contained in:
CyL authored and GitHub committed 2026-10-22 09:08:42 +08:00
1 parent 74a52e8cb0
commit d4fe4e5806
4 files changed
+25 -11

No files matched your search

-2
View File
@@ -72,8 +72,6 @@
<meta name="apple-mobile-web-app-title" content="Nezha Monitoring" />
<link rel="apple-touch-icon" href="/android-chrome-192x192.png" />
<link rel="stylesheet" href="https://fastly.jsdelivr.net/gh/lipis/flag-icons@7.0.0/css/flag-icons.min.css" />
<link rel="stylesheet" href="https://fastly.jsdelivr.net/npm/font-logos@1/assets/font-logos.css" />
</head>
<body>
<div id="root"></div>
+1
View File
@@ -50,6 +50,7 @@
"country-flag-icons": "1.6.17",
"d3-geo": "3.1.1",
"dayjs": "1.11.21",
"flag-icons": "7.0.0",
"i18n-iso-countries": "7.14.0",
"i18next": "26.3.1",
"lucide-react": "1.17.0",
+20 -9
View File
@@ -83,6 +83,9 @@ importers:
dayjs:
specifier: 1.11.21
version: 1.11.21
flag-icons:
specifier: 7.0.0
version: 7.0.0
i18n-iso-countries:
specifier: 7.14.0
version: 7.14.0
@@ -128,13 +131,13 @@ importers:
version: 4.3.2
'@testing-library/jest-dom':
specifier: ^6.9.1
version: 6.9.1
version: 6.10.0(@testing-library/dom@10.4.1)
'@testing-library/react':
specifier: ^16.3.2
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@testing-library/user-event':
specifier: ^14.6.1
version: 14.6.1(@testing-library/dom@10.4.1)
version: 14.6.8(@testing-library/dom@10.4.1)
'@types/node':
specifier: 25.9.2
version: 25.9.2
@@ -1125,9 +1128,11 @@ packages:
resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
engines: {node: '>=18'}
'@testing-library/jest-dom@6.9.1':
resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==}
engines: {node: '>=14', npm: '>=6', yarn: '>=1'}
'@testing-library/jest-dom@6.10.0':
resolution: {integrity: sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ==}
engines: {node: '>=22', npm: '>=6', yarn: '>=1'}
peerDependencies:
'@testing-library/dom': '>=10 <11'
'@testing-library/react@16.3.2':
resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==}
@@ -1144,8 +1149,8 @@ packages:
'@types/react-dom':
optional: true
'@testing-library/user-event@14.6.1':
resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==}
'@testing-library/user-event@14.6.8':
resolution: {integrity: sha512-vgSSqnANMnkcYR/vUNDbwS7aM3OErRLNUG8vCVVlj4oc6cKffUrccX7UAS5AmJQQNZTSibi9z5GvvRZ0aYgUCQ==}
engines: {node: '>=12', npm: '>=6'}
peerDependencies:
'@testing-library/dom': '>=7.21.4'
@@ -1566,6 +1571,9 @@ packages:
picomatch:
optional: true
flag-icons@7.0.0:
resolution: {integrity: sha512-U8nkYAJUHDro4SiKjJgnVJnAr6yMHWG7k6+FnV73dnWf/HkQXOZLxkie8qd4ZWR83+L6hQITEWJYgApN4sfUZA==}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -3032,9 +3040,10 @@ snapshots:
picocolors: 1.1.1
pretty-format: 27.5.1
'@testing-library/jest-dom@6.9.1':
'@testing-library/jest-dom@6.10.0(@testing-library/dom@10.4.1)':
dependencies:
'@adobe/css-tools': 4.5.0
'@testing-library/dom': 10.4.1
aria-query: 5.3.2
css.escape: 1.5.1
dom-accessibility-api: 0.6.3
@@ -3051,7 +3060,7 @@ snapshots:
'@types/react': 19.2.17
'@types/react-dom': 19.2.3(@types/react@19.2.17)
'@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)':
'@testing-library/user-event@14.6.8(@testing-library/dom@10.4.1)':
dependencies:
'@testing-library/dom': 10.4.1
@@ -3388,6 +3397,8 @@ snapshots:
optionalDependencies:
picomatch: 4.0.5
flag-icons@7.0.0: {}
fsevents@2.3.3:
optional: true
+4
View File
@@ -13,6 +13,10 @@ import { TooltipProvider } from "./context/tooltip-provider";
import { WebSocketProvider } from "./context/websocket-provider";
import "./i18n";
import "./index.css";
// Bundled instead of loaded from jsdelivr: the CDN <link> in index.html was
// render-blocking and unreliable on mainland networks. Vite hashes the flag
// sprites into assets/, so they inherit the immutable cache headers.
import "flag-icons/css/flag-icons.min.css";
const queryClient = new QueryClient();
const ReactQueryDevtools = import.meta.env.DEV