using System.Diagnostics;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using XFESystem.Browser;
using XFESystem.Desktop;
using XFESystem.Documents;
// Same production engine, sources and private real-font canvas before/after.
// Synthetic CSS is explicitly a host CPU workload, never a network speed claim.
internal static class LoadingProfile
{
public static void Run(string root, string label)
{
string output = Path.Combine(root, "build/BrowserLoadSpeed", label + "-" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
Directory.CreateDirectory(output);
var hashes = Directory.EnumerateFiles(Path.Combine(root, "Source/XFESystem.Browser"), "*.cs")
.ToDictionary(path => Path.GetRelativePath(root, path).Replace('\\', '/'), Hash);
var cases = new List<object>(); bool allPassed = true;
string css = string.Concat(Enumerable.Range(0, 1800).Select(i => $".scope p.item{i}{{color:#{i % 0xffffff:x6}}}"));
string fixture = "<!doctype html><style>body{margin:0}p{margin:0}" + css + "</style><main class=scope>" +
string.Concat(Enumerable.Range(0, 100).Select(i => $"<p id=p{i} class=item{i * 17}>Row {i}</p>")) + "</main>";
foreach (string kind in new[] { "IndexedCss", "PlainMarkdown", "WebsiteParity", "Monaco" })
for (int attempt = 1; attempt <= 3; attempt++)
{
var trace = new List<object>();
var timer = Stopwatch.StartNew();
var page = new BrowserService(new FixtureTransport(fixture)) { Trace = line => trace.Add(new { Ticks = timer.ElapsedTicks, Line = line.TrimEnd() }) };
using var canvas = new WindowsTextCanvas(Path.Combine(root, "assets/fonts/cascadia-mono-2407.24/CascadiaMono-Regular.ttf"), 796, 404);
page.SetCanvas(canvas); page.ResizeViewport(796, 404);
timer.Restart();
if (kind == "Monaco") page.NavigateEditor("using System;\nnamespace XFE;\npublic class Test { int value = 42; }", "Test.cs");
else if (kind == "IndexedCss") page.Navigate("https://fixture.test/");
else page.BeginDocumentPreview(kind == "PlainMarkdown" ? "# Preview\n\nHello **XFEstudio**.\n\nSimple document without code or math." : WebsiteAssets.ReadText("Fixtures/WebsiteParity.md"), "Test.md");
double navigation = timer.Elapsed.TotalMilliseconds;
page.Paint(canvas, new(0, 0, 796, 404), 0); page.FramePresented();
double firstPaint = timer.Elapsed.TotalMilliseconds;
for (int pump = 1; pump <= 128; pump++)
{
page.AdvanceTime(pump * 20);
if (!page.DocumentEnhancementsPending && pump >= 8) break;
}
double ready = timer.Elapsed.TotalMilliseconds;
timer.Restart();
var layout = page.Layout(new(796, 404));
double layoutMs = timer.Elapsed.TotalMilliseconds;
var engine = (BrowserLayoutEngine)typeof(BrowserService).GetField("layoutEngine", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(page)!;
string signature = JsonSerializer.Serialize(new
{
Commands = layout.Commands.Select(c => new { c.Kind, c.Bounds, c.Color, c.Text, c.Font, c.Opacity, c.Decoration, c.RoundedClip, c.ViewportPinned }),
Boxes = layout.Boxes.Select(b => new { b.BorderBox, Properties = b.Style.Properties.OrderBy(p => p.Key, StringComparer.Ordinal) })
});
// Reflection lets the same probe also measure the frozen dev.3
// engine, which predates the public selector-work diagnostic.
object cascade = typeof(BrowserLayoutEngine).GetField("cascade", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(engine)!;
int selectorEvaluations = (int)cascade.GetType().GetField("comparisons", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(cascade)!;
bool passed = page.Document is not null && !page.DocumentEnhancementsPending &&
(kind != "Monaco" || page.ReadEditorText() == "using System;\nnamespace XFE;\npublic class Test { int value = 42; }");
allPassed &= passed;
var row = new { Kind = kind, Attempt = attempt, Passed = passed, NavigationMilliseconds = navigation, FirstPaintMilliseconds = firstPaint,
ReadyMilliseconds = ready, LayoutMilliseconds = layoutMs, CssSelectorEvaluations = selectorEvaluations, page.LayoutPassCount,
page.PackagedScriptCacheHits, page.PackagedScriptPreparations, Commands = layout.Commands.Count,
RenderSha256 = Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(signature))),
PageText = page.CurrentPage.Text, Trace = trace };
cases.Add(row);
Console.WriteLine(JsonSerializer.Serialize(new { kind, attempt, passed, navigation, firstPaint, ready, layoutMs, CssSelectorEvaluations = selectorEvaluations, row.RenderSha256 }));
page.Release();
}
bool unchanged = hashes.All(p => Hash(Path.Combine(root, p.Key)) == p.Value);
var result = new { Kind = "ProductionBrowserLoadingHostProfile", Passed = unchanged && allPassed, HostOnly = true, NativeAcceptance = false,
Frequency = Stopwatch.Frequency, Sources = hashes, Cases = cases };
string path = Path.Combine(output, "Result.json");
File.WriteAllText(path, JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }));
Console.WriteLine(path);
if (!unchanged) throw new IOException("Production sources changed during the loading profile.");
}
private static string Hash(string path) => Convert.ToHexStringLower(SHA256.HashData(File.ReadAllBytes(path)));
private sealed class FixtureTransport(string html) : IWebTransport
{
public WebResponse Get(Uri uri, BrowserLimits limits) => new(uri, 200, "text/html", html, true);
}
}
using System.Diagnostics;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using XFESystem.Browser;
using XFESystem.Desktop;
using XFESystem.Documents;
// Same production engine, sources and private real-font canvas before/after.
// Synthetic CSS is explicitly a host CPU workload, never a network speed claim.
internal static class LoadingProfile
{
public static void Run(string root, string label)
{
string output = Path.Combine(root, "build/BrowserLoadSpeed", label + "-" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
Directory.CreateDirectory(output);
var hashes = Directory.EnumerateFiles(Path.Combine(root, "Source/XFESystem.Browser"), "*.cs")
.ToDictionary(path => Path.GetRelativePath(root, path).Replace('\\', '/'), Hash);
var cases = new List<object>(); bool allPassed = true;
string css = string.Concat(Enumerable.Range(0, 1800).Select(i => $".scope p.item{i}{{color:#{i % 0xffffff:x6}}}"));
string fixture = "<!doctype html><style>body{margin:0}p{margin:0}" + css + "</style><main class=scope>" +
string.Concat(Enumerable.Range(0, 100).Select(i => $"<p id=p{i} class=item{i * 17}>Row {i}</p>")) + "</main>";
foreach (string kind in new[] { "IndexedCss", "PlainMarkdown", "WebsiteParity", "Monaco" })
for (int attempt = 1; attempt <= 3; attempt++)
{
var trace = new List<object>();
var timer = Stopwatch.StartNew();
var page = new BrowserService(new FixtureTransport(fixture)) { Trace = line => trace.Add(new { Ticks = timer.ElapsedTicks, Line = line.TrimEnd() }) };
using var canvas = new WindowsTextCanvas(Path.Combine(root, "assets/fonts/cascadia-mono-2407.24/CascadiaMono-Regular.ttf"), 796, 404);
page.SetCanvas(canvas); page.ResizeViewport(796, 404);
timer.Restart();
if (kind == "Monaco") page.NavigateEditor("using System;\nnamespace XFE;\npublic class Test { int value = 42; }", "Test.cs");
else if (kind == "IndexedCss") page.Navigate("https://fixture.test/");
else page.BeginDocumentPreview(kind == "PlainMarkdown" ? "# Preview\n\nHello **XFEstudio**.\n\nSimple document without code or math." : WebsiteAssets.ReadText("Fixtures/WebsiteParity.md"), "Test.md");
double navigation = timer.Elapsed.TotalMilliseconds;
page.Paint(canvas, new(0, 0, 796, 404), 0); page.FramePresented();
double firstPaint = timer.Elapsed.TotalMilliseconds;
for (int pump = 1; pump <= 128; pump++)
{
page.AdvanceTime(pump * 20);
if (!page.DocumentEnhancementsPending && pump >= 8) break;
}
double ready = timer.Elapsed.TotalMilliseconds;
timer.Restart();
var layout = page.Layout(new(796, 404));
double layoutMs = timer.Elapsed.TotalMilliseconds;
var engine = (BrowserLayoutEngine)typeof(BrowserService).GetField("layoutEngine", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(page)!;
string signature = JsonSerializer.Serialize(new
{
Commands = layout.Commands.Select(c => new { c.Kind, c.Bounds, c.Color, c.Text, c.Font, c.Opacity, c.Decoration, c.RoundedClip, c.ViewportPinned }),
Boxes = layout.Boxes.Select(b => new { b.BorderBox, Properties = b.Style.Properties.OrderBy(p => p.Key, StringComparer.Ordinal) })
});
// Reflection lets the same probe also measure the frozen dev.3
// engine, which predates the public selector-work diagnostic.
object cascade = typeof(BrowserLayoutEngine).GetField("cascade", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(engine)!;
int selectorEvaluations = (int)cascade.GetType().GetField("comparisons", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(cascade)!;
bool passed = page.Document is not null && !page.DocumentEnhancementsPending &&
(kind != "Monaco" || page.ReadEditorText() == "using System;\nnamespace XFE;\npublic class Test { int value = 42; }");
allPassed &= passed;
var row = new { Kind = kind, Attempt = attempt, Passed = passed, NavigationMilliseconds = navigation, FirstPaintMilliseconds = firstPaint,
ReadyMilliseconds = ready, LayoutMilliseconds = layoutMs, CssSelectorEvaluations = selectorEvaluations, page.LayoutPassCount,
page.PackagedScriptCacheHits, page.PackagedScriptPreparations, Commands = layout.Commands.Count,
RenderSha256 = Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(signature))),
PageText = page.CurrentPage.Text, Trace = trace };
cases.Add(row);
Console.WriteLine(JsonSerializer.Serialize(new { kind, attempt, passed, navigation, firstPaint, ready, layoutMs, CssSelectorEvaluations = selectorEvaluations, row.RenderSha256 }));
page.Release();
}
bool unchanged = hashes.All(p => Hash(Path.Combine(root, p.Key)) == p.Value);
var result = new { Kind = "ProductionBrowserLoadingHostProfile", Passed = unchanged && allPassed, HostOnly = true, NativeAcceptance = false,
Frequency = Stopwatch.Frequency, Sources = hashes, Cases = cases };
string path = Path.Combine(output, "Result.json");
File.WriteAllText(path, JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }));
Console.WriteLine(path);
if (!unchanged) throw new IOException("Production sources changed during the loading profile.");
}
private static string Hash(string path) => Convert.ToHexStringLower(SHA256.HashData(File.ReadAllBytes(path)));
private sealed class FixtureTransport(string html) : IWebTransport
{
public WebResponse Get(Uri uri, BrowserLimits limits) => new(uri, 200, "text/html", html, true);
}
}