Repository navigation
Conversation
This adds a little bit of convenience when developping locally. Server started: - http://localhost:8080 - http://localhost:8080?developerMode
- Use gridlayout to avoid fixd settings panel height and better adjust to window height - Indent settings without chekcbox - Better style select elements - Use consistent spacing around checkbox in settings and suite selection
Migrate webpack configs from node modules to standard mjs modules.
We use step and test interchangeably which is rathe confusing. This PR changes the runner code to use step eclusively.
Based on top of WebKit#537 this renames TestInvoker to StepScheduler which is a bit more descriptive.
- "npm run format" only formats changed files compared to upstream - "npm run format:all" formats all files (existing behavior)
Let's use a bit more modern code and try to avoid node modules in favour of mjs modules.
- Update selenium-webdriver to latest version - When available use webdriver bidi to forward console logging to the test script
This is more consistent with the rest of the codebase.
Run the the end2end tests with an additionaly retry run to mitigatate flaky browsers with selenium. This can be further configured with a new --retry flag.
- Use the temp currentSteppingResolver varialbe in places we modiify the _steppingResolver to avoid acessing the oudated version - Add an explicti "Finished" step so we can inspect the final state of a workload instead of jumping directly to the setup of the next one
The string-based concateation was rather brittle and can cause subtle bugs. - Fix issue where hash and url params were not merged properly - Add warnUnused argument to Params to only warn at top-level
…ponents and dataset, resolve Q-IDs, and pass all unit tests
Instead of storing suites partially in resources/ and experimental, let's use a more consistent naming scheme that makes it more clear where which code lives - "resources/" runner and shared helpers - "suites/" contains the default suites - "suites-experimental/" contains the experimental suites
…to suggestions panel
…yout and JS virtual scrolling
…put borders, and align actions width
- Add package validation (and fix versions identifiers in package.json files) - Add metrics unittests - Add basic translations data unittest
Use the same button style for home, about, instructions and details page.
This way we can avoid a few duplicate property loads in the runner.
- --cache without args uses cache-control 3600 header - --cache=DURATION for explcit cache duration - use --cache for test server to speed up runs a bit
A previous PR caused some accidental CSS rule mismatch which caused the main start button to be small.
In a previous refactoring we accidentally broke the summary page. - Accumulate overall total proprely - Fix broken destructuring for total and prepare time
…Kit#573) - Add explicit BENCHMARK_STATE as preparation for ServiceWorker-based preloading - Use new state to early-abort runs if there are toplevel errors - Add explicit top-level error and unhandledrejection handlers to surfce errors better
The button unification PR accidentally raised the button bar above the developer menu. Adjusting the z-index fixes this.
…ocessing throughput of modern web media APIs. --- Tests standard video playback initialization latency via Media Source Extensions (MSE) to simulate typical streaming user journeys on platforms like YouTube or Vimeo. The time measured is from the `play` button clicked to the first video frame painted on the screen. We use `requestVideoFrameCallback` to ensure that the video is painted on the screen. Measures the latency of performing a quick skip-ahead action within an already loaded media stream. This simulates a common user interaction, such as scrubbing through a video timeline or double-tapping right to skip forward on a streaming platform. The time measured is from the `seek` button clicked to the first video frame painted on the screen after seeking. We use `requestVideoFrameCallback` to ensure that the video is painted on the screen after seeking. --- Tests real-time video encoding and decoding pipelines using WebCodecs. While the UI simulates a Video Chat call, WebRTC is not tested; the focus is purely on measuring VideoEncoder and VideoDecoder throughput. The time measured is from the `video-benchmark` button clicked until all video frames have been encoded, decoded, and the session is torn down. Tests real-time audio encoding, decoding using WebCodecs and audio routing and effects processing using WebAudio. It measures the browser's efficiency in processing audio streams and applying standard audio nodes. The time measured is from the `voice-benchmark` button clicked until all audio frames have been encoded/decoded and the WebAudio offline rendering completes.
Exercises chat-room switching in a two-pane chat UI, so timeline teardown/rebuild cost can be profiled. Original React + Vite code with deterministic, server-free fixtures and no third-party assets. Experimental, so it is off by default and does not affect the official score. SwitchRooms uses flushSync so each programmatic click commits one room switch.
flushSync stopped React 18 batching a burst of programmatic clicks into one deferred render, but it is not what a real app does and it bypasses the concurrent scheduler this workload exists to exercise. The switch is a plain state update now, with the step yielding a task between clicks, which makes the suite async. The yield is a MessageChannel round-trip: an async step is awaited inside the measured window, so setTimeout(0)'s clamp would be reported as workload time, and a microtask would keep all 30 switches in one task. Driving 30 switches: microtask 329ms, flushSync 348ms, MessageChannel 397ms, setTimeout(0) 427ms.
Chat clients open a room at its most recent message; the timeline mounted at offset 0. A layout effect now assigns scrollTop = scrollHeight after commit, so SwitchRooms measures mount plus the scroll to bottom. Not flex-direction: column-reverse, which inverts scrollTop semantics in ways browsers have disagreed on, and later steps drive scrollTop explicitly.
…ctive Bodies were a single plain sentence, so rows were near-uniform in height and a windowing timeline built on that would inherit an unrealistically easy height model. They are now structured blocks -- paragraphs, code, blockquotes, lists, with inline code, links and @mention/#room pills -- giving 48 distinct row heights over 150 rows. Generation moves to a Math.imul integer hash so fields derive independently from the seed. Reaction pills, room pills and reply quotes become real controls, with state in components so the fixtures stay immutable across iterations. The reply jump assigns scrollTop from measured rects rather than scrollIntoView, keeping smooth scrolling out of a timed step. Also fixes senders never repeating, so grouping never triggered, and room pills slugifying 20 names against 40 rooms. SwitchRooms grows from ~245ms to ~450ms, the cost of mounting 150 rich rows.
The app was a read-only viewer. There is now a text input and a Send button below the timeline; sending appends to the end and scrolls to bottom. Sent messages live in Timeline state rather than the fixtures, so the generated data stays immutable and rooms do not grow across iterations. Timestamps continue from the room's last message rather than reading the clock. Enter is an explicit onKeyDown, since a dispatched keydown triggers no default action. No new step: SwitchRooms is unchanged, so this is app surface only.
Message bodies gain an image attachment and an unfurl card block, covering about 11% of messages. Artwork is SVG data URIs built from a palette and shape variant by a new graphics module, so the workload still ships no image assets. The URIs are memoized on a reduced palette/variant key -- with the raw hashes every message got a distinct gradient id, so the browser decoded 652 images instead of 127. Images carry explicit width and height, or a row would resize once the image decoded and invalidate the height cache. Also fixes bullet lists repeating a line about 13% of the time. Row heights now span 24px to 278px with 58 distinct values, up from 229px and 48. SwitchRooms grows from ~367ms to ~442ms.
Speedometer has almost no scroll coverage: across the 32 default suites the only scrolling inside a timed step is a single scrollIntoView. A chat timeline is the natural vehicle for that, but only once it is windowed. Rooms grow from 150 to 1500 messages and the timeline mounts ~15 rows. The virtualizer is hand-rolled, since a generic one assumes a height it can know up front and a chat row's depends on how its text wraps. The new height model estimates, measures, caches and corrects, keeping prefix sums so an offset can be turned back into a row index without touching the DOM. Three constraints it has to respect -- the scroller's height lagging the model by a commit, the row estimate having to sit under the real mean, and overflow-anchor having to be off -- are documented at their sites. ScrollTimeline is the new step, driving explicit offsets back through history and then in long strides. SwitchRooms is unchanged but costs ~4.5x less. PageElement gains scrollTop/scrollHeight/clientHeight, since scrollIntoView cannot reach an unmounted row.
Preserving the scroll position while content is inserted above the viewport is the chat and feed pattern nothing else in Speedometer exercises, and the one real clients visibly get wrong. A room now opens on the newest 300 of its 1500 messages and fetches 120 more whenever a scroll lands within a viewport of the top. The height model grows at the front as well as the end: a row keeps its index when older history arrives, so measured heights stay valid and only the offsets shift, uniformly, which makes the correction exact. Anchored by hand rather than with the browser's scroll anchoring, which would apply a second correction for the same insertion. LoadOlderMessages is the new step; ScrollTimeline stops one stride short of the top so the two stay independent. Following a reply quote can now load history too.
A profile shows a ~14ms nursery collection landing inside a timed step in three of the thirty measured windows, and those three are the slowest iteration of their step. The fixture build is not itself measured, but it pushes ~117MB of permanently-live data through the nursery per iteration, and a minor GC costs what it has to promote. The fixture now shares what it can: bodies come from a pool of 2048 rather than one per message, reaction rows collapse to the nine distinct values they always had, and timestamps and initials stop being rebuilt 60,000 times. The pool is drawn from the same seed space, so the spread of row heights is unchanged. The per-message preview string is gone; nothing rendered it. Building the fixtures drops from 197ms to 31ms and retains 14MB instead of 117MB, taking the unmeasured prepare phase from 335ms to 48ms per iteration.
Turning a message id back into a row index is only needed when a reply quote is clicked, and neither a scroll nor a room switch clicks one. Building it during render rebuilt a map over the room's whole history on every switch, inside the timed step, where the profile puts it at 8.8% of SwitchRooms -- the largest single piece of the app's own JavaScript in the run. With the fixture sharing beneath it, this takes the content process from 1.04GB of net allocation to 459MB, minor collections from 77 to 16, and the ones inside a timed step from 14.1ms to 7.2ms on average. What is left is React's own reconciliation filling the nursery, which is the work the steps exist to measure.
Per-render chrome that chat clients carry and this workload had none of: a labelled rule where the conversation crosses a day, and a marker above the first message the reader has not seen. Neither is a row of its own -- a row here is one message, and the height cache, spacers and offset search are all indexed by message index -- so both are drawn inside the row they belong to, keyed off the message array rather than the mounted window. Day lengths now vary between 8 and 56 messages. At a fixed size the boundary always landed just above the newest page, so no room opened with a separator in view; twenty of the forty now do. Cost is noise: 100.65ms -> 105.00ms over ten Firefox iterations against a +/-20ms spread.
Output of `npm run build` in suites-experimental/chat-room. Build artifacts only, so it can be dropped and regenerated whenever the source commits below it change.
…or' into upstream
…loads' into upstream
✅ Deploy Preview for mozilla-speedometer-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Add the sp4 tag to only run new workloads