[pull] main from tldraw:main#608
Merged
Merged
Conversation
…ers) (#9347) In order to make tldraw.com files open without any animated loading state, this PR removes the editor load animations from the dotcom tla app: the fade-in shroud and the loading screens that show a spinner. The editor chrome and placeholder already appear instantly, so these animations only flashed a spinner and faded content in before the real document hard-cut in. This is scoped entirely to `apps/dotcom/client/src/tla/` — the tldraw SDK (`packages/editor`, `packages/tldraw`) is unchanged, so the default `LoadingScreen`, `DefaultSpinner`, and `.tl-loading` fade are untouched for SDK consumers. What changed: - Set `LoadingScreen: null` on the shared tla `components` object, so the file editor, local editor, and root-providers editor mount with no SDK spinner or fade. The placeholder editor's now-redundant override was folded away. - The auth gate in `useUser` no longer renders a `<LoadingScreen>` with a `<DefaultSpinner>`; it renders a blank editor surface while auth loads. - Removed the fade-in transitions from the `useIsReady` shroud (page and file-content opacity fades) and deleted a dead `.spinner` fade rule. Content now hard-cuts in once the editor is ready. Relates to #9249 ### Change type - [x] `improvement` ### Test plan 1. Open a file on tldraw.com (and a local file at `/`): the editor and its content appear with no fade-in and no spinner. 2. While signed-out/auth is loading, confirm no spinner shows — just a blank editor surface. 3. Confirm the SDK examples app still shows the default loading spinner and fade (SDK behavior unchanged). - [ ] Unit tests - [ ] End to end tests ### Code changes | Section | LOC change | | ------- | ---------- | | Apps | +10 / -37 |
In order to avoid hundreds of redundant `Image.decode()` calls when the editor mounts, this PR deduplicates icon preloads by their underlying resource. The `AssetUrlsProvider` effect preloads every icon URL, but all ~324 icon URLs point at the same SVG sprite sheet and differ only by their `#fragment` (e.g. `0_merged.svg#tool-arrow`). The fragment doesn't change the resource, so the effect was creating one `Image` and `decode()` per icon for what is really a single file. This was visible as repeated, slow work in `asset-urls.tsx` during editor load. The effect now strips the fragment and tracks preloaded resources in a `Set`, so each unique resource is decoded once. Embed icons (separate files) are unaffected and still preload individually. ### Change type - [x] `improvement` ### Test plan 1. Load the editor and confirm icons render correctly (toolbar, menus, style panel). 2. In the Performance panel, record editor load and confirm the icon preload work in `asset-urls.tsx` no longer repeats per-icon. - [ ] Unit tests - [ ] End to end tests ### Release notes - Reduce redundant icon preloading work on editor mount by deduplicating sprite-sheet preloads.
#9316) 🙇♂️ Tested with Desktop + Wacom (correctly does not enter pen mode) and iPad (correctly enters pen mode). --- In order to stop desktop graphics tablets from hijacking the editor into pen mode, this PR makes pen mode auto-enable only for stylus input that looks like direct manipulation on the display (e.g. Apple Pencil on an iPad or a Surface Pen on a touchscreen). Previously, any `pointerdown` with `pointerType === 'pen'` flipped the editor into pen mode, which then ignores touch/mouse input. That's correct for a touchscreen stylus, but wrong for an indirect desktop tablet (e.g. a Wacom Intuos) used alongside a mouse, where it would unexpectedly disable the mouse. We now distinguish direct from indirect pens using implicit pointer capture: direct-manipulation pointers receive implicit capture on `pointerdown`, so the canvas already holds capture before we call `setPointerCapture` ourselves. Indirect tablet styluses do not. This check is deliberately scoped to auto-entering pen mode — `isPen` still drives pen-specific drawing and pressure handling for all pens, so an indirect tablet stylus continues to draw with pressure; it just no longer forces pen mode. ### Change type - [x] `bugfix` ### Test plan 1. On a desktop with an indirect graphics tablet (e.g. Wacom Intuos), draw with the stylus — the editor should keep responding to mouse and touch input (pen mode stays off). 2. On an iPad with an Apple Pencil (or a touchscreen with a Surface Pen), draw with the stylus — the editor should enter pen mode and ignore palm/touch input as before. - [x] Unit tests - [ ] End to end tests ### API changes - Added optional `isPenDirect` field to `TLPointerEventInfo`, indicating whether a pen event appears to be direct-display manipulation. Drawing and pressure behavior remain driven by `isPen`. ### Code changes | Section | LOC change | | --------------- | ---------- | | Core code | +41 / -3 | | Tests | +69 / -1 | | Automated files | +1 / -0 | ### Release notes - Fix desktop graphics tablets (e.g. Wacom) incorrectly switching the editor into pen mode. Pen mode now auto-enables only for direct-display stylus input such as Apple Pencil on iPad or Surface Pen on a touchscreen.
…tion (#9352) 🙇♂️ The fractional indexing libraries we were using were doing silly things. I was never really happy that we moved to an external lib for this, it's a small thing and we benefit from just using the parts that we need and improving those. **What's changed?** This PR vendors a trimmed, base-62-specialized version of `fractional-indexing` and `jittered-fractional-indexing` (both CC0-1.0 public domain) into `packages/utils`, replacing the `jittered-fractional-indexing` dependency. tldraw only ever uses the default base-62 alphabet, so specializing away the `digits` parameter lets us hoist per-call allocations and remove redundant work on hot paths: - `validateIndexKey` (run on every IndexKey validation) now validates directly instead of generating and discarding a jittered key, which previously ran the full key generator ~31 times per call. - The jitter loop validates its two inputs once instead of re-validating both endpoints on every bisection. - `validateOrderKey` is allocation-free (no per-call `repeat`/`slice`), and digit lookups use char-code arithmetic instead of scanning the 62-character alphabet. - Jitter is reduced from 30 to 16 bits, which shortens every generated key by ~3 characters and roughly halves per-key generation work. **What prompted the change?** Index keys are generated and validated constantly — on every shape insert, reorder, and record validation — so this is a genuine hot path. The dependency's `validateOrderKey` allocated a fresh 26-character string on every call, and `validateIndexKey` was generating and throwing away a fully jittered key just to check validity. Inlining the library lets us cut that waste and drop a third-party dependency at the same time. **What do I need to know?** The public API of `@tldraw/utils` is unchanged (`getIndices*`, `getIndexBetween`, `validateIndexKey`, etc. keep their signatures); the vendored core is internal. Reducing jitter from 30 to 16 bits keeps collision probability below ~0.1% even for ~10 simultaneous inserts into the same gap, and existing keys stay valid — only newly generated keys are affected. ### Change type - [x] `improvement` ### Test plan - [x] Unit tests The existing reordering and validation suites pass unchanged. A new `fractionalIndexing.test.ts` pins byte-for-byte compatibility against the upstream library's published vectors and adds ordering/validity invariants across the full base-62 alphabet (integer carry/borrow, jittered and non-jittered generators). ### Release notes - Removed the `jittered-fractional-indexing` dependency and sped up index key generation and validation. Newly generated index keys are slightly shorter. ### Code changes | Section | LOC change | | -------------- | ---------- | | Core code | +282 / -7 | | Tests | +138 / -0 | | Config/tooling | +0 / -18 |
In order to reason about large Chrome DevTools performance traces without loading tens to hundreds of MB of JSON into context, this PR adds a `simplify-trace` agent skill that summarizes a trace into a compact, few-KB markdown report. The skill ships a Node script (`scripts/simplify-trace.mjs`) plus `SKILL.md` guidance on when and how to use it. The report surfaces the work taking too long or happening too often: long tasks (main-thread jank, with offsets), hottest event types by self time, most frequent event types, hottest JS functions (with `file:line` from the embedded V8 CPU profile), and a self-time-by-category breakdown. Opt-in sections cover a per-second main-thread timeline, a network waterfall, and WebSocket lifecycle. `--window START-END` scopes the whole report to a time slice, which is how you isolate a single action in an otherwise idle "what happens when I do X" recording. The script is read-only — it summarizes the trace and never modifies it. ### Change type - [x] `other` (internal agent tooling) ### Test plan 1. Run the script on a Chrome DevTools trace: `node skills/simplify-trace/scripts/simplify-trace.mjs <trace.json> --out /tmp/report.md` 2. Confirm the markdown report includes the summary header, long tasks, hottest events, frequent events, hottest JS functions, and categories. 3. Re-run with `--window START-END`, `--only timeline`, and `--list` and confirm scoping and section selection work. ### Code changes | Section | LOC change | | -------------- | ---------- | | Config/tooling | +549 / -0 | Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )