Skip to content

Commit

Permalink
fix: error when 2 perf markers are stacked
Browse files Browse the repository at this point in the history
We have 3 prod markers today, init, hydrate and rehydration queue.

When 2 markers are stacked, for example, creating a component in the constructor of another will stack 2 init marks, once the second marker is measured, we need to clean the marks and measures and will clear the first one, and when the measure for that marker is done, it throws.

Those cases are for init and hydrate, the rehydration queue measure is fine, we dont want to do it per component.

This pr does 2 main things:
1- removes the init measure, cause we dont have a vm, and by the time is created in create component, it does not make sense to measure.
2- makes the marks for hydrate vm dependant, but the measure name is general, to pair it with the rehydration queue measure.
  • Loading branch information
jodarove committed Nov 30, 2018
1 parent 3e38821 commit fbb0836
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
19 changes: 17 additions & 2 deletions packages/@lwc/engine/src/framework/performance-timing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const isUserTimingSupported: boolean =
typeof performance.measure === 'function' &&
typeof performance.clearMeasures === 'function';

function getMarkName(vm: VM, phase: MeasurementPhase): string {
function getMarkName(vm: VM, phase: MeasurementPhase | GlobalMeasurementPhase): string {
return `<${vm.def.name} (${vm.uid})> - ${phase}`;
}

Expand Down Expand Up @@ -64,6 +64,21 @@ function _endGlobalMeasure(phase: GlobalMeasurementPhase) {
performance.clearMeasures(phase);
}

export const startGlobalMeasure = isUserTimingSupported ? _startGlobalMeasure : noop;
function _startHydrateMeasure(vm: VM) {
performance.mark(getMarkName(vm, GlobalMeasurementPhase.HYDRATE));
}

function _endHydrateMeasure(vm: VM) {
const phase = GlobalMeasurementPhase.HYDRATE;
const name = getMarkName(vm, phase);

performance.measure(phase, name);
performance.clearMarks(name);
performance.clearMeasures(phase);
}

export const startGlobalMeasure = isUserTimingSupported ? _startGlobalMeasure : noop;
export const endGlobalMeasure = isUserTimingSupported ? _endGlobalMeasure : noop;

export const startHydrateMeasure = isUserTimingSupported ? _startHydrateMeasure : noop;
export const endHydrateMeasure = isUserTimingSupported ? _endHydrateMeasure : noop;
8 changes: 3 additions & 5 deletions packages/@lwc/engine/src/framework/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { isNativeShadowRootAvailable } from "../env/dom";
import { patchCustomElementProto } from "./patch";
import { getComponentDef, setElementProto } from "./def";
import { patchCustomElementWithRestrictions } from "./restrictions";
import { endGlobalMeasure, startGlobalMeasure, GlobalMeasurementPhase } from "./performance-timing";
import { startHydrateMeasure, endHydrateMeasure } from "./performance-timing";
import { appendChild, insertBefore, replaceChild, removeChild } from "../env/node";

const ConnectingSlot = createFieldName('connecting');
Expand Down Expand Up @@ -60,7 +60,6 @@ assign(Node.prototype, {
* then it throws a TypeError.
*/
export function createElement(sel: string, options: any = {}): HTMLElement {
startGlobalMeasure(GlobalMeasurementPhase.INIT);
if (!isObject(options) || isNull(options)) {
throw new TypeError();
}
Expand Down Expand Up @@ -98,17 +97,16 @@ export function createElement(sel: string, options: any = {}): HTMLElement {
createVM(sel, element, Ctor, { mode, fallback, isRoot: true });
// Handle insertion and removal from the DOM manually
setInternalField(element, ConnectingSlot, () => {
startGlobalMeasure(GlobalMeasurementPhase.HYDRATE);
const vm = getCustomElementVM(element);
startHydrateMeasure(vm);
removeVM(vm); // moving the element from one place to another is observable via life-cycle hooks
appendVM(vm);
renderVM(vm);
endGlobalMeasure(GlobalMeasurementPhase.HYDRATE);
endHydrateMeasure(vm);
});
setInternalField(element, DisconnectingSlot, () => {
const vm = getCustomElementVM(element);
removeVM(vm);
});
endGlobalMeasure(GlobalMeasurementPhase.INIT);
return element;
}

0 comments on commit fbb0836

Please sign in to comment.