Avoid UI flickering during transition from prerendered to live content
This commit is contained in:
parent
6a57218e14
commit
5315446054
|
|
@ -7,6 +7,7 @@ const selectValuePropname = '_blazorSelectValue';
|
|||
const sharedTemplateElemForParsing = document.createElement('template');
|
||||
const sharedSvgElemForParsing = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
const preventDefaultEvents: { [eventType: string]: boolean } = { submit: true };
|
||||
const rootComponentsPendingFirstRender: { [componentId: number]: Element } = {};
|
||||
|
||||
export class BrowserRenderer {
|
||||
private eventDelegator: EventDelegator;
|
||||
|
|
@ -19,7 +20,9 @@ export class BrowserRenderer {
|
|||
}
|
||||
|
||||
public attachRootComponentToElement(componentId: number, element: Element) {
|
||||
this.attachComponentToElement(componentId, toLogicalElement(element));
|
||||
// 'allowExistingContents' to keep any prerendered content until we do the first client-side render
|
||||
this.attachComponentToElement(componentId, toLogicalElement(element, /* allowExistingContents */ true));
|
||||
rootComponentsPendingFirstRender[componentId] = element;
|
||||
}
|
||||
|
||||
public updateComponent(batch: RenderBatch, componentId: number, edits: ArraySegment<RenderTreeEdit>, referenceFrames: ArrayValues<RenderTreeFrame>) {
|
||||
|
|
@ -28,6 +31,13 @@ export class BrowserRenderer {
|
|||
throw new Error(`No element is currently associated with component ${componentId}`);
|
||||
}
|
||||
|
||||
// On the first render for each root component, clear any existing content (e.g., prerendered)
|
||||
const rootElementToClear = rootComponentsPendingFirstRender[componentId];
|
||||
if (rootElementToClear) {
|
||||
delete rootComponentsPendingFirstRender[componentId];
|
||||
clearElement(rootElementToClear);
|
||||
}
|
||||
|
||||
this.applyEdits(batch, element, 0, edits, referenceFrames);
|
||||
}
|
||||
|
||||
|
|
@ -368,3 +378,10 @@ function raiseEvent(event: Event, browserRendererId: number, eventHandlerId: num
|
|||
eventDescriptor,
|
||||
JSON.stringify(eventArgs.data));
|
||||
}
|
||||
|
||||
function clearElement(element: Element) {
|
||||
let childNode: Node | null;
|
||||
while (childNode = element.firstChild) {
|
||||
element.removeChild(childNode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,12 @@
|
|||
const logicalChildrenPropname = createSymbolOrFallback('_blazorLogicalChildren');
|
||||
const logicalParentPropname = createSymbolOrFallback('_blazorLogicalParent');
|
||||
|
||||
export function toLogicalElement(element: Element) {
|
||||
if (element.childNodes.length > 0) {
|
||||
throw new Error('New logical elements must start empty');
|
||||
export function toLogicalElement(element: Element, allowExistingContents?: boolean) {
|
||||
// Normally it's good to assert that the element has started empty, because that's the usual
|
||||
// situation and we probably have a bug if it's not. But for the element that contain prerendered
|
||||
// root components, we want to let them keep their content until we replace it.
|
||||
if (element.childNodes.length > 0 && !allowExistingContents) {
|
||||
throw new Error('New logical elements must start empty, or allowExistingContents must be true');
|
||||
}
|
||||
|
||||
element[logicalChildrenPropname] = [];
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ export function attachRootComponentToElement(browserRendererId: number, elementS
|
|||
if (!browserRenderer) {
|
||||
browserRenderer = browserRenderers[browserRendererId] = new BrowserRenderer(browserRendererId);
|
||||
}
|
||||
clearElement(element);
|
||||
browserRenderer.attachRootComponentToElement(componentId, element);
|
||||
}
|
||||
|
||||
|
|
@ -57,10 +56,3 @@ export function renderBatch(browserRendererId: number, batch: RenderBatch) {
|
|||
browserRenderer.disposeEventHandler(eventHandlerId);
|
||||
}
|
||||
}
|
||||
|
||||
function clearElement(element: Element) {
|
||||
let childNode: Node | null;
|
||||
while (childNode = element.firstChild) {
|
||||
element.removeChild(childNode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue