Skip to content

Commit becb40f

Browse files
committed
perf
1 parent 0faccf7 commit becb40f

File tree

12 files changed

+788
-620
lines changed

12 files changed

+788
-620
lines changed

frontend/src/styles/test.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@
584584
}
585585

586586
#wordsInput {
587-
width: 1ch;
587+
width: 0;
588588
font-size: 1em;
589589
height: 1em;
590590
opacity: 0;

frontend/src/ts/elements/keymap.ts

Lines changed: 62 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { getActiveFunboxNames } from "../test/funbox/list";
1616
import { areSortedArraysEqual } from "../utils/arrays";
1717
import { LayoutObject } from "@monkeytype/schemas/layouts";
1818
import { animate } from "animejs";
19+
import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame";
1920

2021
export const keyDataDelimiter = "~~";
2122

@@ -60,74 +61,78 @@ const stenoKeys: LayoutObject = {
6061

6162
function highlightKey(currentKey: string): void {
6263
if (Config.mode === "zen") return;
63-
if (currentKey === "") currentKey = " ";
64-
try {
65-
$(".activeKey").removeClass("activeKey");
66-
67-
let highlightKey;
68-
if (Config.language.startsWith("korean")) {
69-
currentKey = Hangul.disassemble(currentKey)[0] ?? currentKey;
70-
}
71-
if (currentKey === " ") {
72-
highlightKey = "#keymap .keySpace";
73-
} else if (currentKey === '"') {
74-
highlightKey = `#keymap .keymapKey[data-key*='${currentKey}']`;
75-
} else {
76-
highlightKey = `#keymap .keymapKey[data-key*="${currentKey}"]`;
77-
}
64+
requestDebouncedAnimationFrame("keymap.highlightKey", async () => {
65+
if (currentKey === "") currentKey = " ";
66+
try {
67+
document
68+
.querySelectorAll(".activeKey")
69+
.forEach((el) => el.classList.remove("activeKey"));
7870

79-
// console.log("highlighting", highlightKey);
71+
let highlightKey;
72+
if (Config.language.startsWith("korean")) {
73+
currentKey = Hangul.disassemble(currentKey)[0] ?? currentKey;
74+
}
75+
if (currentKey === " ") {
76+
highlightKey = "#keymap .keySpace";
77+
} else if (currentKey === '"') {
78+
highlightKey = `#keymap .keymapKey[data-key*='${currentKey}']`;
79+
} else {
80+
highlightKey = `#keymap .keymapKey[data-key*="${currentKey}"]`;
81+
}
8082

81-
$(highlightKey).addClass("activeKey");
82-
} catch (e) {
83-
if (e instanceof Error) {
84-
console.log("could not update highlighted keymap key: " + e.message);
83+
document.querySelector(highlightKey)?.classList.add("activeKey");
84+
} catch (e) {
85+
if (e instanceof Error) {
86+
console.log("could not update highlighted keymap key: " + e.message);
87+
}
8588
}
86-
}
89+
});
8790
}
8891

8992
async function flashKey(key: string, correct?: boolean): Promise<void> {
90-
if (key === undefined) return;
91-
//console.log("key", key);
92-
if (key === " ") {
93-
key = "#keymap .keySpace";
94-
} else if (key === '"') {
95-
key = `#keymap .keymapKey[data-key*='${key}']`;
96-
} else {
97-
key = `#keymap .keymapKey[data-key*="${key}"]`;
98-
}
93+
requestDebouncedAnimationFrame(`keymap.flashKey.${key}`, async () => {
94+
if (key === undefined) return;
95+
//console.log("key", key);
96+
if (key === " ") {
97+
key = "#keymap .keySpace";
98+
} else if (key === '"') {
99+
key = `#keymap .keymapKey[data-key*='${key}']`;
100+
} else {
101+
key = `#keymap .keymapKey[data-key*="${key}"]`;
102+
}
99103

100-
const themecolors = await ThemeColors.getAll();
104+
const themecolors = await ThemeColors.getAll();
101105

102-
try {
103-
let startingStyle = {
104-
color: themecolors.bg,
105-
backgroundColor: themecolors.sub,
106-
borderColor: themecolors.sub,
107-
};
108-
109-
if (correct || Config.blindMode) {
110-
startingStyle = {
111-
color: themecolors.bg,
112-
backgroundColor: themecolors.main,
113-
borderColor: themecolors.main,
114-
};
115-
} else {
116-
startingStyle = {
106+
try {
107+
let startingStyle = {
117108
color: themecolors.bg,
118-
backgroundColor: themecolors.error,
119-
borderColor: themecolors.error,
109+
backgroundColor: themecolors.sub,
110+
borderColor: themecolors.sub,
120111
};
121-
}
122112

123-
animate(key, {
124-
color: [startingStyle.color, themecolors.sub],
125-
backgroundColor: [startingStyle.backgroundColor, themecolors.subAlt],
126-
borderColor: [startingStyle.borderColor, themecolors.sub],
127-
duration: 250,
128-
easing: "out(5)",
129-
});
130-
} catch (e) {}
113+
if (correct || Config.blindMode) {
114+
startingStyle = {
115+
color: themecolors.bg,
116+
backgroundColor: themecolors.main,
117+
borderColor: themecolors.main,
118+
};
119+
} else {
120+
startingStyle = {
121+
color: themecolors.bg,
122+
backgroundColor: themecolors.error,
123+
borderColor: themecolors.error,
124+
};
125+
}
126+
127+
animate(key, {
128+
color: [startingStyle.color, themecolors.sub],
129+
backgroundColor: [startingStyle.backgroundColor, themecolors.subAlt],
130+
borderColor: [startingStyle.borderColor, themecolors.sub],
131+
duration: 250,
132+
easing: "out(5)",
133+
});
134+
} catch (e) {}
135+
});
131136
}
132137

133138
export function hide(): void {

frontend/src/ts/elements/monkey-power.ts

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import * as ThemeColors from "./theme-colors";
22
import * as SlowTimer from "../states/slow-timer";
33
import Config from "../config";
44
import { isSafeNumber } from "@monkeytype/util/numbers";
5+
import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame";
6+
7+
const html = document.querySelector("html") as HTMLElement;
8+
const body = document.body;
59

610
type Particle = {
711
x: number;
@@ -14,7 +18,7 @@ type Particle = {
1418

1519
type CTX = {
1620
particles: Particle[];
17-
caret?: JQuery;
21+
caret?: HTMLElement;
1822
canvas?: HTMLCanvasElement;
1923
context2d?: CanvasRenderingContext2D;
2024
rendering: boolean;
@@ -118,7 +122,7 @@ function updateParticle(particle: Particle): void {
118122
}
119123

120124
export function init(): void {
121-
ctx.caret = $("#caret");
125+
ctx.caret = document.querySelector("#caret") as HTMLElement;
122126
ctx.canvas = createCanvas();
123127
ctx.context2d = ctx.canvas.getContext("2d") as CanvasRenderingContext2D;
124128
}
@@ -155,7 +159,7 @@ function render(): void {
155159
}
156160
ctx.particles = keep;
157161

158-
if (ctx.particles.length && !SlowTimer.get()) {
162+
if (ctx.particles.length) {
159163
requestAnimationFrame(render);
160164
} else {
161165
ctx.context2d.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
@@ -168,14 +172,13 @@ export function reset(immediate = false): void {
168172
delete ctx.resetTimeOut;
169173

170174
clearTimeout(ctx.resetTimeOut);
171-
const body = $(document.body);
172-
body.css("transition", "all .25s, transform 0.8s");
173-
body.css("transform", `translate(0,0)`);
175+
body.style.transition = "all .25s, transform 0.8s";
176+
body.style.transform = `translate(0,0)`;
174177
setTimeout(
175178
() => {
176-
body.css("transition", "all .25s, transform .05s");
177-
$("html").css("overflow", "inherit");
178-
$("html").css("overflow-y", "scroll");
179+
body.style.transition = "all .25s, transform .05s";
180+
html.style.overflow = "inherit";
181+
html.style.overflowY = "scroll";
179182
},
180183
immediate ? 0 : 1000
181184
);
@@ -201,47 +204,46 @@ function randomColor(): string {
201204
export async function addPower(good = true, extra = false): Promise<void> {
202205
if (Config.monkeyPowerLevel === "off" || SlowTimer.get()) return;
203206

204-
if (Config.blindMode) good = true;
205-
206-
// Shake
207-
if (["3", "4"].includes(Config.monkeyPowerLevel)) {
208-
$("html").css("overflow", "hidden");
209-
const shake = [
210-
Math.round(shakeAmount - Math.random() * shakeAmount),
211-
Math.round(shakeAmount - Math.random() * shakeAmount),
207+
requestDebouncedAnimationFrame("monkey-power.addPower", async () => {
208+
if (Config.blindMode) good = true;
209+
210+
// Shake
211+
if (["3", "4"].includes(Config.monkeyPowerLevel)) {
212+
html.style.overflow = "hidden";
213+
const shake = [
214+
Math.round(shakeAmount - Math.random() * shakeAmount),
215+
Math.round(shakeAmount - Math.random() * shakeAmount),
216+
];
217+
body.style.transform = `translate(${shake[0]}px, ${shake[1]}px)`;
218+
if (isSafeNumber(ctx.resetTimeOut)) clearTimeout(ctx.resetTimeOut);
219+
ctx.resetTimeOut = setTimeout(reset, 2000) as unknown as number;
220+
}
221+
222+
// Sparks
223+
const offset = ctx.caret?.getBoundingClientRect();
224+
const coords = [
225+
offset?.left ?? 0,
226+
(offset?.top ?? 0) + (ctx.caret?.offsetHeight ?? 0),
212227
];
213-
$(document.body).css(
214-
"transform",
215-
`translate(${shake[0]}px, ${shake[1]}px)`
216-
);
217-
if (isSafeNumber(ctx.resetTimeOut)) clearTimeout(ctx.resetTimeOut);
218-
ctx.resetTimeOut = setTimeout(reset, 2000) as unknown as number;
219-
}
220228

221-
// Sparks
222-
const offset = ctx.caret?.offset();
223-
const coords = [
224-
offset?.left ?? 0,
225-
(offset?.top ?? 0) + (ctx.caret?.height() ?? 0),
226-
];
227-
228-
for (
229-
let i = Math.round(
230-
(particleCreateCount[0] + Math.random() * particleCreateCount[1]) *
231-
(extra ? 2 : 1)
232-
);
233-
i > 0;
234-
i--
235-
) {
236-
const color = ["2", "4"].includes(Config.monkeyPowerLevel)
237-
? randomColor()
238-
: good
239-
? await ThemeColors.get("caret")
240-
: await ThemeColors.get("error");
241-
ctx.particles.push(
242-
createParticle(...(coords as [x: number, y: number]), color)
243-
);
244-
}
245-
246-
startRender();
229+
for (
230+
let i = Math.round(
231+
(particleCreateCount[0] + Math.random() * particleCreateCount[1]) *
232+
(extra ? 2 : 1)
233+
);
234+
i > 0;
235+
i--
236+
) {
237+
const color = ["2", "4"].includes(Config.monkeyPowerLevel)
238+
? randomColor()
239+
: good
240+
? await ThemeColors.get("caret")
241+
: await ThemeColors.get("error");
242+
ctx.particles.push(
243+
createParticle(...(coords as [x: number, y: number]), color)
244+
);
245+
}
246+
247+
startRender();
248+
});
247249
}

frontend/src/ts/sentry.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ export async function activateSentry(): Promise<void> {
2626
environment: envConfig.isDevelopment ? "development" : "production",
2727
integrations: [
2828
Sentry.browserTracingIntegration(),
29-
// Sentry.replayIntegration({
30-
// unmask: ["#notificationCenter"],
31-
// block: ["#commandLine .modal .suggestions"],
29+
// // Sentry.replayIntegration({
30+
// // unmask: ["#notificationCenter"],
31+
// // block: ["#commandLine .modal .suggestions"],
32+
// // // ignore: ["#wordsInput"],
3233
// }),
3334
Sentry.thirdPartyErrorFilterIntegration({
3435
filterKeys: ["monkeytype-frontend"],

0 commit comments

Comments
 (0)