Class: Dommy::Performance
- Inherits:
-
Object
- Object
- Dommy::Performance
- Includes:
- Bridge::Methods
- Defined in:
- lib/dommy/performance.rb
Overview
window.performance — User Timing API (mark / measure) plus a
virtual now clock backed by the deterministic scheduler.
Spec:
- User Timing: https://www.w3.org/TR/user-timing/
- HRT (now): https://www.w3.org/TR/hr-time/
Instance Method Summary collapse
- #__js_call__(method, args) ⇒ Object
- #__js_get__(key) ⇒ Object
- #clear_marks(name = nil) ⇒ Object (also: #clearMarks)
- #clear_measures(name = nil) ⇒ Object (also: #clearMeasures)
- #get_entries ⇒ Object (also: #getEntries)
- #get_entries_by_name(name, entry_type = nil) ⇒ Object (also: #getEntriesByName)
- #get_entries_by_type(entry_type) ⇒ Object (also: #getEntriesByType)
-
#initialize(window) ⇒ Performance
constructor
A new instance of Performance.
- #mark(name, options = nil) ⇒ Object
- #measure(name, start_or_options = nil, end_mark = nil) ⇒ Object
- #now ⇒ Object
Methods included from Bridge::Methods
Constructor Details
#initialize(window) ⇒ Performance
Returns a new instance of Performance.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/dommy/performance.rb', line 11 def initialize(window) @window = window @entries = [] # In browser mode (dommynx sets DOMMY_REAL_TIME_PERFORMANCE) `now` tracks # REAL wall-clock, not the deterministic scheduler's virtual clock. Virtual # time only advances between tasks (in advance_time), so it is FROZEN inside # a long synchronous task — and a concurrent renderer (React's scheduler) # decides when to yield by watching performance.now() cross a ~5ms frame # budget. With a frozen clock it never crosses, so React renders the entire # fiber tree in ONE eval that overruns the eval timeout ("InternalError: # interrupted"). A real clock lets it slice the work and yield (via # MessageChannel), so each eval stays short. Off by default → tests keep the # deterministic virtual clock. @real_time = !ENV["DOMMY_REAL_TIME_PERFORMANCE"].to_s.empty? @real_origin = nil end |
Instance Method Details
#__js_call__(method, args) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/dommy/performance.rb', line 118 def __js_call__(method, args) case method when "now" now when "mark" mark(args[0], args[1]) when "measure" measure(args[0], args[1], args[2]) when "clearMarks" clear_marks(args[0]) when "clearMeasures" clear_measures(args[0]) when "getEntries" get_entries when "getEntriesByName" get_entries_by_name(args[0], args[1]) when "getEntriesByType" get_entries_by_type(args[0]) end end |
#__js_get__(key) ⇒ Object
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/dommy/performance.rb', line 103 def __js_get__(key) case key when "now" now when "timeOrigin" 0.0 else Bridge::ABSENT end end |
#clear_marks(name = nil) ⇒ Object Also known as: clearMarks
71 72 73 74 |
# File 'lib/dommy/performance.rb', line 71 def clear_marks(name = nil) @entries.reject! { |e| e.entry_type == "mark" && (name.nil? || e.name == name.to_s) } nil end |
#clear_measures(name = nil) ⇒ Object Also known as: clearMeasures
78 79 80 81 |
# File 'lib/dommy/performance.rb', line 78 def clear_measures(name = nil) @entries.reject! { |e| e.entry_type == "measure" && (name.nil? || e.name == name.to_s) } nil end |
#get_entries ⇒ Object Also known as: getEntries
85 86 87 |
# File 'lib/dommy/performance.rb', line 85 def get_entries @entries.dup end |
#get_entries_by_name(name, entry_type = nil) ⇒ Object Also known as: getEntriesByName
91 92 93 |
# File 'lib/dommy/performance.rb', line 91 def get_entries_by_name(name, entry_type = nil) @entries.select { |e| e.name == name.to_s && (entry_type.nil? || e.entry_type == entry_type.to_s) } end |
#get_entries_by_type(entry_type) ⇒ Object Also known as: getEntriesByType
97 98 99 |
# File 'lib/dommy/performance.rb', line 97 def get_entries_by_type(entry_type) @entries.select { |e| e.entry_type == entry_type.to_s } end |
#mark(name, options = nil) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/dommy/performance.rb', line 36 def mark(name, = nil) start_time = .is_a?(Hash) && .key?("startTime") ? ["startTime"].to_f : now detail = .is_a?(Hash) ? ["detail"] : nil entry = PerformanceEntry.new( name: name.to_s, entry_type: "mark", start_time: start_time, duration: 0.0, detail: detail ) @entries << entry entry end |
#measure(name, start_or_options = nil, end_mark = nil) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/dommy/performance.rb', line 50 def measure(name, = nil, end_mark = nil) if .is_a?(Hash) start = resolve_time(["start"]) finish = resolve_time(["end"]) else start = resolve_time() finish = resolve_time(end_mark) end start ||= 0.0 finish ||= now entry = PerformanceEntry.new( name: name.to_s, entry_type: "measure", start_time: start, duration: finish - start ) @entries << entry entry end |
#now ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/dommy/performance.rb', line 28 def now return @window.scheduler.now_ms.to_f unless @real_time current = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) @real_origin ||= current current - @real_origin end |