Spaces:
Running
Running
perf/ui: use forest images across pages and defer Granim init
Browse files- Replace ocean image with forest path image on login and index headers
- Defer Granim script and initialization with requestIdleCallback
- Keep login background as full-screen canvas as before
- Small cache-busting bump on index for reliable refresh
This improves initial render performance and visual consistency.
- static/index.html +37 -28
- static/login.html +42 -35
static/index.html
CHANGED
@@ -10,8 +10,8 @@
|
|
10 |
<link rel="icon" type="image/png" href="/static/image/icons8-tree-96.png">
|
11 |
<link rel="apple-touch-icon" href="/static/image/icons8-tree-96.png">
|
12 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
13 |
-
<!-- Granim.js for gradient animations -->
|
14 |
-
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/granim.min.js"></script>
|
15 |
<style>
|
16 |
|
17 |
:root {
|
@@ -917,7 +917,7 @@
|
|
917 |
// Force refresh if we detect cached version
|
918 |
(function() {
|
919 |
const currentVersion = '5.1.0';
|
920 |
-
const timestamp = '
|
921 |
const lastVersion = sessionStorage.getItem('treetrack_version');
|
922 |
const lastTimestamp = sessionStorage.getItem('treetrack_timestamp');
|
923 |
|
@@ -1156,32 +1156,41 @@
|
|
1156 |
<script>
|
1157 |
// Initialize Granim background animation on page load
|
1158 |
document.addEventListener('DOMContentLoaded', function() {
|
1159 |
-
//
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
[
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
|
|
|
|
|
|
1180 |
}
|
1181 |
-
}
|
1182 |
-
}
|
1183 |
-
|
1184 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1185 |
});
|
1186 |
</script>
|
1187 |
</body>
|
|
|
10 |
<link rel="icon" type="image/png" href="/static/image/icons8-tree-96.png">
|
11 |
<link rel="apple-touch-icon" href="/static/image/icons8-tree-96.png">
|
12 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
13 |
+
<!-- Granim.js for gradient animations (deferred) -->
|
14 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/granim.min.js" defer></script>
|
15 |
<style>
|
16 |
|
17 |
:root {
|
|
|
917 |
// Force refresh if we detect cached version
|
918 |
(function() {
|
919 |
const currentVersion = '5.1.0';
|
920 |
+
const timestamp = '1754659000'; // Cache-busting bump
|
921 |
const lastVersion = sessionStorage.getItem('treetrack_version');
|
922 |
const lastTimestamp = sessionStorage.getItem('treetrack_timestamp');
|
923 |
|
|
|
1156 |
<script>
|
1157 |
// Initialize Granim background animation on page load
|
1158 |
document.addEventListener('DOMContentLoaded', function() {
|
1159 |
+
// Define initializer and defer to idle time for better performance
|
1160 |
+
function startHeaderGranim() {
|
1161 |
+
new Granim({
|
1162 |
+
element: '#header-canvas',
|
1163 |
+
direction: 'diagonal',
|
1164 |
+
isPausedWhenNotInView: false,
|
1165 |
+
image: {
|
1166 |
+
// Forest path image
|
1167 |
+
source: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=2560&auto=format&fit=crop&ixlib=rb-4.0.3',
|
1168 |
+
position: ['center', 'center'],
|
1169 |
+
stretchMode: ['stretch', 'stretch'],
|
1170 |
+
blendingMode: 'multiply'
|
1171 |
+
},
|
1172 |
+
states: {
|
1173 |
+
"default-state": {
|
1174 |
+
gradients: [
|
1175 |
+
['#0f172a', '#1e293b', '#16a085'],
|
1176 |
+
['#1a202c', '#2d3748', '#27ae60'],
|
1177 |
+
['#2d3748', '#4a5568', '#2ecc71'],
|
1178 |
+
['#1a365d', '#2c5282', '#138d75'],
|
1179 |
+
['#0f172a', '#2d3748', '#16a085']
|
1180 |
+
],
|
1181 |
+
transitionSpeed: 12000
|
1182 |
+
}
|
1183 |
}
|
1184 |
+
});
|
1185 |
+
}
|
1186 |
+
|
1187 |
+
if (window.requestIdleCallback) {
|
1188 |
+
requestIdleCallback(() => { startHeaderGranim(); });
|
1189 |
+
} else {
|
1190 |
+
setTimeout(() => { startHeaderGranim(); }, 0);
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
console.log('Scheduled header Granim initialization');
|
1194 |
});
|
1195 |
</script>
|
1196 |
</body>
|
static/login.html
CHANGED
@@ -7,8 +7,8 @@
|
|
7 |
<link rel="icon" type="image/png" href="/static/image/icons8-tree-96.png">
|
8 |
<link rel="apple-touch-icon" href="/static/image/icons8-tree-96.png">
|
9 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
10 |
-
<!-- Granim.js CDN -->
|
11 |
-
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/granim.min.js"></script>
|
12 |
<style>
|
13 |
body {
|
14 |
min-height: 100vh;
|
@@ -510,40 +510,47 @@
|
|
510 |
console.log('Initializing Granim...');
|
511 |
|
512 |
try {
|
513 |
-
//
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
[
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
534 |
}
|
535 |
-
}
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
}
|
542 |
-
}
|
543 |
-
|
544 |
-
console.log('Granim
|
545 |
-
|
546 |
-
console.log('Granim initialized successfully!');
|
547 |
|
548 |
} catch (error) {
|
549 |
console.error('Granim initialization failed:', error);
|
|
|
7 |
<link rel="icon" type="image/png" href="/static/image/icons8-tree-96.png">
|
8 |
<link rel="apple-touch-icon" href="/static/image/icons8-tree-96.png">
|
9 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
10 |
+
<!-- Granim.js CDN (deferred to avoid blocking render) -->
|
11 |
+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/granim.min.js" defer></script>
|
12 |
<style>
|
13 |
body {
|
14 |
min-height: 100vh;
|
|
|
510 |
console.log('Initializing Granim...');
|
511 |
|
512 |
try {
|
513 |
+
// Define and defer Granim initialization to avoid blocking render
|
514 |
+
function startGranim() {
|
515 |
+
new Granim({
|
516 |
+
element: '#granim-canvas',
|
517 |
+
direction: 'diagonal',
|
518 |
+
isPausedWhenNotInView: false,
|
519 |
+
image: {
|
520 |
+
// Forest path image
|
521 |
+
source: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=2560&auto=format&fit=crop&ixlib=rb-4.0.3',
|
522 |
+
position: ['center', 'center'],
|
523 |
+
stretchMode: ['stretch', 'stretch'],
|
524 |
+
blendingMode: 'multiply'
|
525 |
+
},
|
526 |
+
states: {
|
527 |
+
"default-state": {
|
528 |
+
gradients: [
|
529 |
+
['#0f172a', '#1e293b', '#16a085'],
|
530 |
+
['#1a202c', '#2d3748', '#27ae60'],
|
531 |
+
['#2d3748', '#4a5568', '#2ecc71'],
|
532 |
+
['#1a365d', '#2c5282', '#138d75'],
|
533 |
+
['#0f172a', '#2d3748', '#16a085']
|
534 |
+
],
|
535 |
+
transitionSpeed: 10000
|
536 |
+
}
|
537 |
+
},
|
538 |
+
onStart: function() {
|
539 |
+
console.log('Granim forest animation started');
|
540 |
+
},
|
541 |
+
onEnd: function() {
|
542 |
+
console.log('Granim forest animation ended');
|
543 |
}
|
544 |
+
});
|
545 |
+
}
|
546 |
+
|
547 |
+
if (window.requestIdleCallback) {
|
548 |
+
requestIdleCallback(() => { startGranim(); });
|
549 |
+
} else {
|
550 |
+
setTimeout(() => { startGranim(); }, 0);
|
551 |
+
}
|
552 |
+
|
553 |
+
console.log('Scheduled Granim initialization');
|
|
|
|
|
554 |
|
555 |
} catch (error) {
|
556 |
console.error('Granim initialization failed:', error);
|