Skip to content

Commit

Permalink
vite: profiling (#8493)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori authored Jan 12, 2024
1 parent 3218847 commit 4464df2
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 2 deletions.
15 changes: 14 additions & 1 deletion packages/remix-dev/cli/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import getPort, { makeRange } from "get-port";
import prettyMs from "pretty-ms";
import PackageJson from "@npmcli/package-json";
import pc from "picocolors";
import exitHook from "exit-hook";

import * as colors from "../colors";
import * as compiler from "../compiler";
Expand All @@ -20,6 +21,7 @@ import { transpile as convertFileToJS } from "./useJavascript";
import type { Options } from "../compiler/options";
import { createFileWatchCache } from "../compiler/fileWatchCache";
import { logger } from "../tux";
import * as profiler from "../vite/profiler";

type InitFlags = {
deleteScript?: boolean;
Expand Down Expand Up @@ -143,7 +145,14 @@ export async function viteBuild(
}

let { build } = await import("../vite/build");
await build(root, options);
if (options.profile) {
await profiler.start();
}
try {
await build(root, options);
} finally {
await profiler.stop(logger.info);
}
}

export async function watch(
Expand Down Expand Up @@ -191,6 +200,10 @@ export async function dev(

export async function viteDev(root: string, options: ViteDevOptions = {}) {
let { dev } = await import("../vite/dev");
if (options.profile) {
await profiler.start();
}
exitHook(() => profiler.stop(console.info));
await dev(root, options);

// keep `remix vite-dev` alive by waiting indefinitely
Expand Down
1 change: 1 addition & 0 deletions packages/remix-dev/cli/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export async function run(argv: string[] = process.argv.slice(2)) {
"-m": "--mode",
"--open": isBooleanFlag("--open") ? Boolean : String,
"--strictPort": Boolean,
"--profile": Boolean,
}
: {
// Non Vite commands
Expand Down
1 change: 1 addition & 0 deletions packages/remix-dev/vite/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ export interface ViteBuildOptions {
logLevel?: Vite.LogLevel;
minify?: Vite.BuildOptions["minify"];
mode?: string;
profile?: boolean;
}

export async function build(
Expand Down
21 changes: 20 additions & 1 deletion packages/remix-dev/vite/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type * as Vite from "vite";
import colors from "picocolors";

import { preloadViteEsm } from "./import-vite-esm-sync";
import * as profiler from "./profiler";

export interface ViteDevOptions {
clearScreen?: boolean;
Expand All @@ -14,6 +15,7 @@ export interface ViteDevOptions {
open?: boolean | string;
port?: number;
strictPort?: boolean;
profile?: boolean;
}

export async function dev(
Expand Down Expand Up @@ -53,5 +55,22 @@ export async function dev(

await server.listen();
server.printUrls();
server.bindCLIShortcuts({ print: true });

let customShortcuts: Vite.CLIShortcut<typeof server>[] = [
{
key: "p",
description: "start/stop the profiler",
async action(server) {
if (profiler.getSession()) {
await profiler.stop(server.config.logger.info);
} else {
await profiler.start(() => {
server.config.logger.info("Profiler started");
});
}
},
},
];

server.bindCLIShortcuts({ print: true, customShortcuts });
}
44 changes: 44 additions & 0 deletions packages/remix-dev/vite/profiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Adapted from:
// - https://github.com/vitejs/vite/blob/9fc5d9cb3a1b9df067e00959faa9da43ae03f776/packages/vite/bin/vite.js
// - https://github.com/vitejs/vite/blob/9fc5d9cb3a1b9df067e00959faa9da43ae03f776/packages/vite/src/node/cli.ts

import fs from "node:fs";
import type { Session } from "node:inspector";
import path from "node:path";
import colors from "picocolors";

declare namespace global {
let __remix_profile_session: Session | undefined;
}

export const getSession = () => global.__remix_profile_session;

export const start = async (callback?: () => void | Promise<void>) => {
let inspector = await import("node:inspector").then((r) => r.default);
let session = (global.__remix_profile_session = new inspector.Session());
session.connect();
session.post("Profiler.enable", () => {
session.post("Profiler.start", callback);
});
};

let profileCount = 0;

export const stop = (log: (message: string) => void): void | Promise<void> => {
let session = getSession();
if (!session) return;
return new Promise((res, rej) => {
session!.post("Profiler.stop", (err, { profile }) => {
if (err) return rej(err);
let outPath = path.resolve(`./remix-${profileCount++}.cpuprofile`);
fs.writeFileSync(outPath, JSON.stringify(profile));
log(
colors.yellow(
`CPU profile written to ${colors.white(colors.dim(outPath))}`
)
);
global.__remix_profile_session = undefined;
res();
});
});
};

0 comments on commit 4464df2

Please sign in to comment.