Optimize lazy rendering and theme switching
Browse files- static/app.js +10 -7
- static/style.css +9 -17
static/app.js
CHANGED
|
@@ -558,17 +558,20 @@ function applyTheme() {
|
|
| 558 |
|
| 559 |
function toggleTheme() {
|
| 560 |
const animate = motionAllowed();
|
| 561 |
-
|
| 562 |
STATE.isDark = !STATE.isDark;
|
| 563 |
applyTheme();
|
| 564 |
localStorage.setItem("theme", STATE.isDark ? "dark" : "light");
|
|
|
|
| 565 |
if (animate) {
|
| 566 |
-
document.
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
|
|
|
|
|
|
| 572 |
}
|
| 573 |
}
|
| 574 |
|
|
|
|
| 558 |
|
| 559 |
function toggleTheme() {
|
| 560 |
const animate = motionAllowed();
|
| 561 |
+
DOM.resultsList.classList.add("theme-static");
|
| 562 |
STATE.isDark = !STATE.isDark;
|
| 563 |
applyTheme();
|
| 564 |
localStorage.setItem("theme", STATE.isDark ? "dark" : "light");
|
| 565 |
+
requestAnimationFrame(() => DOM.resultsList.classList.remove("theme-static"));
|
| 566 |
if (animate) {
|
| 567 |
+
document.querySelectorAll(".theme-icon-svg").forEach((icon) => {
|
| 568 |
+
icon.getAnimations().forEach((animation) => animation.cancel());
|
| 569 |
+
icon.animate([
|
| 570 |
+
{ opacity: 0.15, transform: "rotate(-160deg) scale(0.5)" },
|
| 571 |
+
{ opacity: 1, transform: "rotate(14deg) scale(1.16)", offset: 0.64 },
|
| 572 |
+
{ opacity: 1, transform: "rotate(0) scale(1)" },
|
| 573 |
+
], { duration: 520, easing: "cubic-bezier(0.05, 0.7, 0.1, 1)" });
|
| 574 |
+
});
|
| 575 |
}
|
| 576 |
}
|
| 577 |
|
static/style.css
CHANGED
|
@@ -556,16 +556,6 @@ body.preview-open #preview-panel .preview-header {
|
|
| 556 |
display: block;
|
| 557 |
}
|
| 558 |
|
| 559 |
-
body.theme-switching .theme-icon-svg {
|
| 560 |
-
animation: theme-icon-turn 520ms var(--motion-emphasized-easing);
|
| 561 |
-
}
|
| 562 |
-
|
| 563 |
-
@keyframes theme-icon-turn {
|
| 564 |
-
0% { opacity: 0.15; transform: rotate(-160deg) scale(0.5); }
|
| 565 |
-
64% { opacity: 1; transform: rotate(14deg) scale(1.16); }
|
| 566 |
-
100% { opacity: 1; transform: rotate(0) scale(1); }
|
| 567 |
-
}
|
| 568 |
-
|
| 569 |
.preview-title {
|
| 570 |
font-size: 15px;
|
| 571 |
font-weight: 600;
|
|
@@ -1213,6 +1203,13 @@ body.mobile .multi-toggle { padding: 1px 4px; font-size: 11px; }
|
|
| 1213 |
transition: opacity var(--motion-standard), transform var(--motion-standard);
|
| 1214 |
}
|
| 1215 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1216 |
.snippet-loading {
|
| 1217 |
color: var(--on-surface-variant);
|
| 1218 |
opacity: 0.7;
|
|
@@ -1229,6 +1226,8 @@ body.mobile .multi-toggle { padding: 1px 4px; font-size: 11px; }
|
|
| 1229 |
padding: 10px 16px;
|
| 1230 |
border-bottom: 1px solid var(--outline-variant);
|
| 1231 |
transition: background var(--transition);
|
|
|
|
|
|
|
| 1232 |
}
|
| 1233 |
|
| 1234 |
.result-item.result-enter {
|
|
@@ -2117,13 +2116,6 @@ input[type="checkbox"]:indeterminate {
|
|
| 2117 |
accent-color: var(--primary);
|
| 2118 |
}
|
| 2119 |
|
| 2120 |
-
body.theme-transitioning,
|
| 2121 |
-
body.theme-transitioning *,
|
| 2122 |
-
body.theme-transitioning *::before,
|
| 2123 |
-
body.theme-transitioning *::after {
|
| 2124 |
-
transition: background-color 240ms var(--motion-standard-easing), color 240ms var(--motion-standard-easing), border-color 240ms var(--motion-standard-easing), box-shadow 240ms var(--motion-standard-easing) !important;
|
| 2125 |
-
}
|
| 2126 |
-
|
| 2127 |
@media (prefers-reduced-motion: reduce) {
|
| 2128 |
*, *::before, *::after {
|
| 2129 |
animation-duration: 0.01ms !important;
|
|
|
|
| 556 |
display: block;
|
| 557 |
}
|
| 558 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 559 |
.preview-title {
|
| 560 |
font-size: 15px;
|
| 561 |
font-weight: 600;
|
|
|
|
| 1203 |
transition: opacity var(--motion-standard), transform var(--motion-standard);
|
| 1204 |
}
|
| 1205 |
|
| 1206 |
+
.results-list.theme-static,
|
| 1207 |
+
.results-list.theme-static *,
|
| 1208 |
+
.results-list.theme-static *::before,
|
| 1209 |
+
.results-list.theme-static *::after {
|
| 1210 |
+
transition: none !important;
|
| 1211 |
+
}
|
| 1212 |
+
|
| 1213 |
.snippet-loading {
|
| 1214 |
color: var(--on-surface-variant);
|
| 1215 |
opacity: 0.7;
|
|
|
|
| 1226 |
padding: 10px 16px;
|
| 1227 |
border-bottom: 1px solid var(--outline-variant);
|
| 1228 |
transition: background var(--transition);
|
| 1229 |
+
content-visibility: auto;
|
| 1230 |
+
contain-intrinsic-size: auto 112px;
|
| 1231 |
}
|
| 1232 |
|
| 1233 |
.result-item.result-enter {
|
|
|
|
| 2116 |
accent-color: var(--primary);
|
| 2117 |
}
|
| 2118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2119 |
@media (prefers-reduced-motion: reduce) {
|
| 2120 |
*, *::before, *::after {
|
| 2121 |
animation-duration: 0.01ms !important;
|