Decrease the number of elements by 3. (#3283)

When geo shape has no url or text we don't show the html container
containing the label and link. This results in 3 fewer dom nodes per
empty geo shape (going from 7 to 4). Similarly for an arrow without the
text label we go from 13 to 10.

First paint experience with 2000 empty rectangle shapes
Before: 1.5-1.6s
After: 1.2-1.3s

2000 rectangles shapes with text is similar between the two, around
3.6s.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know

### Release Notes

- Reduce the number of rendered dom nodes for geo shapes and arrows
without text.
This commit is contained in:
Mitja Bezenšek 2024-03-28 10:49:29 +01:00 committed by GitHub
parent d399c027fd
commit 41b5fffa2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 31 deletions

View file

@ -530,6 +530,8 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
if (!info?.isValid) return null if (!info?.isValid) return null
const labelPosition = getArrowLabelPosition(this.editor, shape) const labelPosition = getArrowLabelPosition(this.editor, shape)
const isEditing = this.editor.getEditingShapeId() === shape.id
const showArrowLabel = isEditing || shape.props.text
return ( return (
<> <>
@ -539,15 +541,17 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
shouldDisplayHandles={shouldDisplayHandles && onlySelectedShape === shape} shouldDisplayHandles={shouldDisplayHandles && onlySelectedShape === shape}
/> />
</SVGContainer> </SVGContainer>
<ArrowTextLabel {showArrowLabel && (
id={shape.id} <ArrowTextLabel
text={shape.props.text} id={shape.id}
font={shape.props.font} text={shape.props.text}
size={shape.props.size} font={shape.props.font}
position={labelPosition.box.center} size={shape.props.size}
width={labelPosition.box.w} position={labelPosition.box.center}
labelColor={shape.props.labelColor} width={labelPosition.box.w}
/> labelColor={shape.props.labelColor}
/>
)}
</> </>
) )
} }

View file

@ -383,33 +383,42 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
const { id, type, props } = shape const { id, type, props } = shape
const { labelColor, fill, font, align, verticalAlign, size, text } = props const { labelColor, fill, font, align, verticalAlign, size, text } = props
const isEditing = this.editor.getEditingShapeId() === id
const showHtmlContainer = isEditing || shape.props.url || shape.props.text
return ( return (
<> <>
<SVGContainer id={id}> <SVGContainer id={id}>
<GeoShapeBody shape={shape} /> <GeoShapeBody shape={shape} />
</SVGContainer> </SVGContainer>
<HTMLContainer {showHtmlContainer && (
id={shape.id} <HTMLContainer
style={{ overflow: 'hidden', width: shape.props.w, height: shape.props.h + props.growY }} id={shape.id}
> style={{
<TextLabel overflow: 'hidden',
id={id} width: shape.props.w,
type={type} height: shape.props.h + props.growY,
font={font} }}
fontSize={LABEL_FONT_SIZES[size]} >
lineHeight={TEXT_PROPS.lineHeight} <TextLabel
fill={fill} id={id}
align={align} type={type}
verticalAlign={verticalAlign} font={font}
text={text} fontSize={LABEL_FONT_SIZES[size]}
labelColor={labelColor} lineHeight={TEXT_PROPS.lineHeight}
wrap fill={fill}
bounds={props.geo === 'cloud' ? this.getGeometry(shape).bounds : undefined} align={align}
/> verticalAlign={verticalAlign}
{shape.props.url && ( text={text}
<HyperlinkButton url={shape.props.url} zoomLevel={this.editor.getZoomLevel()} /> labelColor={labelColor}
)} wrap
</HTMLContainer> bounds={props.geo === 'cloud' ? this.getGeometry(shape).bounds : undefined}
/>
{shape.props.url && (
<HyperlinkButton url={shape.props.url} zoomLevel={this.editor.getZoomLevel()} />
)}
</HTMLContainer>
)}
</> </>
) )
} }