perf(web): inline whale image into CSS at build time

This commit is contained in:
imccyu committed 2026-09-29 16:03:26 +08:00
1 parent 6a0f36cdea
commit bb7455da04
4 files changed
+12 -21

No files matched your search

@@ -168,7 +168,7 @@
position: absolute;
inset: 0;
background: currentColor;
mask: var(--dsh-whale-image) center / 100% 100% no-repeat;
mask: url('./[email protected]') center / 100% 100% no-repeat;
mask-mode: alpha;
will-change: transform;
}
@@ -1,12 +1,8 @@
/** Native SVG contour animation for the whale Chat shows while the Session runs. */
import type { CSSProperties } from 'react'
import whaleImage from './[email protected]'
import css from './ChatView.module.css'
const REST_PATH = 'M8.844 13.742C8.967 12.328 8.45 10.4 8.45 9.65C8.45 8.94 8.88 8.43 9.6 8.43C11.285 8.43 12.106 8.281 12.685 8.104C13.71 7.791 14.585 6.768 15.055 5.945C15.137 5.803 14.99 5.641 14.829 5.671C13.829 5.86 12.828 5.376 11.827 4.978C10.659 4.514 9.491 4.707 8.935 4.876C8.805 4.915 8.658 4.819 8.636 4.686C8.468 3.643 7.405 2.615 5.498 2.238C4.54 2.048 3.748 1.574 3.347 1.202C3.252 1.113 3.088 1.125 3.03 1.242C2.628 2.059 2.168 3.82 5.248 6.115C5.82 6.494 6.31 6.785 6.574 7.637C6.72 8.104 6.157 9.168 6.061 9.368C5.157 11.27 5.089 12.19 4.926 13.742'
/** Same cubic segments in every pose keep both tail-base endpoints stationary. */
const IMAGE_STYLE = { '--dsh-whale-image': `url("${whaleImage}")` } as CSSProperties
const REST_PATH = 'M8.844 13.742C8.967 12.328 8.45 10.4 8.45 9.65C8.45 8.94 8.88 8.43 9.6 8.43C11.285 8.43 12.106 8.281 12.685 8.104C13.71 7.791 14.585 6.768 15.055 5.945C15.137 5.803 14.99 5.641 14.829 5.671C13.829 5.86 12.828 5.376 11.827 4.978C10.659 4.514 9.491 4.707 8.935 4.876C8.805 4.915 8.658 4.819 8.636 4.686C8.468 3.643 7.405 2.615 5.498 2.238C4.54 2.048 3.748 1.574 3.347 1.202C3.252 1.113 3.088 1.125 3.03 1.242C2.628 2.059 2.168 3.82 5.248 6.115C5.82 6.494 6.31 6.785 6.574 7.637C6.72 8.104 6.157 9.168 6.061 9.368C5.157 11.27 5.089 12.19 4.926 13.742'
/**
* Loop the tail every three seconds after a 0.3s delay.
@@ -14,7 +10,7 @@ const IMAGE_STYLE = { '--dsh-whale-image': `url("${whaleImage}")` } as CSSProper
*/
export function RunningWhaleTail() {
return (
<span className={css.runningIcon} style={IMAGE_STYLE} aria-hidden="true">
<span className={css.runningIcon} aria-hidden="true">
<span className={css.runningWhaleAnimated} />
<svg className={css.runningWhaleStill} width="100%" height="100%" viewBox="0 0 16 16" fill="none">
<path d={REST_PATH} stroke="currentColor" strokeWidth={1} />
-5
View File
@@ -4,8 +4,3 @@ declare module '*.module.css' {
}
declare module '*.css'
declare module '*[email protected]' {
const url: string
export default url
}
+9 -9
View File
@@ -3,20 +3,20 @@ import { readFile } from 'node:fs/promises'
import { fileURLToPath } from 'node:url'
const bundle = clientBundle('@deepseek-ai/dsh-client-ui-chat', ['lib/types/index.js'])
const whaleImage = fileURLToPath(new URL('./src/client/chat/[email protected]', import.meta.url)).replaceAll('\\', '/')
const stylesheet = fileURLToPath(new URL('./src/client/chat/ChatView.module.css', import.meta.url)).replaceAll('\\', '/')
const whaleImage = fileURLToPath(new URL('./src/client/chat/[email protected]', import.meta.url))
export default ((options) => bundle(options).map(config => ({
...config,
plugins: [...(config.plugins ?? []), {
name: 'chat-whale-image',
resolveId(source: string) {
return source === './[email protected]' ? whaleImage : null
},
async load(id: string) {
if (id !== whaleImage) return null
this.addWatchFile(id)
const image = await readFile(id)
return `export default ${JSON.stringify(`data:image/png;base64,${image.toString('base64')}`)}`
async transform(code: string, id: string) {
if (id.replaceAll('\\', '/') !== `\0dsh-css:${stylesheet}.mjs`) return null
const imageUrl = './[email protected]'
if (!code.includes(imageUrl)) return null
this.addWatchFile(whaleImage)
const image = await readFile(whaleImage)
return { code: code.replaceAll(imageUrl, `data:image/png;base64,${image.toString('base64')}`), map: null }
},
}],
}))) satisfies typeof bundle