Skip to content

Commit 4b9b9e6

Browse files
committed
perf: optimize loading transitions and build configuration
- Reduce transition durations and improve animation performance - Replace setTimeout with requestAnimationFrame for smoother transitions - Optimize Vite build configuration with minification and CSS splitting - Remove console logs in production via terser options
1 parent 911bb00 commit 4b9b9e6

File tree

4 files changed

+79
-53
lines changed

4 files changed

+79
-53
lines changed

astro.config.mjs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,24 @@ export default defineConfig({
1919
},
2020

2121
prefetch: {
22-
prefetchAll: true
22+
prefetchAll: true,
23+
defaultStrategy: 'viewport'
24+
},
25+
26+
vite: {
27+
build: {
28+
cssCodeSplit: true,
29+
cssMinify: true,
30+
minify: 'terser',
31+
terserOptions: {
32+
compress: {
33+
drop_console: true
34+
}
35+
}
36+
},
37+
optimizeDeps: {
38+
include: ['tailwindcss']
39+
}
2340
},
2441

2542
// Configure Vercel adapter with image service enabled

src/components/Home.astro

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const categories = ['All', ...new Set(tools.map((tool) => tool.category))];
1111
---
1212

1313
<div id="app" class="container mx-auto px-4 py-8 font-inter dark:text-gray-100">
14-
<div id="loadingState" class="block transition-opacity duration-700 ease-in-out">
14+
<div id="loadingState" class="block transition-opacity duration-300 ease-in-out">
1515
<LoadingState />
1616
</div>
1717

@@ -29,7 +29,7 @@ const categories = ['All', ...new Set(tools.map((tool) => tool.category))];
2929
</style>
3030
</noscript>
3131

32-
<div id="mainContent" class="hidden opacity-0 transition-all duration-700 ease-in-out transform translate-y-8 scale-[0.98]">
32+
<div id="mainContent" class="hidden opacity-0 transition-all duration-300 ease-in-out transform translate-y-4 scale-[0.99]">
3333
<style>
3434
/* Ensure the content is fully rendered in memory but not visible */
3535
#mainContent {
@@ -39,6 +39,7 @@ const categories = ['All', ...new Set(tools.map((tool) => tool.category))];
3939
right: 0;
4040
visibility: hidden;
4141
z-index: -1; /* Ensure it's behind the loading state */
42+
will-change: opacity, transform; /* Optimize for animation */
4243
}
4344

4445
/* When content is ready to be shown */
@@ -181,7 +182,7 @@ const categories = ['All', ...new Set(tools.map((tool) => tool.category))];
181182
}
182183

183184
// Set a timeout to ensure content is shown even if loading takes too long
184-
const maxLoadingTime = 3000; // 3 seconds max loading time
185+
const maxLoadingTime = 1500; // Reduced from 3000ms to 1500ms
185186
const forceShowTimeout = setTimeout(() => {
186187
console.log('Force showing content due to timeout');
187188
if (loadingState) {
@@ -194,6 +195,8 @@ const categories = ['All', ...new Set(tools.map((tool) => tool.category))];
194195
mainContent.classList.remove('hidden');
195196
mainContent.classList.add('opacity-100');
196197
mainContent.classList.remove('opacity-0');
198+
// Ensure transform is applied immediately
199+
mainContent.style.transform = 'translateY(0) scale(1)';
197200
}
198201
}, maxLoadingTime);
199202

@@ -240,38 +243,38 @@ const categories = ['All', ...new Set(tools.map((tool) => tool.category))];
240243
}
241244
});
242245

243-
const MIN_LOADING_TIME = 800;
246+
const MIN_LOADING_TIME = 300; // Reduced from 800ms to 300ms
244247
const startTime = Date.now();
245248

246249
const performTransition = () => {
247250
// Clear the force show timeout since we're transitioning normally
248251
clearTimeout(forceShowTimeout);
249252

250253
if (loadingState && mainContent) {
251-
// First make the main content ready but still invisible
254+
// Prepare content for immediate display
252255
mainContent.classList.add('content-visible');
253256
mainContent.style.display = 'block';
254257
mainContent.classList.remove('hidden');
255258

256-
// Small delay to ensure the DOM updates before animation
257-
setTimeout(() => {
258-
// Start fading out loading state
259+
// Use requestAnimationFrame for smoother transition
260+
requestAnimationFrame(() => {
261+
// Start fading out loading state immediately
259262
loadingState.classList.add('opacity-0');
260263

261-
// Start fading in content with a slight delay for a smoother handoff
262-
setTimeout(() => {
264+
// Start fading in content with minimal delay
265+
requestAnimationFrame(() => {
263266
mainContent.classList.add('opacity-100');
264267
mainContent.classList.remove('opacity-0');
265268
// Apply transform changes for a smooth animation
266269
mainContent.style.transform = 'translateY(0) scale(1)';
267-
}, 150);
270+
});
268271

269272
// After transition completes, hide loading state completely
270273
setTimeout(() => {
271274
loadingState.style.display = 'none';
272275
console.log('Transition complete - content visible');
273-
}, 700);
274-
}, 100);
276+
}, 300); // Reduced from 700ms to 300ms
277+
});
275278
}
276279
};
277280

src/layouts/Layout.astro

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const {
2626
<title>{title}</title>
2727
<ClientRouter fallback="swap" />
2828
<style is:global>
29-
/* Add loading indicator for view transitions */
29+
/* Add loading indicator for view transitions - optimized for performance */
3030
.astro-loading-indicator {
3131
position: fixed;
3232
top: 0;
@@ -38,7 +38,8 @@ const {
3838
transform-origin: 0% 0%;
3939
z-index: 9999;
4040
opacity: 0;
41-
transition: transform 0.4s ease-in-out, opacity 0.3s ease-in-out;
41+
transition: transform 0.2s ease-out, opacity 0.15s ease-out;
42+
will-change: transform, opacity;
4243
}
4344

4445
:root.astro-loading .astro-loading-indicator {
@@ -53,9 +54,9 @@ const {
5354

5455
/* Light theme colors */
5556
:root {
56-
/* Theme transition settings - optimized for performance */
57-
--theme-transition-duration: 250ms;
58-
--theme-transition-timing: cubic-bezier(0.22, 0.61, 0.36, 1);
57+
/* Theme transition settings - optimized for faster performance */
58+
--theme-transition-duration: 150ms;
59+
--theme-transition-timing: cubic-bezier(0.25, 0.1, 0.25, 1);
5960

6061
/* Light theme colors */
6162
--color-text: #1f2937;
@@ -172,20 +173,24 @@ const {
172173
<slot />
173174
</main>
174175
<script>
175-
// Handle loading indicator
176+
// Handle loading indicator with optimized timing
176177
document.addEventListener('astro:before-preparation', () => {
177-
document.documentElement.classList.add('astro-loading');
178+
requestAnimationFrame(() => {
179+
document.documentElement.classList.add('astro-loading');
180+
});
178181
});
179182

180183
document.addEventListener('astro:after-preparation', () => {
181-
document.documentElement.classList.add('astro-loading-done');
184+
requestAnimationFrame(() => {
185+
document.documentElement.classList.add('astro-loading-done');
186+
});
182187
});
183188

184189
document.addEventListener('astro:page-load', () => {
185-
// Reset loading state
186-
setTimeout(() => {
190+
// Reset loading state immediately
191+
requestAnimationFrame(() => {
187192
document.documentElement.classList.remove('astro-loading', 'astro-loading-done');
188-
}, 300);
193+
});
189194

190195
// Announce page changes to screen readers
191196
const pageTitle = document.title;
@@ -198,21 +203,17 @@ const {
198203
document.body.appendChild(announcer);
199204
}
200205
announcer.textContent = `Navigated to ${pageTitle}`;
201-
206+
202207
// Ensure content is visible
203208
const loadingState = document.getElementById('loadingState');
204209
const mainContent = document.getElementById('mainContent');
205-
206210
if (loadingState && mainContent) {
207-
// Force content to be visible after page load
208-
setTimeout(() => {
209-
loadingState.style.display = 'none';
210-
mainContent.style.display = 'block';
211-
mainContent.classList.remove('hidden');
212-
mainContent.classList.add('opacity-100');
213-
mainContent.classList.add('translate-y-0');
214-
mainContent.classList.remove('translate-y-4');
215-
}, 500);
211+
loadingState.style.display = 'none';
212+
mainContent.style.display = 'block';
213+
mainContent.classList.remove('hidden');
214+
mainContent.classList.add('content-visible');
215+
mainContent.classList.add('opacity-100');
216+
mainContent.style.transform = 'translateY(0) scale(1)';
216217
}
217218
});
218219
</script>

src/pages/index.astro

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,26 @@ import Layout from '../layouts/Layout.astro';
99
</Layout>
1010

1111
<script>
12-
// Ensure content is visible after a short delay
13-
document.addEventListener('DOMContentLoaded', () => {
14-
setTimeout(() => {
15-
const loadingState = document.getElementById('loadingState');
16-
const mainContent = document.getElementById('mainContent');
17-
18-
if (loadingState && mainContent) {
19-
console.log('Forcing content visibility from index.astro');
20-
loadingState.style.display = 'none';
21-
mainContent.style.display = 'block';
22-
mainContent.classList.remove('hidden');
23-
mainContent.classList.add('opacity-100');
24-
mainContent.classList.add('translate-y-0');
25-
mainContent.classList.remove('translate-y-4');
26-
}
27-
}, 1000);
28-
});
12+
// Ensure content is visible immediately after DOM is ready
13+
const showContent = () => {
14+
const loadingState = document.getElementById('loadingState');
15+
const mainContent = document.getElementById('mainContent');
16+
17+
if (loadingState && mainContent) {
18+
console.log('Forcing content visibility from index.astro');
19+
loadingState.style.display = 'none';
20+
mainContent.style.display = 'block';
21+
mainContent.classList.remove('hidden');
22+
mainContent.classList.add('content-visible');
23+
mainContent.classList.add('opacity-100');
24+
mainContent.style.transform = 'translateY(0) scale(1)';
25+
}
26+
};
27+
28+
// Execute immediately if DOM is already loaded
29+
if (document.readyState === 'interactive' || document.readyState === 'complete') {
30+
showContent();
31+
} else {
32+
document.addEventListener('DOMContentLoaded', showContent);
33+
}
2934
</script>

0 commit comments

Comments
 (0)