UNPKG

@tamagui/react-native-web-lite

Version:
189 lines 6.39 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var FillRateHelper_exports = {}; __export(FillRateHelper_exports, { FillRateHelper: () => FillRateHelper, default: () => FillRateHelper_default }); module.exports = __toCommonJS(FillRateHelper_exports); class Info { any_blank_count = 0; any_blank_ms = 0; any_blank_speed_sum = 0; mostly_blank_count = 0; mostly_blank_ms = 0; pixels_blank = 0; pixels_sampled = 0; pixels_scrolled = 0; total_time_spent = 0; sample_count = 0; } const DEBUG = false; let _listeners = []; let _minSampleCount = 10; let _sampleRate = DEBUG ? 1 : null; class FillRateHelper { _anyBlankStartTime = null; _enabled = false; _getFrameMetrics; _info = new Info(); _mostlyBlankStartTime = null; _samplesStartTime = null; static addListener(callback) { if (_sampleRate === null) { console.warn("Call `FillRateHelper.setSampleRate` before `addListener`."); } _listeners.push(callback); return { remove: () => { _listeners = _listeners.filter(listener => callback !== listener); } }; } static setSampleRate(sampleRate) { _sampleRate = sampleRate; } static setMinSampleCount(minSampleCount) { _minSampleCount = minSampleCount; } constructor(getFrameMetrics) { this._getFrameMetrics = getFrameMetrics; this._enabled = (_sampleRate || 0) > Math.random(); this._resetData(); } activate() { if (this._enabled && this._samplesStartTime == null) { DEBUG && console.debug("FillRateHelper: activate"); this._samplesStartTime = global.performance.now(); } } deactivateAndFlush() { if (!this._enabled) { return; } const start = this._samplesStartTime; if (start == null) { DEBUG && console.debug("FillRateHelper: bail on deactivate with no start time"); return; } if (this._info.sample_count < _minSampleCount) { this._resetData(); return; } const total_time_spent = global.performance.now() - start; const info = { ...this._info, total_time_spent }; if (DEBUG) { const derived = { avg_blankness: this._info.pixels_blank / this._info.pixels_sampled, avg_speed: this._info.pixels_scrolled / (total_time_spent / 1e3), avg_speed_when_any_blank: this._info.any_blank_speed_sum / this._info.any_blank_count, any_blank_per_min: this._info.any_blank_count / (total_time_spent / 1e3 / 60), any_blank_time_frac: this._info.any_blank_ms / total_time_spent, mostly_blank_per_min: this._info.mostly_blank_count / (total_time_spent / 1e3 / 60), mostly_blank_time_frac: this._info.mostly_blank_ms / total_time_spent }; for (const key in derived) { derived[key] = Math.round(1e3 * derived[key]) / 1e3; } console.debug("FillRateHelper deactivateAndFlush: ", { derived, info }); } _listeners.forEach(listener => listener(info)); this._resetData(); } computeBlankness(props, cellsAroundViewport, scrollMetrics) { if (!this._enabled || props.getItemCount(props.data) === 0 || cellsAroundViewport.last < cellsAroundViewport.first || this._samplesStartTime == null) { return 0; } const { dOffset, offset, velocity, visibleLength } = scrollMetrics; this._info.sample_count++; this._info.pixels_sampled += Math.round(visibleLength); this._info.pixels_scrolled += Math.round(Math.abs(dOffset)); const scrollSpeed = Math.round(Math.abs(velocity) * 1e3); const now = global.performance.now(); if (this._anyBlankStartTime != null) { this._info.any_blank_ms += now - this._anyBlankStartTime; } this._anyBlankStartTime = null; if (this._mostlyBlankStartTime != null) { this._info.mostly_blank_ms += now - this._mostlyBlankStartTime; } this._mostlyBlankStartTime = null; let blankTop = 0; let first = cellsAroundViewport.first; let firstFrame = this._getFrameMetrics(first, props); while (first <= cellsAroundViewport.last && (!firstFrame || !firstFrame.inLayout)) { firstFrame = this._getFrameMetrics(first, props); first++; } if (firstFrame && first > 0) { blankTop = Math.min(visibleLength, Math.max(0, firstFrame.offset - offset)); } let blankBottom = 0; let last = cellsAroundViewport.last; let lastFrame = this._getFrameMetrics(last, props); while (last >= cellsAroundViewport.first && (!lastFrame || !lastFrame.inLayout)) { lastFrame = this._getFrameMetrics(last, props); last--; } if (lastFrame && last < props.getItemCount(props.data) - 1) { const bottomEdge = lastFrame.offset + lastFrame.length; blankBottom = Math.min(visibleLength, Math.max(0, offset + visibleLength - bottomEdge)); } const pixels_blank = Math.round(blankTop + blankBottom); const blankness = pixels_blank / visibleLength; if (blankness > 0) { this._anyBlankStartTime = now; this._info.any_blank_speed_sum += scrollSpeed; this._info.any_blank_count++; this._info.pixels_blank += pixels_blank; if (blankness > 0.5) { this._mostlyBlankStartTime = now; this._info.mostly_blank_count++; } } else if (scrollSpeed < 0.01 || Math.abs(dOffset) < 1) { this.deactivateAndFlush(); } return blankness; } enabled() { return this._enabled; } _resetData() { this._anyBlankStartTime = null; this._info = new Info(); this._mostlyBlankStartTime = null; this._samplesStartTime = null; } } var FillRateHelper_default = FillRateHelper;