Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions suites-experimental/social-network/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
node_modules

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
pnpm-debug.log*

# dist-ssr / local
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.sw?
70 changes: 70 additions & 0 deletions suites-experimental/social-network/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
## Description

Social feeds are among the most used pages on the web. A reader scrolls a long,
virtualized list of rich stories, opens one to read its comments, types a reply,
visits a profile and goes back, and searches, all on a page that also runs a
lot of instrumentation: every callback is wrapped, every interaction is timed,
and a steady stream of analytics events is batched, compressed and sent.

This workload is an original, self-contained React 19 app built to reproduce
that mix. It was modeled on the kind of work a large production feed does,
measured from the outside with performance traces, and is **not** derived from
any existing product's source code. It ships no third-party assets: all names,
text and pictures are generated or written for it.

## What are we testing

- React reconciliation of deep, many-component stories, mounting and
unmounting as a virtualized feed scrolls, with layout effects that measure
each unit
- A normalized client cache fed by streamed, chunked responses with deferred
fragments, and per-record subscriptions through `useSyncExternalStore`
- Transitions for page navigation, and synchronous scroll-driven updates
(`flushSync`) for the feed window
- Forced layout from viewability checks (`getBoundingClientRect`,
`elementFromPoint`), auto-growing text areas and scroll-depth tracking
- Analytics work: error-guard wrappers, event enrichment, sampling, batching,
LZW compression and checksums, User Timing marks and feature-gate exposures
- Many small atomic CSS classes per element (Tailwind), masked SVG avatars
and generated SVG photos

## How are we testing

All content is generated deterministically at load time from fixed seeds (no
`Math.random`, no `Date.now`). An in-page server answers each query with
GraphQL-shaped JSON split into chunks, delivered one task apiece through a
`MessageChannel`, so every iteration renders identical data without a network.

The app fires a window event when the result of an interaction has committed
(`feed-page-loaded`, `post-dialog-ready`, `search-results`, …), and the steps
wait on those instead of on timers.

- `RefreshHomeFeed`: clicks Home while on the home page, which fetches a new
ranking and remounts the feed.
- `LoadMoreStories`: reads down the feed one story at a time, loading the next
page whenever the end comes into range.
- `ExpandStoryTexts`: scrolls back to the top, expanding every truncated story.
- `OpenPostDialog`: opens a busy thread in the post dialog.
- `ExpandCommentReplies`: expands every reply thread on the first page.
- `ChangeCommentOrder`: switches the comment order to "All comments".
- `LoadMoreComments`: scrolls the dialog to load more pages of comments.
- `TypeComment`: types a comment key by key, with a mention typeahead,
emoticon replacement and highlighting.
- `ClosePostDialog`: closes the dialog and restores focus.
- `OpenOwnProfile`: navigates to the viewer's profile and scrolls through it.
- `BackToHomeFeed`: returns to the cached home feed at its old position.
- `SearchTypeahead`: types a name into search; each key filters the local
index and asks the server.
- `OpenHeaderMenus`: opens and closes the menu, chats, notifications and
account popovers.

## Developer Documentation

The app was created with Vite + React 19 and Tailwind CSS. It can be previewed
during development with `npm run dev`. To update the files run in the harness
you have to run `npm run build`, which regenerates the committed `dist/`
directory.

The built workload can be loaded within the harness at e.g.
`http://localhost:8080/?developerMode&suites=SocialNetwork-React`, or directly at
`http://localhost:8080/suites-experimental/social-network/dist/index.html`.
1 change: 1 addition & 0 deletions suites-experimental/social-network/dist/assets/index.css

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions suites-experimental/social-network/dist/assets/index.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions suites-experimental/social-network/dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Commons</title>
<script>
// This hack allows to capture the work normally happening in a rAF. We
// may be able to remove it if the runner improves.
window.requestAnimationFrame = (cb) => window.setTimeout(cb, 0);
window.cancelAnimationFrame = window.clearTimeout;
// Disable requestIdleCallback until WebKit / Safari supports it.
window.requestIdleCallback = undefined;
window.cancelIdleCallback = undefined;
</script>
<script type="module" crossorigin src="./assets/index.js"></script>
<link rel="stylesheet" href="./assets/index.css">
</head>
<body>
<div id="root"></div>

</body>
</html>
4 changes: 4 additions & 0 deletions suites-experimental/social-network/dist/resources.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
assets/index.css
assets/index.js
assets/index.js.map
index.html
21 changes: 21 additions & 0 deletions suites-experimental/social-network/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Commons</title>
<script>
// This hack allows to capture the work normally happening in a rAF. We
// may be able to remove it if the runner improves.
window.requestAnimationFrame = (cb) => window.setTimeout(cb, 0);
window.cancelAnimationFrame = window.clearTimeout;
// Disable requestIdleCallback until WebKit / Safari supports it.
window.requestIdleCallback = undefined;
window.cancelIdleCallback = undefined;
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading
Loading