Element#matches() compiles the selector on every call
Maintainer thường phản hồi trong vòng 17 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 35/100
- Loại issue
- Tái cấu trúc
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- css, javascript
- Lĩnh vực
- backend, performance
Hướng nghiên cứu
The hot path is esm/shared/matches.js near line 109, where Element#matches() passes the selector string to CSSselect.is(), which recompiles it on every call; prepareMatch already compiles once per call for querySelector* and closest(), so look there for the pattern to reuse. Pull request #349 is already open against this, so check it before starting. Done means a compiled selector is cached per selector string and document kind in a small bounded Map, :scope selectors still compile per call, and the existing matches tests pass with coverage unchanged.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Element#matches(selectors) parses and compiles the selector again on every call. Code that tests many elements against the same few selectors (resolving a <style> sheet over an SVG chart, for example) spends most of its time in css-what's parser and css-select's compiler rather than in matching.
// npm i linkedom && node matches.mjs
import { parseHTML } from 'linkedom';
let svg = '<svg id="chart">';
for (let i = 0; i < 400; i++)
svg += `<g class="node n${i % 7}"><rect class="box"></rect><g class="label"><text class="title"><tspan>${i}</tspan></text></g></g>`;
const { document } = parseHTML(`<!doctype html><html><body>${svg}</svg></body></html>`);
const selectors = [];
for (const a of ['#chart', '#chart .node', '#chart g.label', 'svg'])
for (const b of ['rect', 'text', 'tspan', '.label', '.title', '.box', '.n3', 'g', '.cluster rect', '.edgeLabel', 'g.node', '.missing'])
selectors.push(`${a} ${b}`);
const elements = [...document.querySelectorAll('svg, svg *')];
const t = performance.now();
for (const el of elements)
for (const sel of selectors)
el.matches(sel);
console.log(`${elements.length * selectors.length} calls: ${(performance.now() - t).toFixed(0)} ms`);
Node 22.17.0, macOS, median of runs:
96,048 matches() calls |
|
|---|---|
| linkedom 0.18.13 | ~112 ms |
linkedom main (3fcf145) |
~108 ms |
| same, with the compiled selector kept per selector string | ~20 ms |
A larger run (2,001 elements × 50 selectors, 300k calls), in ms per 100k calls: linkedom 0.18.13 158, main 111, with the compiled selector kept 17; happy-dom 21.0.3 10, jsdom 30.1.3 209.
A CPU profile of main shows css-what parseSelector/unescapeCSS, css-select compileToken/escapeRegex and GC on top; the matching itself is a small share.
Where: esm/shared/matches.js#L109 passes the selector string to CSSselect.is(), which calls compile(query, options) each time (css-select 7.0.0, dist/index.js, is). querySelector* and closest() compile once per call through prepareMatch, so it is matches() that pays per element.
Possible fix: keep the compiled function per selector string and document kind (xmlMode), in a small bounded Map; selectors with :scope keep compiling per call since their context is the element. I have this with a test (coverage unchanged) and can open a PR.
- Ngôn ngữ chính
- HTML
- Star
- 2.1k
- Fork
- 112
- Merge trung bình
- 11 ngày 1 giờ
- Pull request đã merge (30 ngày)
- 1
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của WebReflection/linkedom
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
WebReflection/linkedom#344 ·
Maintainer thường phản hồi trong vòng 17 ngày
-
`TextElement.toString()` puts the element text back at the first `><` of the start tag, so an attribute value containing `><` swallows the text of `<style>`, `<script>`, `<title>` and `<textarea>`Có thể đã có người làm @vsolano9 đã nhận 3 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
WebReflection/linkedom#341 ·
Maintainer thường phản hồi trong vòng 17 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
WebReflection/linkedom#340 ·
Maintainer thường phản hồi trong vòng 17 ngày
-
Độ khó 3/5 Nửa ngày Mức phù hợp với người mới 50/100
WebReflection/linkedom#345 ·
Maintainer thường phản hồi trong vòng 17 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
WebReflection/linkedom#342 ·
Maintainer thường phản hồi trong vòng 17 ngày
Tất cả issue của WebReflection/linkedom
Issue tương tự
-
get_page_thumbnail modifies cached page images, affecting later thumbnails and picture exportsĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
docling-project/docling-mcp#147 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
subhranshudash13-dotcom/Contribo#71 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
fix(backup-uploader): write current-round marker outside / so the container can run as non-rootĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
hiero-ledger/solo-containers#254 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
backend good first issue security Stellar Wave trivial
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Godgift-care/sci-healthcare-backend#171 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
laaielichter/Reverseport#43 ·
Maintainer thường phản hồi trong vòng 1 ngày