Compilation
Every argument or output schemas are compiled by TypeBox TypeCompiler.
The reason for the compilation is to create very high-performance validations.
The TypeBox TypeCompiler is a high-performance JIT validation compiler that transforms TypeBox types into optimized JavaScript validation routines.
Cold starts
Since compilation occurs at runtime, the initial validation call may experience a slight delay compared to subsequent ones due to the compilation step. This delay is a natural part of the process and typically minimally impacts overall performance once the initial compilation is complete.
parsing: 0.706ms
parsing: 0.018ms
parsing: 0.042ms
These statistics, derived from real application data, illustrate that the initial parsing process tends to have a longer duration compared to subsequent ones. This discrepancy is attributable to the compilation step, which is automatically cached per instance of the validation schema. As a result, subsequent parsing processes benefit from faster execution times due to the cached compilation.
That means that those two schemas
const schema1 = Type.String();
const schema2 = Type.String();
are both must be compiled, so the compilation process is twice.
Compilers sharing
Sharing compilers across the entire application ensures that the same validation schema is not compiled multiple times. This optimization reduces redundancy and enhances overall performance by leveraging a centralized compilation mechanism for all relevant validation processes.
import { Compiler } from '@ptsq/server';
export const compiler = new Compiler();
import { Resolver } from '@ptsq/server';
import { compiler } from './compiler';
const externalResolver = Resolver.createRoot({
compiler: compiler,
});
import { PtsqServer } from '@ptsq/server';
import { compiler } from './compiler';
import { externalResolver } from './external-resolver';
const { resolver, router, serve } = PtsqServer.init({
ctx: () => ({}),
compiler: compiler,
}).create();
// ...
Typebox vs Zod
Performance comparison between Typebox and Zod validations.
const personSchemaTypeBox = Type.Intersect([
Type.Object({
firstName: Type.String({ minLength: 4 }),
age: Type.Number({ minimum: 18 }),
}),
Type.Object({
lastName: Type.Optional(Type.String({ minLength: 4 })),
}),
]);
const personSchemaZod = z.intersection(
z.object({
firstName: z.string().min(4),
age: z.number().min(18),
}),
z.object({
lastName: z.string().min(4).optional(),
}),
);
Test 1
const data = {
firstName: 'John',
age: 22,
};
non-compiled Typebox schema check: 0.247ms
Typebox compilation: 0.738ms
compiled Typebox schema check: 0.024ms
Zod schema check: 0.67ms
Test 2
const data = {
firstName: 'John',
age: 22,
lastName: 'Doe', // invalid!
};
non-compiled Typebox schema check: 0.244ms
Typebox compilation: 0.702ms
compiled Typebox schema check: 0.025ms
Zod schema check: 0.846ms
Results
From these small tests, it's evident that the Typebox compilation step nearly matches the speed of Zod validation. Crucially, this compilation occurs just once per application deployment. Subsequent validations are then expedited by cached and validated JavaScript functions. Although the schemas tested here aren't overly complex, they represent a common pattern, particularly the intersection of two schemas in ptsq. This efficiency demonstrates the effectiveness of optimizing compilation and caching mechanisms to streamline validation processes.