perf: demand-load mobile workspace features (Closes #1468)
CI / lint (pull_request) Successful in 3m49s
CI / build-release (pull_request) Successful in 6s
CI / browser-journey (pull_request) Failing after 9m26s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-27 11:47:09 +00:00
1 parent 2a44cf20fc
commit 5d9cec1dd7
7 files changed
+204 -40

No files matched your search

+41 -12
View File
@@ -41,6 +41,10 @@ def test_release_artifact_guides_an_empty_mobile_account_to_first_work(
page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
page.locator("#submit-sign-in").click()
page.wait_for_url(origin + "/", wait_until="networkidle")
page.evaluate(
"async () => { const lifecycle = await window.stackchainWorkspaceLifecycle; "
"await lifecycle.hydrateWorkspace(); await lifecycle.workspaceReady; }"
)
expect(page.locator("#my-work-status")).to_contain_text("No assigned work")
page.locator('[data-mobile-task="work"]').click()
@@ -100,7 +104,12 @@ def test_release_artifact_guides_an_empty_mobile_account_to_first_work(
fresh_page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
fresh_page.locator("#submit-sign-in").click()
fresh_page.wait_for_url(origin + "/", wait_until="networkidle")
fresh_page.evaluate(
"async () => { const lifecycle = await window.stackchainWorkspaceLifecycle; "
"await lifecycle.hydrateWorkspace(); await lifecycle.workspaceReady; }"
)
expect(fresh_page.locator("#my-work-status")).to_contain_text("No assigned work")
fresh_page.wait_for_load_state("networkidle")
assert fresh_page.evaluate(
"localStorage.getItem('stackchain.first-task.v1:timmy')"
) == "complete"
@@ -128,6 +137,7 @@ def test_release_artifact_bootstraps_mobile_home_and_returns_from_insights(
browser_errors: list[str] = []
failed_responses: list[str] = []
workspace_requests: list[str] = []
optional_workspace_requests: list[str] = []
launch_transfer_events: list[str] = []
live_requests: list[str] = []
@@ -171,6 +181,12 @@ def test_release_artifact_bootstraps_mobile_home_and_returns_from_insights(
)
if "feature-work-core-" in request.url else None,
)
page.on(
"request",
lambda request: optional_workspace_requests.append(request.url)
if "feature-today-timer-" in request.url or "feature-planning-" in request.url
else None,
)
page.on(
"requestfinished",
lambda request: launch_transfer_events.append("core-finished")
@@ -184,6 +200,7 @@ def test_release_artifact_bootstraps_mobile_home_and_returns_from_insights(
)
page.goto(origin + "/", wait_until="networkidle")
assert optional_workspace_requests == []
page.locator('input[name="device_label"]').fill("Home bootstrap release phone")
page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
live_requests.clear()
@@ -194,9 +211,24 @@ def test_release_artifact_bootstraps_mobile_home_and_returns_from_insights(
), launch_transfer_events
expect(page.locator("#my-work-status")).to_contain_text("2")
assert optional_workspace_requests == []
revisionless_live_requests = [url for url in live_requests if "?" not in url]
assert len(revisionless_live_requests) == 1, live_requests
initial_live_requests = len(live_requests)
page.locator("#work-settings-toggle").click()
tomorrow = page.locator("#plan-tomorrow")
expect(tomorrow).to_be_visible()
assert len(optional_workspace_requests) == 2, optional_workspace_requests
tomorrow_bounds = tomorrow.bounding_box()
assert tomorrow_bounds and tomorrow_bounds["height"] >= 44
tomorrow.click()
expect(page.locator("#plan-today-sheet")).to_be_visible()
expect(page.locator("#plan-today-title")).to_have_text("Plan Tomorrow")
expect(page.locator("#save-and-start-today")).to_be_hidden()
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
page.locator("#cancel-plan-today").click()
page.evaluate(
"""
() => {
@@ -226,18 +258,6 @@ def test_release_artifact_bootstraps_mobile_home_and_returns_from_insights(
bounds = control.bounding_box()
assert bounds and bounds["height"] >= 44
page.locator("#work-settings-toggle").click()
tomorrow = page.locator("#plan-tomorrow")
expect(tomorrow).to_be_visible()
tomorrow_bounds = tomorrow.bounding_box()
assert tomorrow_bounds and tomorrow_bounds["height"] >= 44
tomorrow.click()
expect(page.locator("#plan-today-sheet")).to_be_visible()
expect(page.locator("#plan-today-title")).to_have_text("Plan Tomorrow")
expect(page.locator("#save-and-start-today")).to_be_hidden()
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
page.locator("#cancel-plan-today").click()
page.locator('[data-mobile-task="queues"]').click()
page.locator(".mobile-queue-all summary").click()
delivery_queue = page.locator('[data-mobile-queue="delivery"]')
@@ -361,6 +381,7 @@ def test_release_artifact_recovers_a_transient_workspace_request_in_place(tmp_pa
page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
page.locator("#submit-sign-in").click()
page.wait_for_url(origin + "/", wait_until="networkidle")
page.locator('[data-mobile-task="find"]').click()
page.wait_for_timeout(1500)
resources = page.evaluate(
@@ -406,6 +427,10 @@ def test_release_artifact_keeps_mobile_delivery_recovery_single_flight(tmp_path:
page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
page.locator("#submit-sign-in").click()
page.wait_for_url(origin + "/", wait_until="networkidle")
page.evaluate(
"async () => { const lifecycle = await window.stackchainWorkspaceLifecycle; "
"await lifecycle.hydrateWorkspace(); await lifecycle.workspaceReady; }"
)
page.evaluate(
"""
@@ -508,6 +533,10 @@ def test_release_artifact_reviews_and_downloads_mobile_agenda_snapshot(
page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
page.locator("#submit-sign-in").click()
page.wait_for_url(origin + "/", wait_until="networkidle")
page.evaluate(
"async () => { const lifecycle = await window.stackchainWorkspaceLifecycle; "
"await lifecycle.hydrateWorkspace(); await lifecycle.workspaceReady; }"
)
page.locator('[data-mobile-task="queues"]').click()
page.locator('[data-mobile-queue="agenda"]').click()
+14 -1
View File
@@ -33,6 +33,15 @@ def test_page_runtime_is_one_deterministic_content_addressed_bundle(tmp_path):
assert first.runtime_name.startswith("runtime-")
assert first.runtime_name.endswith(".js")
assert len(gzip.compress(first.runtime_bytes, mtime=0)) <= 100 * 1024
initial_mobile_javascript = (
len(first.runtime_gzip_bytes)
+ len(first.feature_bundles["work-core"].runtime_gzip_bytes)
)
assert initial_mobile_javascript <= 60 * 1024
assert (
len(first.feature_bundles["today-timer"].runtime_gzip_bytes)
+ len(first.feature_bundles["planning"].runtime_gzip_bytes)
) > initial_mobile_javascript
changed_frontend = tmp_path / "frontend"
shutil.copytree(FRONTEND, changed_frontend)
@@ -100,9 +109,13 @@ def test_product_workflows_are_stable_lazy_feature_chunks(tmp_path):
)
optional_block = optional_block.split("];", 1)[0]
assert f"BASE + '{first.feature_bundles['today-timer'].runtime_name}'" not in shell_block
demand_loaded = {"today-timer", "planning"}
for name, bundle in first.feature_bundles.items():
assert f"BASE + '{bundle.runtime_name}'" not in shell_block
assert f"BASE + '{bundle.runtime_name}'" in optional_block
if name in demand_loaded:
assert f"BASE + '{bundle.runtime_name}'" not in optional_block
else:
assert f"BASE + '{bundle.runtime_name}'" in optional_block
changed_frontend = tmp_path / "frontend"
shutil.copytree(FRONTEND, changed_frontend)
+73 -10
View File
@@ -19,7 +19,7 @@ const loadWorkspace = require({json.dumps(str(BOOTSTRAP))});
return json.loads(completed.stdout)
def test_workspace_bootstrap_loads_content_addressed_feature_before_startup():
def test_workspace_bootstrap_demand_loads_optional_features_after_work_core():
result = run_bootstrap("""
const status={textContent:''};
const document={
@@ -33,11 +33,14 @@ const document={
};
const requested=[];
const createLoader=options=>({load:async name=>{requested.push(name + ':' + options.urls[name]);}});
await loadWorkspace({document,createLoader});
console.log(JSON.stringify({requested,status:status.textContent}));
const lifecycle=await loadWorkspace({document,createLoader});
const before=requested.slice();
await lifecycle.hydrateWorkspace?.();
console.log(JSON.stringify({before,after:requested,status:status.textContent}));
""")
assert result == {
"requested": [
"before": ["work-core:feature-work-core-123.js"],
"after": [
"work-core:feature-work-core-123.js",
"today-timer:feature-workspace-abc.js",
"planning:feature-planning-def.js",
@@ -46,7 +49,65 @@ console.log(JSON.stringify({requested,status:status.textContent}));
}
def test_workspace_bootstrap_returns_after_work_core_while_optional_features_hydrate():
def test_workspace_bootstrap_hydrates_once_and_replays_dependent_mobile_action():
result = run_bootstrap("""
const listeners={}; const requested=[];
const document={
querySelector(selector) {
const match=selector.match(/stackchain-feature-([^\"]+)/);
return match ? {content:'feature-' + match[1] + '.js'} : null;
},
addEventListener(name,callback,capture){listeners[name]={callback,capture};},
removeEventListener(name,callback,capture){
if(listeners[name]?.callback===callback && listeners[name]?.capture===capture) delete listeners[name];
},
};
const createLoader=()=>({load:async name=>{
requested.push(name);
if(name==='today-timer') setImmediate(()=>{
actionReady=true;
lifecycle.markWorkspaceReady?.();
});
}});
let lifecycle=await loadWorkspace({document,createLoader});
let prevented=0,stopped=0,replayed=0,actionReady=false,replayedReady=false;
const target={
closest(selector){return selector.includes('data-mobile-task') ? this : null;},
click(){replayed++; replayedReady=actionReady;},
};
await listeners.click?.callback({target,preventDefault(){prevented++;},stopImmediatePropagation(){stopped++;}});
console.log(JSON.stringify({requested,prevented,stopped,replayed,replayedReady,listening:Boolean(listeners.click)}));
""")
assert result == {
"requested": ["work-core", "today-timer", "planning"],
"prevented": 1,
"stopped": 1,
"replayed": 1,
"replayedReady": True,
"listening": False,
}
def test_workspace_bootstrap_hydrates_immediately_for_deep_link():
result = run_bootstrap("""
const requested=[];
const document={
querySelector(selector) {
const match=selector.match(/stackchain-feature-([^\"]+)/);
return match ? {content:'feature-' + match[1] + '.js'} : null;
},
addEventListener(){},
};
const window={location:{hash:'#/my-work/today'},addEventListener(){},removeEventListener(){}};
const createLoader=()=>({load:async name=>{requested.push(name);}});
const lifecycle=await loadWorkspace({document,window,createLoader});
await lifecycle.deepLinkReady;
console.log(JSON.stringify({requested}));
""")
assert result == {"requested": ["work-core", "today-timer", "planning"]}
def test_workspace_bootstrap_returns_after_work_core_before_optional_features_hydrate():
result = run_bootstrap("""
const document={querySelector(selector) {
const match=selector.match(/stackchain-feature-([^\"]+)/);
@@ -60,12 +121,13 @@ const createLoader=()=>({load:name=>{
}});
const lifecycle=await loadWorkspace({document,createLoader});
const returned=requested.slice();
const hydration=lifecycle.hydrateWorkspace();
releases['today-timer'](); releases.planning();
await lifecycle.optionalReady;
await hydration;
console.log(JSON.stringify({returned,settled:requested}));
""")
assert result == {
"returned": ["work-core", "today-timer", "planning"],
"returned": ["work-core"],
"settled": ["work-core", "today-timer", "planning"],
}
@@ -81,7 +143,8 @@ const document={querySelector(selector) {
}};
const createLoader=()=>({load:async()=>{attempts++; if (attempts === 1) throw new Error('brief outage');}});
const schedule=callback=>{callback();};
await loadWorkspace({document,createLoader,schedule});
const lifecycle=await loadWorkspace({document,createLoader,schedule});
await lifecycle.hydrateWorkspace();
console.log(JSON.stringify({attempts,status:status.textContent,retryHidden:retry.hidden}));
""")
assert result == {"attempts": 4, "status": "", "retryHidden": True}
@@ -107,7 +170,7 @@ await Promise.all([first,second,loading]);
console.log(JSON.stringify({attempts,reloads,offered,status:status.textContent,retryHidden:retry.hidden}));
""")
assert result == {
"attempts": 5,
"attempts": 3,
"reloads": 0,
"offered": {
"hidden": False,
@@ -151,7 +214,7 @@ await loading;
console.log(JSON.stringify({attempts,waiting,reloads,status:status.textContent}));
""")
assert result == {
"attempts": 5,
"attempts": 3,
"waiting": True,
"reloads": 0,
"status": "",