Skip to content

Commit 0d6b02b

Browse files
committed
Lack of requestIdleCallback on iOS was causing unexpected event emission ordering due to synchronous emission of an asset during a full snapshot before the FullSnapshot event could be emitted. At least if they explicitly set processStylesheetsWithin=0 then there is a cause relating to this outcome. A further update might ensure that all Assets emitted during a FullSnapshot take on the timestamp of the FullSnapshot
1 parent 5c17dd5 commit 0d6b02b

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

docs/assets.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The `captureAssets` configuration option allows you to customize the asset captu
3232

3333
- `stylesheetsRuleThreshold` (default: `0`): only invoke the asset system for stylesheets with more than this number of rules. Defaults to zero (rather than say 100) as it only looks at the 'outer' rules (e.g. could have a single media rule which nests 1000s of sub rules). This default may be increased based on feedback.
3434

35-
- `processStylesheetsWithin` (default: `2000`): This property defines the maximum time in milliseconds that the browser should delay before processing stylesheets. Inline `<style>` elements will be processed within half this value. Lower this value if you wish to improve the odds that short 'bounce' visits will emit the asset before visitor unloads page. Set to zero or a negative number to process stylesheets synchronously, which can cause poor scores on e.g. https://pagespeed.web.dev/ ("Third-party code blocked the main thread").
35+
- `processStylesheetsWithin` (default: `2000`): This property defines the maximum time in milliseconds that the browser should delay before processing stylesheets. Inline `<style>` elements will be processed within half this value. Lower this value if you wish to improve the odds that short 'bounce' visits will emit the asset before visitor unloads page. Set to zero or a negative number to process stylesheets synchronously, which can cause poor scores on e.g. https://pagespeed.web.dev/ ("Third-party code blocked the main thread"), and also cause assets to be emitted with an earlier timestamp than the snapshot they are associated with.
3636

3737
## TypeScript Type Definition
3838

packages/rrweb/src/record/observers/asset-manager.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,16 @@ export default class AssetManager {
244244
if (!timeout && timeout !== 0) {
245245
timeout = 2000;
246246
}
247-
if (window.requestIdleCallback !== undefined && timeout > 0) {
247+
if (timeout <= 0) {
248+
// warning: stylesheet will be emitted with an earlier timestamp than snapshot it is associated with
249+
processStylesheet();
250+
return {
251+
url,
252+
status: 'captured',
253+
info: 'just processed',
254+
timeout,
255+
};
256+
} else if (window.requestIdleCallback !== undefined) {
248257
if (el.tagName === 'STYLE') {
249258
// mark it so mutations on it can be ignored until processed
250259
(el as ProcessingStyleElement).__rrProcessingStylesheet = true;
@@ -263,11 +272,16 @@ export default class AssetManager {
263272
timeout,
264273
};
265274
} else {
266-
processStylesheet();
275+
// fallback for e.g. iOS which doesn't have requestIdleCallback
276+
// we still defer so that it isn't emitted before FullSnapshot
277+
// and also so that we don't block the main thread.
278+
// don't use the `timeout` variable as that should be seen
279+
// as a maximum delay and not a minimum
280+
setTimeout(processStylesheet, 0);
267281
return {
268282
url,
269-
status: 'captured',
270-
info: 'just processed',
283+
status: 'capturing', // 'processing' ?
284+
timeout: 1, // not sure how to make this figure meaningful in the context of setTimeout
271285
};
272286
}
273287
}

0 commit comments

Comments
 (0)