@gemx-dev/heatmap-react 3.5.92-dev.8 → 3.5.92-dev.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
- package/dist/esm/index.js +165 -24
- package/dist/esm/index.mjs +165 -24
- package/dist/esm/libs/iframe-processor/orchestrator.d.ts.map +1 -1
- package/dist/esm/libs/iframe-processor/processors/viewport/global-fixes/global-fixes/viewport-unit-replacer/fixes.d.ts.map +1 -1
- package/dist/esm/libs/iframe-processor/processors/viewport/index.d.ts.map +1 -1
- package/dist/esm/libs/iframe-processor/processors/viewport/pipeline.d.ts.map +1 -1
- package/dist/esm/libs/iframe-processor/shared/perf.d.ts +58 -0
- package/dist/esm/libs/iframe-processor/shared/perf.d.ts.map +1 -0
- package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
- package/dist/umd/index.js +2 -2
- package/dist/umd/libs/iframe-processor/orchestrator.d.ts.map +1 -1
- package/dist/umd/libs/iframe-processor/processors/viewport/global-fixes/global-fixes/viewport-unit-replacer/fixes.d.ts.map +1 -1
- package/dist/umd/libs/iframe-processor/processors/viewport/index.d.ts.map +1 -1
- package/dist/umd/libs/iframe-processor/processors/viewport/pipeline.d.ts.map +1 -1
- package/dist/umd/libs/iframe-processor/shared/perf.d.ts +58 -0
- package/dist/umd/libs/iframe-processor/shared/perf.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHeatmapRender.d.ts","sourceRoot":"","sources":["../../../src/hooks/viz-render/useHeatmapRender.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useHeatmapRender.d.ts","sourceRoot":"","sources":["../../../src/hooks/viz-render/useHeatmapRender.ts"],"names":[],"mappings":"AAgCA,UAAU,uBAAuB;IAC/B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACtD;AAaD,eAAO,MAAM,gBAAgB,QAAO,uBAoEnC,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -3904,6 +3904,85 @@ function useVizLiveIframeMsg(options = {}) {
|
|
|
3904
3904
|
};
|
|
3905
3905
|
}
|
|
3906
3906
|
|
|
3907
|
+
/**
|
|
3908
|
+
* Performance tracker — measures render pipeline timings and stores results
|
|
3909
|
+
* in `window.__gemxPerf` for inspection in DevTools.
|
|
3910
|
+
*
|
|
3911
|
+
* Usage:
|
|
3912
|
+
* perf.startSession('render-1');
|
|
3913
|
+
* const t = perf.mark('viewport.run');
|
|
3914
|
+
* perf.measure('viewport.run', t);
|
|
3915
|
+
* perf.endSession();
|
|
3916
|
+
*
|
|
3917
|
+
* // In DevTools:
|
|
3918
|
+
* window.__gemxPerf.latest
|
|
3919
|
+
* window.__gemxPerf.sessions
|
|
3920
|
+
*/
|
|
3921
|
+
const s = {
|
|
3922
|
+
enabled: true,
|
|
3923
|
+
current: null,
|
|
3924
|
+
sessions: [],
|
|
3925
|
+
maxSessions: 20,
|
|
3926
|
+
};
|
|
3927
|
+
// ── Functions ─────────────────────────────────────────────────────────────────
|
|
3928
|
+
function startSession(id) {
|
|
3929
|
+
if (!s.enabled)
|
|
3930
|
+
return;
|
|
3931
|
+
s.current = { id, startedAt: performance.now(), entries: [] };
|
|
3932
|
+
}
|
|
3933
|
+
function endSession() {
|
|
3934
|
+
if (!s.enabled || !s.current)
|
|
3935
|
+
return null;
|
|
3936
|
+
const session = s.current;
|
|
3937
|
+
session.total = performance.now() - session.startedAt;
|
|
3938
|
+
s.sessions = [session, ...s.sessions].slice(0, s.maxSessions);
|
|
3939
|
+
s.current = null;
|
|
3940
|
+
flush();
|
|
3941
|
+
return session;
|
|
3942
|
+
}
|
|
3943
|
+
/** Record a point-in-time mark. Returns `performance.now()` for use with measure(). */
|
|
3944
|
+
function mark$1(label) {
|
|
3945
|
+
const now = performance.now();
|
|
3946
|
+
if (s.enabled && s.current) {
|
|
3947
|
+
s.current.entries.push({ label, t: now - s.current.startedAt });
|
|
3948
|
+
}
|
|
3949
|
+
return now;
|
|
3950
|
+
}
|
|
3951
|
+
/** Record a duration from a previous mark() timestamp. */
|
|
3952
|
+
function measure$1(label, t0) {
|
|
3953
|
+
const duration = performance.now() - t0;
|
|
3954
|
+
if (s.enabled && s.current) {
|
|
3955
|
+
s.current.entries.push({ label, t: t0 - s.current.startedAt, duration });
|
|
3956
|
+
}
|
|
3957
|
+
return duration;
|
|
3958
|
+
}
|
|
3959
|
+
function getReport() {
|
|
3960
|
+
return {
|
|
3961
|
+
sessions: s.sessions,
|
|
3962
|
+
latest: s.sessions[0] ?? null,
|
|
3963
|
+
};
|
|
3964
|
+
}
|
|
3965
|
+
function clear$1() {
|
|
3966
|
+
s.current = null;
|
|
3967
|
+
s.sessions = [];
|
|
3968
|
+
if (typeof window !== 'undefined')
|
|
3969
|
+
delete window.__gemxPerf;
|
|
3970
|
+
}
|
|
3971
|
+
function enable$1() {
|
|
3972
|
+
s.enabled = true;
|
|
3973
|
+
}
|
|
3974
|
+
function disable$1() {
|
|
3975
|
+
s.enabled = false;
|
|
3976
|
+
}
|
|
3977
|
+
// ── Internal ──────────────────────────────────────────────────────────────────
|
|
3978
|
+
function flush() {
|
|
3979
|
+
if (typeof window === 'undefined')
|
|
3980
|
+
return;
|
|
3981
|
+
window.__gemxPerf = getReport();
|
|
3982
|
+
}
|
|
3983
|
+
// ── Singleton export ──────────────────────────────────────────────────────────
|
|
3984
|
+
const perf = { startSession, endSession, mark: mark$1, measure: measure$1, getReport, clear: clear$1, enable: enable$1, disable: disable$1 };
|
|
3985
|
+
|
|
3907
3986
|
/**
|
|
3908
3987
|
* DOM observation setup — ResizeObserver + MutationObserver.
|
|
3909
3988
|
* Returns a cleanup function that disconnects both observers.
|
|
@@ -4644,15 +4723,20 @@ const HEIGHT_RELATED_PROPERTIES = ['height', 'min-height', 'max-height', 'top',
|
|
|
4644
4723
|
let elementsWithViewportUnits = new Set();
|
|
4645
4724
|
let originalValues = new WeakMap();
|
|
4646
4725
|
// ─── Regex ────────────────────────────────────────────────────────────────────
|
|
4647
|
-
/**
|
|
4726
|
+
/**
|
|
4727
|
+
* Stateless test-only regex (no `g` flag) — safe to share across calls.
|
|
4728
|
+
* Used exclusively for `.test()` checks before doing a full replacement.
|
|
4729
|
+
*/
|
|
4730
|
+
const VIEWPORT_RE_TEST = /([-.?\d]+)(vh|svh|lvh|dvh|vw|svw|lvw|dvw)/i;
|
|
4731
|
+
/** Fresh `g`-flagged instance for String.replace() callbacks. */
|
|
4648
4732
|
function createRegex() {
|
|
4649
|
-
return /([
|
|
4733
|
+
return /([-.?\d]+)(vh|svh|lvh|dvh|vw|svw|lvw|dvw)/gi;
|
|
4650
4734
|
}
|
|
4651
4735
|
// ─── Unit conversion ─────────────────────────────────────────────────────────
|
|
4652
4736
|
function px(value) {
|
|
4653
4737
|
return `${value.toFixed(2)}px`;
|
|
4654
4738
|
}
|
|
4655
|
-
function
|
|
4739
|
+
function buildUnitMap(ctx) {
|
|
4656
4740
|
return {
|
|
4657
4741
|
vh: ctx.targetHeight,
|
|
4658
4742
|
svh: ctx.targetHeight,
|
|
@@ -4664,15 +4748,15 @@ function getUnitMap(ctx) {
|
|
|
4664
4748
|
dvw: ctx.targetWidth,
|
|
4665
4749
|
};
|
|
4666
4750
|
}
|
|
4667
|
-
function toPx(value, unit,
|
|
4751
|
+
function toPx(value, unit, unitMap, targetHeight) {
|
|
4668
4752
|
const u = unit.toLowerCase();
|
|
4669
4753
|
if (u === '%')
|
|
4670
|
-
return (value / 100) *
|
|
4671
|
-
return (value / 100) * (
|
|
4754
|
+
return (value / 100) * targetHeight;
|
|
4755
|
+
return (value / 100) * (unitMap[u] ?? 0);
|
|
4672
4756
|
}
|
|
4673
|
-
function convert(value, unit,
|
|
4757
|
+
function convert(value, unit, unitMap, targetHeight) {
|
|
4674
4758
|
const num = parseFloat(value);
|
|
4675
|
-
return isNaN(num) ? value : px(toPx(num, unit,
|
|
4759
|
+
return isNaN(num) ? value : px(toPx(num, unit, unitMap, targetHeight));
|
|
4676
4760
|
}
|
|
4677
4761
|
function isHeightRelated(prop) {
|
|
4678
4762
|
return HEIGHT_RELATED_PROPERTIES.includes(prop);
|
|
@@ -4687,11 +4771,13 @@ function extractProperty(cssText, matchOffset) {
|
|
|
4687
4771
|
return m ? m[1].toLowerCase() : '';
|
|
4688
4772
|
}
|
|
4689
4773
|
function replaceInText(cssText, ctx) {
|
|
4774
|
+
const unitMap = buildUnitMap(ctx);
|
|
4775
|
+
const { targetHeight } = ctx;
|
|
4690
4776
|
return cssText.replace(createRegex(), (match, value, unit, offset) => {
|
|
4691
4777
|
if (unit === '%') {
|
|
4692
|
-
return isHeightRelated(extractProperty(cssText, offset)) ? convert(value, unit,
|
|
4778
|
+
return isHeightRelated(extractProperty(cssText, offset)) ? convert(value, unit, unitMap, targetHeight) : match;
|
|
4693
4779
|
}
|
|
4694
|
-
return convert(value, unit,
|
|
4780
|
+
return convert(value, unit, unitMap, targetHeight);
|
|
4695
4781
|
});
|
|
4696
4782
|
}
|
|
4697
4783
|
// ─── Element tracking ─────────────────────────────────────────────────────────
|
|
@@ -4720,7 +4806,7 @@ function processInlineStyles(ctx) {
|
|
|
4720
4806
|
let count = 0;
|
|
4721
4807
|
ctx.doc.querySelectorAll('[style]').forEach((el) => {
|
|
4722
4808
|
const style = el.getAttribute('style');
|
|
4723
|
-
if (style &&
|
|
4809
|
+
if (style && VIEWPORT_RE_TEST.test(style)) {
|
|
4724
4810
|
elementsWithViewportUnits.add(el);
|
|
4725
4811
|
el.setAttribute('style', replaceInText(style, ctx));
|
|
4726
4812
|
count++;
|
|
@@ -4733,7 +4819,7 @@ function processStyleTags(ctx) {
|
|
|
4733
4819
|
let count = 0;
|
|
4734
4820
|
ctx.doc.querySelectorAll('style').forEach((tag) => {
|
|
4735
4821
|
const css = tag.textContent || '';
|
|
4736
|
-
if (
|
|
4822
|
+
if (VIEWPORT_RE_TEST.test(css)) {
|
|
4737
4823
|
tag.textContent = replaceInText(css, ctx);
|
|
4738
4824
|
count++;
|
|
4739
4825
|
}
|
|
@@ -4751,7 +4837,7 @@ function processRule(rule, ctx) {
|
|
|
4751
4837
|
for (let i = 0; i < style.length; i++) {
|
|
4752
4838
|
const prop = style[i];
|
|
4753
4839
|
const value = style.getPropertyValue(prop);
|
|
4754
|
-
if (value &&
|
|
4840
|
+
if (value && VIEWPORT_RE_TEST.test(value)) {
|
|
4755
4841
|
hasVp = true;
|
|
4756
4842
|
propOriginals.set(prop, value);
|
|
4757
4843
|
style.setProperty(prop, replaceInText(value, ctx), style.getPropertyPriority(prop));
|
|
@@ -4762,8 +4848,11 @@ function processRule(rule, ctx) {
|
|
|
4762
4848
|
trackSelector(cssRule.selectorText, propOriginals, ctx);
|
|
4763
4849
|
}
|
|
4764
4850
|
if ('cssRules' in rule) {
|
|
4765
|
-
|
|
4766
|
-
|
|
4851
|
+
const nested = rule.cssRules;
|
|
4852
|
+
if (nested) {
|
|
4853
|
+
for (let i = 0; i < nested.length; i++) {
|
|
4854
|
+
count += processRule(nested[i], ctx);
|
|
4855
|
+
}
|
|
4767
4856
|
}
|
|
4768
4857
|
}
|
|
4769
4858
|
return count;
|
|
@@ -4771,25 +4860,29 @@ function processRule(rule, ctx) {
|
|
|
4771
4860
|
/** Processes only inline <style> sheets. Linked sheets are handled by processLinkedStylesheets. */
|
|
4772
4861
|
function processStylesheets(ctx) {
|
|
4773
4862
|
let total = 0;
|
|
4774
|
-
|
|
4863
|
+
const sheets = ctx.doc.styleSheets;
|
|
4864
|
+
for (let i = 0; i < sheets.length; i++) {
|
|
4865
|
+
const sheet = sheets[i];
|
|
4775
4866
|
if (sheet.href)
|
|
4776
|
-
|
|
4867
|
+
continue; // deferred to processLinkedStylesheets
|
|
4777
4868
|
try {
|
|
4778
|
-
|
|
4779
|
-
|
|
4869
|
+
const rules = sheet.cssRules;
|
|
4870
|
+
for (let j = 0; j < rules.length; j++) {
|
|
4871
|
+
total += processRule(rules[j], ctx);
|
|
4780
4872
|
}
|
|
4781
4873
|
}
|
|
4782
4874
|
catch (e) {
|
|
4783
4875
|
logger$1.warn('Cannot read stylesheet (CORS?):', e.message);
|
|
4784
4876
|
}
|
|
4785
|
-
}
|
|
4877
|
+
}
|
|
4786
4878
|
logger$1.log(`Replaced ${total} rules in inline stylesheets`);
|
|
4787
4879
|
return total;
|
|
4788
4880
|
}
|
|
4789
4881
|
async function processLinkedStylesheets(ctx) {
|
|
4790
4882
|
const links = ctx.doc.querySelectorAll('link[rel="stylesheet"]');
|
|
4791
4883
|
let count = 0;
|
|
4792
|
-
for (
|
|
4884
|
+
for (let i = 0; i < links.length; i++) {
|
|
4885
|
+
const link = links[i];
|
|
4793
4886
|
// Skip cross-origin — already in browser CSSOM, handled via processStylesheets
|
|
4794
4887
|
if (link.href && !link.href.startsWith(ctx.win.location.origin)) {
|
|
4795
4888
|
logger$1.log('Skipping cross-origin CSS:', link.href);
|
|
@@ -4798,7 +4891,7 @@ async function processLinkedStylesheets(ctx) {
|
|
|
4798
4891
|
try {
|
|
4799
4892
|
const res = await fetch(link.href);
|
|
4800
4893
|
let css = await res.text();
|
|
4801
|
-
if (
|
|
4894
|
+
if (VIEWPORT_RE_TEST.test(css)) {
|
|
4802
4895
|
css = replaceInText(css, ctx);
|
|
4803
4896
|
const style = ctx.doc.createElement('style');
|
|
4804
4897
|
style.textContent = css;
|
|
@@ -5057,35 +5150,52 @@ function configure(debug) {
|
|
|
5057
5150
|
}
|
|
5058
5151
|
async function run$1(ctx, activeGlobal, shopFix) {
|
|
5059
5152
|
// ── Phase 1: beforeProcess ────────────────────────────────────────────────
|
|
5153
|
+
const t1 = perf.mark('phase1.beforeProcess');
|
|
5060
5154
|
for (const fix of activeGlobal) {
|
|
5061
5155
|
if (fix.beforeProcess) {
|
|
5062
5156
|
logger.log(`[beforeProcess] ${fix.name}`);
|
|
5157
|
+
const t = perf.mark(`phase1.${fix.name}.beforeProcess`);
|
|
5063
5158
|
await fix.beforeProcess(ctx);
|
|
5159
|
+
perf.measure(`phase1.${fix.name}.beforeProcess`, t);
|
|
5064
5160
|
}
|
|
5065
5161
|
}
|
|
5066
5162
|
if (shopFix?.beforeProcess) {
|
|
5067
5163
|
logger.log('[beforeProcess] shop');
|
|
5164
|
+
const t = perf.mark('phase1.shop.beforeProcess');
|
|
5068
5165
|
await shopFix.beforeProcess(ctx);
|
|
5166
|
+
perf.measure('phase1.shop.beforeProcess', t);
|
|
5069
5167
|
}
|
|
5168
|
+
perf.measure('phase1.beforeProcess', t1);
|
|
5070
5169
|
// ── Phase 2: process ──────────────────────────────────────────────────────
|
|
5170
|
+
const t2 = perf.mark('phase2.process');
|
|
5071
5171
|
for (const fix of activeGlobal) {
|
|
5072
5172
|
if (fix.process) {
|
|
5073
5173
|
logger.log(`[process] ${fix.name}`);
|
|
5174
|
+
const t = perf.mark(`phase2.${fix.name}.process`);
|
|
5074
5175
|
await fix.process(ctx);
|
|
5176
|
+
perf.measure(`phase2.${fix.name}.process`, t);
|
|
5075
5177
|
}
|
|
5076
5178
|
}
|
|
5179
|
+
perf.measure('phase2.process', t2);
|
|
5077
5180
|
// ── Phase 3: afterProcess ─────────────────────────────────────────────────
|
|
5181
|
+
const t3 = perf.mark('phase3.afterProcess');
|
|
5078
5182
|
if (shopFix?.afterProcess) {
|
|
5079
5183
|
logger.log('[afterProcess] shop');
|
|
5184
|
+
const t = perf.mark('phase3.shop.afterProcess');
|
|
5080
5185
|
await shopFix.afterProcess(ctx);
|
|
5186
|
+
perf.measure('phase3.shop.afterProcess', t);
|
|
5081
5187
|
}
|
|
5082
5188
|
for (const fix of activeGlobal) {
|
|
5083
5189
|
if (fix.afterProcess) {
|
|
5084
5190
|
logger.log(`[afterProcess] ${fix.name}`);
|
|
5191
|
+
const t = perf.mark(`phase3.${fix.name}.afterProcess`);
|
|
5085
5192
|
await fix.afterProcess(ctx);
|
|
5193
|
+
perf.measure(`phase3.${fix.name}.afterProcess`, t);
|
|
5086
5194
|
}
|
|
5087
5195
|
}
|
|
5196
|
+
perf.measure('phase3.afterProcess', t3);
|
|
5088
5197
|
// ── Phase 4: getDimensions ────────────────────────────────────────────────
|
|
5198
|
+
const t4 = perf.mark('phase4.getDimensions');
|
|
5089
5199
|
return new Promise((resolve) => {
|
|
5090
5200
|
requestAnimationFrame(() => {
|
|
5091
5201
|
let dimensions = null;
|
|
@@ -5110,6 +5220,7 @@ async function run$1(ctx, activeGlobal, shopFix) {
|
|
|
5110
5220
|
dimensions = { height: getFinalHeight(ctx.doc, ctx.win), width: getFinalWidth(ctx.doc) };
|
|
5111
5221
|
}
|
|
5112
5222
|
logger.log('Final dimensions:', dimensions);
|
|
5223
|
+
perf.measure('phase4.getDimensions', t4);
|
|
5113
5224
|
resolve(dimensions);
|
|
5114
5225
|
});
|
|
5115
5226
|
});
|
|
@@ -5237,10 +5348,14 @@ async function run(s) {
|
|
|
5237
5348
|
const activeGlobal = getActiveFixes(ctx);
|
|
5238
5349
|
if (activeGlobal.length > 0)
|
|
5239
5350
|
s.logger.log(`Active global fixes: ${activeGlobal.map((f) => f.name).join(', ')}`);
|
|
5351
|
+
const tRun = perf.mark('viewport.run');
|
|
5240
5352
|
try {
|
|
5241
|
-
|
|
5353
|
+
const result = await run$1(ctx, activeGlobal, s.shopFix);
|
|
5354
|
+
perf.measure('viewport.run', tRun);
|
|
5355
|
+
return result;
|
|
5242
5356
|
}
|
|
5243
5357
|
catch (err) {
|
|
5358
|
+
perf.measure('viewport.run', tRun);
|
|
5244
5359
|
s.logger.error('Critical error:', err);
|
|
5245
5360
|
return { height: s.doc.body?.scrollHeight || 1000, width: s.doc.body?.scrollWidth || 1000 };
|
|
5246
5361
|
}
|
|
@@ -5289,16 +5404,23 @@ async function process(s) {
|
|
|
5289
5404
|
s.config.onError?.(new Error('Cannot access iframe document'));
|
|
5290
5405
|
return;
|
|
5291
5406
|
}
|
|
5407
|
+
const sessionId = `render-${Date.now()}`;
|
|
5408
|
+
perf.startSession(sessionId);
|
|
5409
|
+
const t0 = perf.mark('orchestrator.process');
|
|
5292
5410
|
try {
|
|
5293
5411
|
s.logger.log('Processing viewport units...');
|
|
5294
5412
|
s.viewportReplacer.start(s.iframe, s.config);
|
|
5295
5413
|
s.navigationBlocker.start(s.iframe, { debug: s.config.debug });
|
|
5296
5414
|
const result = await s.viewportReplacer.run();
|
|
5415
|
+
perf.measure('orchestrator.process', t0);
|
|
5416
|
+
perf.endSession();
|
|
5297
5417
|
s.logger.log('Process completed:', result);
|
|
5298
5418
|
s.config.onSuccess?.(result);
|
|
5299
5419
|
dispatchDimensionsEvent(result);
|
|
5300
5420
|
}
|
|
5301
5421
|
catch (error) {
|
|
5422
|
+
perf.measure('orchestrator.process', t0);
|
|
5423
|
+
perf.endSession();
|
|
5302
5424
|
s.logger.error('Failed to process:', error);
|
|
5303
5425
|
s.config.onError?.(error);
|
|
5304
5426
|
}
|
|
@@ -5792,6 +5914,17 @@ class GXVisualizer extends Visualizer {
|
|
|
5792
5914
|
};
|
|
5793
5915
|
}
|
|
5794
5916
|
|
|
5917
|
+
// ── Performance timing ────────────────────────────────────────────────────────
|
|
5918
|
+
function mark(label) {
|
|
5919
|
+
const t = performance.now();
|
|
5920
|
+
console.log(`[Render] ⏱ ${label}`);
|
|
5921
|
+
return t;
|
|
5922
|
+
}
|
|
5923
|
+
function measure(label, startMs) {
|
|
5924
|
+
const ms = (performance.now() - startMs).toFixed(1);
|
|
5925
|
+
console.log(`[Render] ✅ ${label} — ${ms}ms`);
|
|
5926
|
+
}
|
|
5927
|
+
// ── Hook ──────────────────────────────────────────────────────────────────────
|
|
5795
5928
|
const useHeatmapRender = () => {
|
|
5796
5929
|
const viewId = useViewIdContext();
|
|
5797
5930
|
const data = useHeatmapDataContext((s) => s.data);
|
|
@@ -5809,6 +5942,7 @@ const useHeatmapRender = () => {
|
|
|
5809
5942
|
return;
|
|
5810
5943
|
if (!payloads || payloads.length === 0)
|
|
5811
5944
|
return;
|
|
5945
|
+
const t0 = mark('renderHeatmap start');
|
|
5812
5946
|
const visualizer = vizRef ?? new GXVisualizer();
|
|
5813
5947
|
if (!vizRef)
|
|
5814
5948
|
setVizRef(visualizer);
|
|
@@ -5816,12 +5950,15 @@ const useHeatmapRender = () => {
|
|
|
5816
5950
|
const iframe = iframeRef.current;
|
|
5817
5951
|
if (!iframe?.contentWindow)
|
|
5818
5952
|
return;
|
|
5953
|
+
const tHtml = mark('visualizer.html start');
|
|
5819
5954
|
await visualizer.html(payloads, iframe.contentWindow, viewId);
|
|
5955
|
+
measure('visualizer.html', tHtml);
|
|
5820
5956
|
startIframe({
|
|
5821
5957
|
helperRef,
|
|
5822
5958
|
iframe,
|
|
5823
5959
|
deviceType,
|
|
5824
5960
|
size: { width: contentWidth, height: wrapperHeight },
|
|
5961
|
+
t0,
|
|
5825
5962
|
onSuccess: (height) => {
|
|
5826
5963
|
if (height)
|
|
5827
5964
|
setIframeHeight(height);
|
|
@@ -5849,12 +5986,14 @@ const useHeatmapRender = () => {
|
|
|
5849
5986
|
iframeRef,
|
|
5850
5987
|
};
|
|
5851
5988
|
};
|
|
5852
|
-
|
|
5989
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
5990
|
+
function startIframe({ helperRef, iframe, deviceType = EDeviceType.Desktop, size, t0, onSuccess }) {
|
|
5853
5991
|
const docWidth = size.width ?? 0;
|
|
5854
5992
|
const docHeight = size.height ?? 0;
|
|
5855
5993
|
if (docHeight === 0)
|
|
5856
5994
|
return;
|
|
5857
5995
|
helperRef.current?.stop();
|
|
5996
|
+
const tHelper = mark('IframeHelper.start');
|
|
5858
5997
|
const helper = createIframeHelper();
|
|
5859
5998
|
helperRef.current = helper;
|
|
5860
5999
|
helper.start({
|
|
@@ -5864,6 +6003,8 @@ function startIframe({ helperRef, iframe, deviceType = EDeviceType.Desktop, size
|
|
|
5864
6003
|
iframe,
|
|
5865
6004
|
debug: true,
|
|
5866
6005
|
onSuccess: (data) => {
|
|
6006
|
+
measure('IframeHelper processing', tHelper);
|
|
6007
|
+
measure('Total render', t0);
|
|
5867
6008
|
iframe.style.height = `${data.height}px`;
|
|
5868
6009
|
onSuccess(data.height);
|
|
5869
6010
|
},
|