mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-02 02:09:03 +08:00
perf: shiki code block (#8763)
* perf: inlining completeLineTokens and use memo for minor improvements * chore: bump shiki to 3.9.1 * refactor: improve token line * refactor: add plainTokenStyle
This commit is contained in:
parent
3010f20d13
commit
43dc1e06e4
@ -129,7 +129,7 @@
|
||||
"@opentelemetry/sdk-trace-web": "^2.0.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@reduxjs/toolkit": "^2.2.5",
|
||||
"@shikijs/markdown-it": "^3.7.0",
|
||||
"@shikijs/markdown-it": "^3.9.1",
|
||||
"@swc/plugin-styled-components": "^7.1.5",
|
||||
"@tanstack/react-query": "^5.27.0",
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
@ -249,7 +249,7 @@
|
||||
"remove-markdown": "^0.6.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.88.0",
|
||||
"shiki": "^3.7.0",
|
||||
"shiki": "^3.9.1",
|
||||
"strict-url-sanitise": "^0.0.1",
|
||||
"string-width": "^7.2.0",
|
||||
"styled-components": "^6.1.11",
|
||||
|
||||
@ -189,44 +189,12 @@ const CodePreview = ({ children, language, setTools }: CodePreviewProps) => {
|
||||
|
||||
CodePreview.displayName = 'CodePreview'
|
||||
|
||||
/**
|
||||
* 补全代码行 tokens,把原始内容拼接到高亮内容之后,确保渲染出整行来。
|
||||
*/
|
||||
function completeLineTokens(themedTokens: ThemedToken[], rawLine: string): ThemedToken[] {
|
||||
// 如果出现空行,补一个空格保证行高
|
||||
if (rawLine.length === 0) {
|
||||
return [
|
||||
{
|
||||
content: ' ',
|
||||
offset: 0,
|
||||
color: 'inherit',
|
||||
bgColor: 'inherit',
|
||||
htmlStyle: {
|
||||
opacity: '0.35'
|
||||
}
|
||||
}
|
||||
]
|
||||
const plainTokenStyle = {
|
||||
color: 'inherit',
|
||||
bgColor: 'inherit',
|
||||
htmlStyle: {
|
||||
opacity: '0.35'
|
||||
}
|
||||
|
||||
const themedContent = themedTokens.map((token) => token.content).join('')
|
||||
const extraContent = rawLine.slice(themedContent.length)
|
||||
|
||||
// 已有内容已经全部高亮,直接返回
|
||||
if (!extraContent) return themedTokens
|
||||
|
||||
// 补全剩余内容
|
||||
return [
|
||||
...themedTokens,
|
||||
{
|
||||
content: extraContent,
|
||||
offset: themedContent.length,
|
||||
color: 'inherit',
|
||||
bgColor: 'inherit',
|
||||
htmlStyle: {
|
||||
opacity: '0.35'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
interface VirtualizedRowData {
|
||||
@ -240,11 +208,43 @@ interface VirtualizedRowData {
|
||||
*/
|
||||
const VirtualizedRow = memo(
|
||||
({ rawLine, tokenLine, showLineNumbers, index }: VirtualizedRowData & { index: number }) => {
|
||||
// 补全代码行 tokens,把原始内容拼接到高亮内容之后,确保渲染出整行来。
|
||||
const completeTokenLine = useMemo(() => {
|
||||
// 如果出现空行,补一个空元素保证行高
|
||||
if (rawLine.length === 0) {
|
||||
return [
|
||||
{
|
||||
content: '',
|
||||
offset: 0,
|
||||
...plainTokenStyle
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const currentTokens = tokenLine ?? []
|
||||
const themedContentLength = currentTokens.reduce((acc, token) => acc + token.content.length, 0)
|
||||
|
||||
// 已有内容已经全部高亮,直接返回
|
||||
if (themedContentLength >= rawLine.length) {
|
||||
return currentTokens
|
||||
}
|
||||
|
||||
// 补全剩余内容
|
||||
return [
|
||||
...currentTokens,
|
||||
{
|
||||
content: rawLine.slice(themedContentLength),
|
||||
offset: themedContentLength,
|
||||
...plainTokenStyle
|
||||
}
|
||||
]
|
||||
}, [rawLine, tokenLine])
|
||||
|
||||
return (
|
||||
<div className="line">
|
||||
{showLineNumbers && <span className="line-number">{index + 1}</span>}
|
||||
<span className="line-content">
|
||||
{completeLineTokens(tokenLine ?? [], rawLine).map((token, tokenIndex) => (
|
||||
{completeTokenLine.map((token, tokenIndex) => (
|
||||
<span key={tokenIndex} style={getReactStyleFromToken(token)}>
|
||||
{token.content}
|
||||
</span>
|
||||
@ -272,6 +272,7 @@ const ScrollContainer = styled.div<{
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
line-height: ${(props) => props.$lineHeight}px;
|
||||
contain: content;
|
||||
|
||||
.line-number {
|
||||
width: var(--gutter-width, 1.2ch);
|
||||
|
||||
92
yarn.lock
92
yarn.lock
@ -4923,79 +4923,79 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/core@npm:3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/core@npm:3.7.0"
|
||||
"@shikijs/core@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/core@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/types": "npm:3.7.0"
|
||||
"@shikijs/types": "npm:3.9.1"
|
||||
"@shikijs/vscode-textmate": "npm:^10.0.2"
|
||||
"@types/hast": "npm:^3.0.4"
|
||||
hast-util-to-html: "npm:^9.0.5"
|
||||
checksum: 10c0/885c9d00712d350ab0aac0d239b26d8ba045f075abbaee5eda33c4a39fe841a1a2b0ca34391a3704cde0edcf1468ca583bea25fcbd37b7b8d6189b7afcf2a55d
|
||||
checksum: 10c0/2267cb9b056f29d93d60b5591340161db614719f1cee8e0050af8ca048eb8ee32bac51fcfe536de65dcaeadae8697fba1157c178803daae33771a2baf6bf9672
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/engine-javascript@npm:3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/engine-javascript@npm:3.7.0"
|
||||
"@shikijs/engine-javascript@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/engine-javascript@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/types": "npm:3.7.0"
|
||||
"@shikijs/types": "npm:3.9.1"
|
||||
"@shikijs/vscode-textmate": "npm:^10.0.2"
|
||||
oniguruma-to-es: "npm:^4.3.3"
|
||||
checksum: 10c0/ac792fe99a2007ab076856d32d4934e191d3b03f8bd416e96f461821580c223da73de8abc199e5eceb8b56fd47e992824b2571270e7c3d55efa6b9a6d87fec80
|
||||
checksum: 10c0/9d5e5e0fde46c9fc3813363f61b75cee9b06df10a676609b2006df344123993af94444f7564e44adb877c8299a33fa144c0bf35688370d0a70077249c2a5836b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/engine-oniguruma@npm:3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/engine-oniguruma@npm:3.7.0"
|
||||
"@shikijs/engine-oniguruma@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/engine-oniguruma@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/types": "npm:3.7.0"
|
||||
"@shikijs/types": "npm:3.9.1"
|
||||
"@shikijs/vscode-textmate": "npm:^10.0.2"
|
||||
checksum: 10c0/e1ec52ec2255e3330812084d62bde8853d20162b1cd285dbb63440d63d0b16c03b6ce6983982e41ac2fc2eceb3e2f6b2bc1c627d093482c4c3836c4fbb9567b0
|
||||
checksum: 10c0/70eb64cccb043d01f82804a0c630ce1861ab9cb0f79eca31ea550c1f9c6e7de2f37094c4c28f0fca81b26d78b77287d11c110809e7f76a59829c443abd88ef2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/langs@npm:3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/langs@npm:3.7.0"
|
||||
"@shikijs/langs@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/langs@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/types": "npm:3.7.0"
|
||||
checksum: 10c0/326e8b014e74d25ce84a63bf7fdd47d5582f85c8404d4c48d6bdacf2f32ab92ddb39b41710ee7eff3daaecbbea7ee96a6c49d427344ee8375551597c74010a81
|
||||
"@shikijs/types": "npm:3.9.1"
|
||||
checksum: 10c0/94351ef82e0a7a26351eaf70e33a5c0a48727ef052b907cb3c09ebbd3bb8fb1ef7825ae27c0ff2829888d5fb9da24eeca86c914178c354754eefd7fab70a613f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/markdown-it@npm:^3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/markdown-it@npm:3.7.0"
|
||||
"@shikijs/markdown-it@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/markdown-it@npm:3.9.1"
|
||||
dependencies:
|
||||
markdown-it: "npm:^14.1.0"
|
||||
shiki: "npm:3.7.0"
|
||||
shiki: "npm:3.9.1"
|
||||
peerDependencies:
|
||||
markdown-it-async: ^2.2.0
|
||||
peerDependenciesMeta:
|
||||
markdown-it-async:
|
||||
optional: true
|
||||
checksum: 10c0/28d7ccacf241ef9b60080f232ac352694e9f29556e27c4c874226cf222b2deac3edb6f27813f46cb6316fbcaaf1b7880a76fdd6acd6f40a36cde3b3392107449
|
||||
checksum: 10c0/54b7acbf1e12b8686a71fe22b988e1a1475d70bdca5434824f2cb75efc5fc929d9be793c7118e3d9a112589d39197e954b8d47dddbfc1e6981b05b5b1a28d98a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/themes@npm:3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/themes@npm:3.7.0"
|
||||
"@shikijs/themes@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/themes@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/types": "npm:3.7.0"
|
||||
checksum: 10c0/6887eb99b55439988edab21a1af00302eaed6ba0dd7e2bea6c844ff4dfb8879a0c6c2178ba3fcfe2dbf3fd9f3ab6105572c57ae871e147aaceaf53bcc345d0cd
|
||||
"@shikijs/types": "npm:3.9.1"
|
||||
checksum: 10c0/a061eec4d9dd147d83cda9c41b296263fab92d6113146279a244751b9f016f8af543f91c37dcefe33f47cff9f1a1d7898f78a80169947ac119617b32d16766d4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shikijs/types@npm:3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "@shikijs/types@npm:3.7.0"
|
||||
"@shikijs/types@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@shikijs/types@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/vscode-textmate": "npm:^10.0.2"
|
||||
"@types/hast": "npm:^3.0.4"
|
||||
checksum: 10c0/d7c4fcca358c0585602090e2b4ed0a3f6742b55bea340030c115cb7aa643eac79836baa095517a538d695415458bb48c08b7be7f3c8d1cf1c1c7749a58913a3f
|
||||
checksum: 10c0/c726478ae36ca078a8b9d61a9b51b83fe32b7af2cfe7ae597828b2ffccbd24858d955c49d0786af13ebd04cfbb9d192067499c410a05c41eb38da57928424076
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -7677,7 +7677,7 @@ __metadata:
|
||||
"@opentelemetry/sdk-trace-web": "npm:^2.0.0"
|
||||
"@playwright/test": "npm:^1.52.0"
|
||||
"@reduxjs/toolkit": "npm:^2.2.5"
|
||||
"@shikijs/markdown-it": "npm:^3.7.0"
|
||||
"@shikijs/markdown-it": "npm:^3.9.1"
|
||||
"@strongtz/win32-arm64-msvc": "npm:^0.4.7"
|
||||
"@swc/plugin-styled-components": "npm:^7.1.5"
|
||||
"@tanstack/react-query": "npm:^5.27.0"
|
||||
@ -7804,7 +7804,7 @@ __metadata:
|
||||
rollup-plugin-visualizer: "npm:^5.12.0"
|
||||
sass: "npm:^1.88.0"
|
||||
selection-hook: "npm:^1.0.8"
|
||||
shiki: "npm:^3.7.0"
|
||||
shiki: "npm:^3.9.1"
|
||||
strict-url-sanitise: "npm:^0.0.1"
|
||||
string-width: "npm:^7.2.0"
|
||||
styled-components: "npm:^6.1.11"
|
||||
@ -19300,19 +19300,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"shiki@npm:3.7.0, shiki@npm:^3.7.0":
|
||||
version: 3.7.0
|
||||
resolution: "shiki@npm:3.7.0"
|
||||
"shiki@npm:3.9.1, shiki@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "shiki@npm:3.9.1"
|
||||
dependencies:
|
||||
"@shikijs/core": "npm:3.7.0"
|
||||
"@shikijs/engine-javascript": "npm:3.7.0"
|
||||
"@shikijs/engine-oniguruma": "npm:3.7.0"
|
||||
"@shikijs/langs": "npm:3.7.0"
|
||||
"@shikijs/themes": "npm:3.7.0"
|
||||
"@shikijs/types": "npm:3.7.0"
|
||||
"@shikijs/core": "npm:3.9.1"
|
||||
"@shikijs/engine-javascript": "npm:3.9.1"
|
||||
"@shikijs/engine-oniguruma": "npm:3.9.1"
|
||||
"@shikijs/langs": "npm:3.9.1"
|
||||
"@shikijs/themes": "npm:3.9.1"
|
||||
"@shikijs/types": "npm:3.9.1"
|
||||
"@shikijs/vscode-textmate": "npm:^10.0.2"
|
||||
"@types/hast": "npm:^3.0.4"
|
||||
checksum: 10c0/a458d06cc0487da5916e10ab9daaf314e3c3c92024664c545bcacb58fad9bd3aa18cde90a200afe4f6632a2487014def57eb6f10f38ab6269e90f3420b724105
|
||||
checksum: 10c0/383ca4b91b0ade1df7ce8889c4abeb9bfabead53a808f11de749e44f8400b3967d8bad7aad99a8ecf7991a2e1d1c42a71b73154d12baca6deeb979b9929376cb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user