跳到主要内容

React DOM fizz static browser

一、作用

二、预渲染

备注
function prerender(
children: ReactNodeList,
options?: Options,
): Promise<StaticResult> {
return new Promise((resolve, reject) => {
const onFatalError = reject;

function onAllReady() {
const stream = new ReadableStream(
{
type: 'bytes',
pull: (controller): ?Promise<void> => {
startFlowing(request, controller);
},
cancel: (reason): ?Promise<void> => {
stopFlowing(request);
abort(request, reason);
},
},
{ highWaterMark: 0 },
);

const result: StaticResult = enableHalt
? {
postponed: getPostponedState(request),
prelude: stream,
}
: ({
prelude: stream,
} as any);
resolve(result);
}

const onHeaders = options ? options.onHeaders : undefined;
let onHeadersImpl;
if (onHeaders) {
onHeadersImpl = (headersDescriptor: HeadersDescriptor) => {
onHeaders(new Headers(headersDescriptor));
};
}

const resources = createResumableState(
options ? options.identifierPrefix : undefined,
options ? options.unstable_externalRuntimeSrc : undefined,
options ? options.bootstrapScriptContent : undefined,
options ? options.bootstrapScripts : undefined,
options ? options.bootstrapModules : undefined,
);
const request = createPrerenderRequest(
children,
resources,
createRenderState(
resources,
// 一次性与预渲染的引导脚本不兼容
undefined, // nonce is not compatible with prerendered bootstrap scripts
options ? options.unstable_externalRuntimeSrc : undefined,
options ? options.importMap : undefined,
onHeadersImpl,
options ? options.maxHeadersLength : undefined,
),
createRootFormatContext(options ? options.namespaceURI : undefined),
options ? options.progressiveChunkSize : undefined,
options ? options.onError : undefined,
onAllReady,
undefined,
undefined,
onFatalError,
);
if (options && options.signal) {
const signal = options.signal;
if (signal.aborted) {
abort(request, (signal as any).reason);
} else {
const listener = () => {
abort(request, (signal as any).reason);
signal.removeEventListener('abort', listener);
};
signal.addEventListener('abort', listener);
}
}
startWork(request);
});
}

三、恢复并预渲染

备注
function resumeAndPrerender(
children: ReactNodeList,
postponedState: PostponedState,
options?: Omit<ResumeOptions, 'nonce'>,
): Promise<StaticResult> {
return new Promise((resolve, reject) => {
const onFatalError = reject;

function onAllReady() {
const stream = new ReadableStream(
{
type: 'bytes',
pull: (controller): ?Promise<void> => {
startFlowing(request, controller);
},
cancel: (reason): ?Promise<void> => {
stopFlowing(request);
abort(request, reason);
},
},
{ highWaterMark: 0 },
);

const result = {
postponed: getPostponedState(request),
prelude: stream,
};
resolve(result);
}

const request = resumeAndPrerenderRequest(
children,
postponedState,
resumeRenderState(postponedState.resumableState, undefined),
options ? options.onError : undefined,
onAllReady,
undefined,
undefined,
onFatalError,
);
if (options && options.signal) {
const signal = options.signal;
if (signal.aborted) {
abort(request, (signal as any).reason);
} else {
const listener = () => {
abort(request, (signal as any).reason);
signal.removeEventListener('abort', listener);
};
signal.addEventListener('abort', listener);
}
}
startWork(request);
});
}

四、类型

1. 一次性选项

// 一次性选项
type NonceOption =
| string
| {
script?: string;
style?: string;
};

// 选项
type Options = {
identifierPrefix?: string;
namespaceURI?: string;
bootstrapScriptContent?: string;
bootstrapScripts?: Array<string | BootstrapScriptDescriptor>;
bootstrapModules?: Array<string | BootstrapScriptDescriptor>;
progressiveChunkSize?: number;
signal?: AbortSignal;
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string;
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor;
importMap?: ImportMap;
onHeaders?: (headers: Headers) => void;
maxHeadersLength?: number;
};

// 静态结果
type StaticResult = {
postponed: null | PostponedState;
prelude: ReadableStream;
};

2. 恢复选项

type ResumeOptions = {
nonce?: NonceOption;
signal?: AbortSignal;
onError?: (error: mixed) => ?string;
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor;
};

五、转导