Files
next.js/crates/next-code-frame/benches/code_frame_bench.rs
Arian Tron 61f56f997c
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled
first commit
2026-03-10 19:37:31 +03:30

208 lines
6.7 KiB
Rust

use criterion::{Criterion, black_box, criterion_group, criterion_main};
use next_code_frame::{CodeFrameLocation, CodeFrameOptions, Language, Location, render_code_frame};
/// Generate a realistic small TypeScript/React file (~300 lines).
fn generate_small_file() -> String {
let mut lines = Vec::with_capacity(300);
lines.push("import React, { useState, useEffect, useCallback, useMemo } from 'react'");
lines.push("import { useRouter } from 'next/router'");
lines.push("import Link from 'next/link'");
lines.push("");
lines.push("interface User {");
lines.push(" id: string");
lines.push(" name: string");
lines.push(" email: string");
lines.push(" avatar?: string");
lines.push(" role: 'admin' | 'user' | 'moderator'");
lines.push(" createdAt: Date");
lines.push("}");
lines.push("");
// Pad with realistic component code
for i in 0..40 {
lines.push("function ComponentPart() {");
// Use a leaked string so we get &'static str
let s: &'static str =
Box::leak(format!(" const [state{i}, setState{i}] = useState(null)").into_boxed_str());
lines.push(s);
lines.push(" useEffect(() => {");
let s: &'static str = Box::leak(
format!(" fetch('/api/data/{i}').then(r => r.json()).then(setState{i})")
.into_boxed_str(),
);
lines.push(s);
lines.push(" }, [])");
lines.push(" return (");
lines.push(" <div className=\"flex items-center justify-center p-4\">");
let s: &'static str =
Box::leak(format!(" <span>{{state{i}?.name}}</span>").into_boxed_str());
lines.push(s);
lines.push(" </div>");
lines.push(" )");
lines.push("}");
lines.push("");
}
lines.join("\n")
}
/// Generate a large bundled JS file (~30k lines) mimicking react-dom.development.js.
fn generate_large_file(minified: bool) -> String {
let mut lines = Vec::with_capacity(30_000);
lines.push("/**");
lines.push(" * @license React");
lines.push(" * react-dom.development.js");
lines.push(" *");
lines.push(" * Copyright (c) Meta Platforms, Inc. and affiliates.");
lines.push(" */");
lines.push("'use strict';");
lines.push("");
lines.push("(function (global, factory) {");
lines.push(
" typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, \
require('react')) :",
);
lines.push(
" typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :",
);
lines.push(" (global = global || self, factory(global.ReactDOM = {}, global.React));");
lines.push("}(this, (function (exports, React) { 'use strict';");
lines.push("");
// Generate ~30k lines of realistic bundled code
for i in 0..3000 {
lines.push(
"function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {",
);
// Leaked strings for &'static str
let s: &'static str = Box::leak(
format!(
" var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== \
null && newChild.type === REACT_FRAGMENT_TYPE_{i} && newChild.key === null;"
)
.into_boxed_str(),
);
lines.push(s);
lines.push(" if (isUnkeyedTopLevelFragment) {");
lines.push(" newChild = newChild.props.children;");
lines.push(" }");
lines.push(" if (typeof newChild === 'object' && newChild !== null) {");
lines.push(" switch (newChild.$$typeof) {");
lines.push(" case REACT_ELEMENT_TYPE:");
lines.push(
" return placeSingleChild(reconcileSingleElement(returnFiber, \
currentFirstChild, newChild, lanes));",
);
lines.push(" }");
lines.push(" }");
lines.push("}");
lines.push("");
}
lines.push("})));");
lines.join(if minified { " " } else { "\n" })
}
fn bench_small_file(c: &mut Criterion) {
let source = generate_small_file();
let line_count = source.lines().count();
let mid = line_count / 2;
let location = CodeFrameLocation {
start: Location {
line: mid,
column: Some(10),
},
end: None,
};
let options = CodeFrameOptions {
highlight_code: true,
color: true,
max_width: 100,
language: Language::JavaScript,
..Default::default()
};
c.bench_function(&format!("rust: small file ({line_count} lines)"), |b| {
b.iter(|| {
let result = render_code_frame(black_box(&source), black_box(&location), &options);
black_box(result).unwrap();
});
});
}
fn bench_large_file(c: &mut Criterion) {
let source = generate_large_file(false);
let line_count = source.lines().count();
let mid = line_count / 2;
let location = CodeFrameLocation {
start: Location {
line: mid,
column: Some(10),
},
end: None,
};
let options = CodeFrameOptions {
highlight_code: true,
color: true,
max_width: 100,
language: Language::JavaScript,
..Default::default()
};
c.bench_function(&format!("rust: large file ({line_count} lines)"), |b| {
b.iter(|| {
let result = render_code_frame(black_box(&source), black_box(&location), &options);
black_box(result).unwrap();
});
});
}
fn bench_minified_file(c: &mut Criterion) {
// Take the large file and collapse lines by stripping whitespace after `;`
// to simulate a minified bundle with very long lines.
let source = generate_large_file(true);
let line_count = source.lines().count();
// Point at a column somewhere in the middle of the long line
let mid_col = source.lines().next().map_or(100, |l| l.len() / 2);
let location = CodeFrameLocation {
start: Location {
line: 1,
column: Some(mid_col),
},
end: None,
};
let options = CodeFrameOptions {
highlight_code: true,
color: true,
max_width: 100,
language: Language::JavaScript,
..Default::default()
};
c.bench_function(
&format!("rust: minified file ({line_count} lines, ~{mid_col} col)"),
|b| {
b.iter(|| {
let result = render_code_frame(black_box(&source), black_box(&location), &options);
black_box(result).unwrap();
});
},
);
}
criterion_group!(
benches,
bench_small_file,
bench_large_file,
bench_minified_file
);
criterion_main!(benches);