lint is up to 40x slower than 0.8.106 on a long linked stylesheet: the canvas-zoom rule strips comments once per matched rule, and lint now reads stylesheets linked from sub-compositions
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 75/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- css, typescript
- Ambito
- performance, tooling
Direzione di ricerca
Il percorso lento è stylesheetCanvasZoomHits in packages/lint/src/rules/composition.ts, dove il ciclo while chiama stripCssComments(style.content) a ogni corrispondenza (intorno alla riga 364). Inizia leggendo collectHeavyOverlayHooks (righe 203-206), che rimuove già i commenti una volta, e applica lo stesso schema al ciclo. È completato quando il tempo di lint della riproduzione cresce approssimativamente in modo lineare con il numero di regole e l'output di lint non cambia.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
lint takes 10 to 60 s a project in 0.8.158 where 0.8.106 took 0.5 to 1.6 s on the same projects and machine (one project measured alternately: 11.5 and 12.5 s on 0.8.158 against 2.2 and 1.7 s on 0.8.106). On a quiet machine, two projects measured alternately on 0.8.152 took 3.1 and 3.2 s against 0.8.106's 0.5 and 0.5 s, and 7.1 and 7.4 s against 0.6 and 0.5 s. check runs the lint too, so every check pays it, and a check split into parts pays it in every part.
A CPU profile of one 14.2 s run: 6.5 s in stripCssComments and 4.6 s in stylesheetCanvasZoomHits (chunk-7F3B5YYT.js of the package's dist, around line 6470). The canvas-zoom rule's loop is
while ((match = ruleWithBody.exec(stripCssComments(style.content))) !== null)
so it strips the whole stylesheet's comments again for every rule it matches, and the time grows with the square of the stylesheet's length. Our stylesheet is about 2,750 lines with some 800 rules, which is where it shows.
The loop itself is older: 0.8.106 is as slow on the same 3,000 rules when they sit in an inline <style> (4.4 to 5.2 s on 0.8.106, 4.2 to 4.8 s on 0.8.158). What changed is which stylesheets lint reads. A <link rel="stylesheet"> inside a sub-composition's <template> is now also resolved from the project root (packages/lint/src/project.ts, lines 108-113 at v0.8.162), where 0.8.106 looked only beside the sub-composition's file and skipped it. That matches how the runtime mounts the template, but it sends every such stylesheet through the quadratic loop, once for each composition that links it (line 246). Our sub-compositions each link the one shared stylesheet.
Measured on 0.8.158 (0.8.152 behaves the same). The code is unchanged in v0.8.162: packages/lint/src/rules/composition.ts, line 364 still calls stripCssComments(style.content) inside the while.
Minimal reproduction
A blank project with one sub-composition that links a long stylesheet (3,000 simple rules with a comment each):
npx hyperframes init repro --non-interactive --example blank
cd repro
mkdir compositions
# write index.html and compositions/scene.html as below, then:
node -e "require('fs').writeFileSync('long.css', Array.from({ length: 3000 }, (_, i) => '/* rule ' + i + ' */\n.r' + i + ' { color: #f4f4f5; }\n').join(''))"
index.html (the blank template plus the #scene clip, with the example comment removed from the script):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=1920, height=1080" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
margin: 0;
width: 1920px;
height: 1080px;
overflow: hidden;
background: #0a0a0a;
}
#root {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}
#title {
color: #f4f4f5;
font-size: 72px;
font-weight: 600;
letter-spacing: -0.03em;
}
</style>
</head>
<body>
<div
id="root"
data-composition-id="main"
data-start="0"
data-duration="10"
data-width="1920"
data-height="1080"
>
<h1 id="title" class="clip" data-start="0" data-duration="10" data-track-index="0">Title</h1>
<div
id="scene"
data-composition-id="scene"
data-composition-src="compositions/scene.html"
data-start="0"
data-duration="10"
data-track-index="1"
data-width="1920"
data-height="1080"
></div>
</div>
<script>
const tl = gsap.timeline({ paused: true });
window.__timelines["main"] = tl;
tl.seek(0);
</script>
</body>
</html>
compositions/scene.html:
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<template>
<link rel="stylesheet" href="long.css" />
<div id="root" data-composition-id="scene" data-width="1920" data-height="1080"></div>
<script>
window.__timelines["scene"] = gsap.timeline({ paused: true });
</script>
</template>
</body>
</html>
Steps to reproduce
- Set up the reproduction above.
- In
repro, timenpx [email protected] lintandnpx [email protected] lint, alternately, a few times each (both report0 errors, 0 warnings). - Change
3000in thenode -eline to1000or6000, regeneratelong.cssand time again: on 0.8.158 the time grows with the square of the rule count.
Expected behavior
lint about as fast as 0.8.106 on the same project (0.4 to 0.5 s here), its time growing linearly with the stylesheet's length.
Actual behavior
Wall-clock times of lint on the reproduction, versions run alternately (the installed CLI started with node, so no npx resolution is included):
rules in long.css |
0.8.106 | 0.8.152 | 0.8.158 |
|---|---|---|---|
| 1,000 | 0.47, 0.48 s | 0.95, 0.83 s | |
| 3,000 | 0.44, 0.42, 0.44 s | 5.3, 5.1, 4.8 s | 4.4, 5.4, 6.7 s |
| 6,000 | 0.45, 0.48 s | 21.4, 17.3 s |
A CPU profile of 0.8.158 on the 3,000-rule reproduction: of 3.6 s, 1.4 s in stripCssComments, 1.3 s in stylesheetCanvasZoomHits and 0.6 s in garbage collection.
Environment
OS: Windows 11 (build 26200)
Node.js: v24.14.0
HyperFrames: 0.8.158 and 0.8.152 against 0.8.106 (code unchanged at v0.8.162)
Chrome: Chrome Headless Shell 152.0.7977.30
Additional context
Request: strip the comments once, before the loop (and run the regular expression over that one string), as collectHeavyOverlayHooks in the same file already does (composition.ts, lines 203-206 at v0.8.162).
- Lingua principale
- TypeScript
- Stelle
- 54.1k
- Fork
- 4.9k
- Merge medio
- 8h 32m
- PR unite (30g)
- 707
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di heygen-com/hyperframes
-
gsap_tween_tail counts GSAP's force3D and autoRound flags as propertiesForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertabug triage/needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
heygen-com/hyperframes#5683 ·
I maintainer di solito rispondono entro 1 giorno
-
desktop-candidate difficulty/easy enhancement good first issue help wanted triage/ready
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
heygen-com/hyperframes#5582 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Studio: press ? to open the keyboard shortcuts panelForse già presa @B-Payal l’ha presa 3 giorni fa. Apertadesktop-candidate difficulty/easy enhancement good first issue help wanted triage/ready
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
heygen-com/hyperframes#5580 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
remotion-to-hyperframes: Easing.cubic is mapped to power3 (quartic); cubic is power2Forse già presa @user-github-me l’ha presa 3 giorni fa. Apertadifficulty/easy documentation help wanted triage/ready
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
heygen-com/hyperframes#5538 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
`hyperframes docs examples` lists templates that don't existForse già presa @Muhtasim-Munif-Fahim l’ha presa 6 giorni fa. Apertabug difficulty/easy help wanted triage/ready
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
heygen-com/hyperframes#5393 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di heygen-com/hyperframes
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Chocobozzz/PeerTube#7832 ·
I maintainer di solito rispondono entro 3 giorni
-
Pay to use?Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 66/100
darkreader/darkreader#16108 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Add: Dak Nong TV SDApertacheck:passed streams:add
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
bug engine
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
frostney/GocciaScript#1746 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
agilepathway/label-checker#739 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno