git.iko.soy/typeable/elm-ui
on master help sign in
improve benchmarking suite
commitcc9b2aca2088f0536ed92ff1584b0919cfbed086 authorMatthew Griffith <mdg.griffith@gmail.com> dateSat 13 Jul 2019, 08:48 (7 years ago) parent750a57e
6 files changed+343−106
benchmarks/runtime/benchPage.js+52−3 benchmarks/runtime/index.js+52−26 benchmarks/src/Benchmark/Render.elm+13−1 benchmarks/src/ManyElements.elm+29−4 benchmarks/src/View/Results.elm+196−72 src/Internal/Model.elm+1
benchmarks/runtime/benchPage.js+52−3
@@ -1,23 +1,44 @@
11const path = require('path');
22
3−async function benchPage(page) {
3+async function benchPage(page, file) {
44 const client = await page.target().createCDPSession();
55 await client.send('Performance.enable');
66 // await page.tracing.start({ path: 'trace.json' });
7− await page.goto('file://' + path.resolve('./tmp/run.html'))
7+ await page.goto('file://' + path.resolve(file))
88
99 await page.waitFor(5000);
1010 // await page.tracing.stop();
1111 const metrics = await client.send('Performance.getMetrics');
12+
13+ const startMetrics = await page.metrics()
14+ await page.evaluate(() => { window.elmRefresh() })
15+ await page.waitFor(1500);
16+ const endMetrics = await page.metrics()
17+
1218 await page.evaluate(() => { window.elmStartAnim() })
1319 await sleep(5000)
1420 await page.evaluate(() => { window.elmStopAnim() })
21+ await page.waitFor(2000);
22+ const finalMetrics = await page.metrics()
1523 const frames = await page.evaluate(x => {
1624 return Promise.resolve(window.metrics);
1725 }, {});
1826 return {
1927 name: frames.name,
28+ link: 'file://' + path.resolve(file),
2029 perf: extract(metrics),
30+ afterRefresh: {
31+ RecalcStyleDuration: endMetrics.RecalcStyleDuration - startMetrics.RecalcStyleDuration,
32+ LayoutDuration: endMetrics.LayoutDuration - startMetrics.LayoutDuration,
33+ ScriptDuration: endMetrics.ScriptDuration - startMetrics.ScriptDuration,
34+ JSHeapUsedSize: endMetrics.JSHeapUsedSize - startMetrics.JSHeapUsedSize
35+ },
36+ afterAnimation: {
37+ RecalcStyleDuration: finalMetrics.RecalcStyleDuration - endMetrics.RecalcStyleDuration,
38+ LayoutDuration: finalMetrics.LayoutDuration - endMetrics.LayoutDuration,
39+ ScriptDuration: finalMetrics.ScriptDuration - endMetrics.ScriptDuration,
40+ JSHeapUsedSize: finalMetrics.JSHeapUsedSize - endMetrics.JSHeapUsedSize
41+ },
2142 frames: summarize(frames.frames),
2243 }
2344}
@@ -28,7 +49,9 @@ function summarize(frames) {
2849 median: median(frames),
2950 mode: mode(frames),
3051 avg: average(frames),
31− fps: 1000 / average(frames)
52+ fps: 1000 / median(frames),
53+ min: minimum(frames),
54+ max: maximum(frames)
3255 }
3356}
3457
@@ -65,6 +88,32 @@ function mode(array) {
6588 return maxEl;
6689}
6790
91+function minimum(values) {
92+ var m = null
93+ for (var i = 0; i < values.length; i++) {
94+ if (m == null) {
95+ m = values[i]
96+ } else if (values[i] < m) {
97+ m = values[i]
98+ }
99+ }
100+ return m
101+}
102+
103+
104+function maximum(values) {
105+ var m = null
106+ for (var i = 0; i < values.length; i++) {
107+ if (m == null) {
108+ m = values[i]
109+ } else if (values[i] > m) {
110+ m = values[i]
111+ }
112+ }
113+ return m
114+}
115+
116+
68117function average(values) {
69118 var total = 0;
70119 for (var i = 0; i < values.length; i++) {
benchmarks/runtime/index.js+52−26
@@ -35,13 +35,31 @@ function regroupResults(results) {
3535 if (results[i].group) {
3636
3737 var reorged = {
38− count: results[i].count
38+ name: results[i].name
39+ , link: results[i].link
40+ , count: results[i].count
3941 , fps: results[i].frames.fps
4042 , timeToFirstPaintMS: results[i].perf.TimeToFirstPaintMS
4143 , nodes: results[i].perf.Nodes
42− , layoutSeconds: results[i].perf.LayoutDuration
43− , recalcStyleSeconds: results[i].perf.RecalcStyleDuration
44− , scriptDurationSeconds: results[i].perf.ScriptDuration
44+ , coldRender: {
45+ layoutSeconds: results[i].perf.LayoutDuration
46+ , recalcStyleSeconds: results[i].perf.RecalcStyleDuration
47+ , scriptDurationSeconds: results[i].perf.ScriptDuration
48+
49+ }
50+ , warmRender: {
51+ layoutSeconds: results[i].afterRefresh.LayoutDuration
52+ , recalcStyleSeconds: results[i].afterRefresh.RecalcStyleDuration
53+ , scriptDurationSeconds: results[i].afterRefresh.ScriptDuration
54+
55+ }
56+ , extendedRender: {
57+ layoutSeconds: results[i].afterAnimation.LayoutDuration
58+ , recalcStyleSeconds: results[i].afterAnimation.RecalcStyleDuration
59+ , scriptDurationSeconds: results[i].afterAnimation.ScriptDuration
60+
61+ }
62+
4563 }
4664 if (results[i].group in regrouped) {
4765 regrouped[results[i].group].results.push(reorged)
@@ -58,8 +76,8 @@ var contain = [{ module: "Contain", group: "html", count: 1024, value: "viewHtml
5876 , { module: "Contain", group: "contain", count: 128, value: "viewHtmlContain8192" }]
5977
6078
61−async function write_results(allResults) {
62− var resultsDir = "benchmarks/results"
79+async function writeResults(allResults, resultsDir, name) {
80+
6381 if (!fs.existsSync(resultsDir)) {
6482 fs.mkdirSync(resultsDir);
6583 }
@@ -68,7 +86,7 @@ async function write_results(allResults) {
6886 // we embed the compiled js to avoid having to start a server to read the app.
6987 await compileToString(["./src/View/Results.elm"], { optimize: true, cwd: "./benchmarks" }).then(function (compiled_elm_code) {
7088 const compiled = eval(`\`${template}\``)
71− fs.writeFileSync(`./${resultsDir}/1.1.1-cand.html`, compiled)
89+ fs.writeFileSync(`./${resultsDir}/${name}/index.html`, compiled)
7290 });
7391
7492 // fs.writeFileSync(`./${resultsDir}/1.1.1-candidate-optimized.json`, results)
@@ -82,40 +100,40 @@ async function write_results(allResults) {
82100 var instances = [
83101 { module: "Baseline", group: null, value: "bench" }
84102 , { module: "ManyElements", group: "elmUI", count: 1024, value: "elmUI1024" }
85− , { module: "ManyElements", group: "elmUI", count: 128, value: "elmUI128" }
103+ // , { module: "ManyElements", group: "elmUI", count: 128, value: "elmUI128" }
86104 , { module: "ManyElements", group: "elmUI", count: 2048, value: "elmUI2048" }
87105 , { module: "ManyElements", group: "elmUI", count: 24, value: "elmUI24" }
88− , { module: "ManyElements", group: "elmUI", count: 256, value: "elmUI256" }
106+ // , { module: "ManyElements", group: "elmUI", count: 256, value: "elmUI256" }
89107 , { module: "ManyElements", group: "elmUI", count: 4096, value: "elmUI4096" }
90− , { module: "ManyElements", group: "elmUI", count: 512, value: "elmUI512" }
91− , { module: "ManyElements", group: "elmUI", count: 64, value: "elmUI64" }
108+ // , { module: "ManyElements", group: "elmUI", count: 512, value: "elmUI512" }
109+ // , { module: "ManyElements", group: "elmUI", count: 64, value: "elmUI64" }
92110 , { module: "ManyElements", group: "elmUI", count: 8192, value: "elmUI8192" }
93111 , { module: "ManyElements", group: "elmUIVCSS", count: 1024, value: "elmUIVCSS1024" }
94− , { module: "ManyElements", group: "elmUIVCSS", count: 128, value: "elmUIVCSS128" }
112+ // , { module: "ManyElements", group: "elmUIVCSS", count: 128, value: "elmUIVCSS128" }
95113 , { module: "ManyElements", group: "elmUIVCSS", count: 2048, value: "elmUIVCSS2048" }
96114 , { module: "ManyElements", group: "elmUIVCSS", count: 24, value: "elmUIVCSS24" }
97− , { module: "ManyElements", group: "elmUIVCSS", count: 256, value: "elmUIVCSS256" }
115+ // , { module: "ManyElements", group: "elmUIVCSS", count: 256, value: "elmUIVCSS256" }
98116 , { module: "ManyElements", group: "elmUIVCSS", count: 4096, value: "elmUIVCSS4096" }
99− , { module: "ManyElements", group: "elmUIVCSS", count: 512, value: "elmUIVCSS512" }
100− , { module: "ManyElements", group: "elmUIVCSS", count: 64, value: "elmUIVCSS64" }
117+ // , { module: "ManyElements", group: "elmUIVCSS", count: 512, value: "elmUIVCSS512" }
118+ // , { module: "ManyElements", group: "elmUIVCSS", count: 64, value: "elmUIVCSS64" }
101119 , { module: "ManyElements", group: "elmUIVCSS", count: 8192, value: "elmUIVCSS8192" }
102120 , { module: "ManyElements", group: "viewHtml", count: 1024, value: "viewHtml1024" }
103− , { module: "ManyElements", group: "viewHtml", count: 128, value: "viewHtml128" }
121+ // , { module: "ManyElements", group: "viewHtml", count: 128, value: "viewHtml128" }
104122 , { module: "ManyElements", group: "viewHtml", count: 2048, value: "viewHtml2048" }
105123 , { module: "ManyElements", group: "viewHtml", count: 24, value: "viewHtml24" }
106− , { module: "ManyElements", group: "viewHtml", count: 256, value: "viewHtml256" }
124+ // , { module: "ManyElements", group: "viewHtml", count: 256, value: "viewHtml256" }
107125 , { module: "ManyElements", group: "viewHtml", count: 4096, value: "viewHtml4096" }
108− , { module: "ManyElements", group: "viewHtml", count: 512, value: "viewHtml512" }
109− , { module: "ManyElements", group: "viewHtml", count: 64, value: "viewHtml64" }
126+ // , { module: "ManyElements", group: "viewHtml", count: 512, value: "viewHtml512" }
127+ // , { module: "ManyElements", group: "viewHtml", count: 64, value: "viewHtml64" }
110128 , { module: "ManyElements", group: "viewHtml", count: 8192, value: "viewHtml8192" }
111129 , { module: "ManyElements", group: "viewInline", count: 1024, value: "viewInline1024" }
112− , { module: "ManyElements", group: "viewInline", count: 128, value: "viewInline128" }
130+ // , { module: "ManyElements", group: "viewInline", count: 128, value: "viewInline128" }
113131 , { module: "ManyElements", group: "viewInline", count: 2048, value: "viewInline2048" }
114132 , { module: "ManyElements", group: "viewInline", count: 24, value: "viewInline24" }
115− , { module: "ManyElements", group: "viewInline", count: 256, value: "viewInline256" }
133+ // , { module: "ManyElements", group: "viewInline", count: 256, value: "viewInline256" }
116134 , { module: "ManyElements", group: "viewInline", count: 4096, value: "viewInline4096" }
117− , { module: "ManyElements", group: "viewInline", count: 512, value: "viewInline512" }
118− , { module: "ManyElements", group: "viewInline", count: 64, value: "viewInline64" }
135+ // , { module: "ManyElements", group: "viewInline", count: 512, value: "viewInline512" }
136+ // , { module: "ManyElements", group: "viewInline", count: 64, value: "viewInline64" }
119137 , { module: "ManyElements", group: "viewInline", count: 8192, value: "viewInline8192" }
120138 ]
121139
@@ -131,20 +149,28 @@ async function write_results(allResults) {
131149 }
132150
133151 var allResults = []
152+ const resultsDir = "benchmarks/results"
153+ const resultName = "1.2-cand"
154+
155+ if (!fs.existsSync(`./${resultsDir}/${resultName}/instances/`)) {
156+ fs.mkdirSync(`./${resultsDir}/${resultName}/instances/`, { recursive: true });
157+ }
158+
134159
135160 for (var i = 0; i < instances.length; i++) {
136161 var item = instances[i]
137162 write_entrypoint(item)
163+ const test_file = `${resultsDir}/${resultName}/instances/${item.value}.html`
138164 var template = fs.readFileSync("./benchmarks/runtime/template/run.html")
139165 var cssom = fs.readFileSync("./experiments/virtual-css/cssom.js")
140166 // we embed the compiled js to avoid having to start a server to read the app.
141167 await compileToString(["tmp/Main.elm"], { optimize: true, cwd: "./benchmarks" }).then(function (compiled_elm_code) {
142168 const compiled = eval(`\`${template}\``)
143− fs.writeFileSync("./tmp/run.html", compiled)
169+ fs.writeFileSync(test_file, compiled)
144170 });
145171
146172 const page = await browser.newPage();
147− const results = await benchPage(page);
173+ const results = await benchPage(page, test_file);
148174 results.group = item.group
149175 results.count = item.count
150176 await page.close()
@@ -155,6 +181,6 @@ async function write_results(allResults) {
155181
156182 allResults = regroupResults(allResults)
157183
158− write_results(allResults)
184+ writeResults(allResults, resultsDir, resultName)
159185
160186})();
benchmarks/src/Benchmark/Render.elm+13−1
@@ -6,6 +6,8 @@ port module Benchmark.Render exposing (Benchmark, toProgram)
66import Browser
77import Browser.Events
88import Html exposing (Html)
9+import Html.Attributes as Attr
10+import Html.Events as Events
911import Json.Decode as Decode
1012import Json.Encode as Encode
1113import Time
@@ -50,7 +52,17 @@ toProgram render =
5052 , view =
5153 \model ->
5254 { title = render.name
53− , body = [ render.view model.model ]
55+ , body =
56+ [ Html.div
57+ [ Attr.style "display" "flex"
58+ , Attr.style "flex-direction" "row"
59+ ]
60+ [ Html.button [ Events.onClick Refresh ] [ Html.text "Refresh" ]
61+ , Html.button [ Events.onClick StartAnim ] [ Html.text "StartAnim" ]
62+ , Html.button [ Events.onClick StopAnim ] [ Html.text "StopAnim" ]
63+ ]
64+ , render.view model.model
65+ ]
5466 }
5567 , update =
5668 update render
benchmarks/src/ManyElements.elm+29−4
@@ -343,14 +343,14 @@ viewEl selectedIndex index =
343343 el
344344 [ Background.color
345345 (if selectedIndex == index then
346− pink
346+ pinkish index
347347
348348 else
349349 white
350350 )
351351 , Font.color
352352 (if selectedIndex /= index then
353− pink
353+ pinkish index
354354
355355 else
356356 white
@@ -375,6 +375,21 @@ pink =
375375 rgb255 240 0 245
376376
377377
378+pinkish i =
379+ rgb255 (wrap255 (i + 240)) 0 245
380+
381+
382+wrap255 i =
383+ if i > 255 then
384+ 0
385+
386+ else if i < 0 then
387+ 0
388+
389+ else
390+ i
391+
392+
378393{-| -}
379394viewHtml : String -> Int -> Benchmark.Render.Benchmark Model Msg
380395viewHtml name count =
@@ -470,14 +485,14 @@ viewInline name count =
470485viewInlineHtmlElement selectedIndex index =
471486 Html.div
472487 (if selectedIndex == index then
473− [ Html.Attributes.style "background-color" "rgb(240, 0, 245)"
488+ [ Html.Attributes.style "background-color" (renderColor (wrap255 (index + 240)) 0 245)
474489 , Html.Attributes.style "color" "white"
475490 , Html.Attributes.style "padding" "24"
476491 ]
477492
478493 else
479494 [ Html.Attributes.style "background-color" "white"
480− , Html.Attributes.style "color" "rgb(240, 0, 245)"
495+ , Html.Attributes.style "color" (renderColor (wrap255 (index + 240)) 0 245)
481496 , Html.Attributes.style "padding" "24"
482497 ]
483498 )
@@ -489,3 +504,13 @@ viewInlineHtmlElement selectedIndex index =
489504 Html.text "Hello!"
490505 ]
491506 ]
507+
508+
509+renderColor r g b =
510+ "rgb("
511+ ++ String.fromInt r
512+ ++ ","
513+ ++ String.fromInt g
514+ ++ ","
515+ ++ String.fromInt b
516+ ++ ")"
benchmarks/src/View/Results.elm+196−72
@@ -3,11 +3,15 @@ port module View.Results exposing (main)
33import Browser
44import Color
55import Html
6−import Html.Attributes exposing (class)
6+import Html.Attributes as Attr exposing (class)
77import LineChart as LineChart
88import LineChart.Area as Area
99import LineChart.Axis as Axis
1010import LineChart.Axis.Intersection as Intersection
11+import LineChart.Axis.Line as AxisLine
12+import LineChart.Axis.Range as Range
13+import LineChart.Axis.Ticks as Ticks
14+import LineChart.Axis.Title as Title
1115import LineChart.Colors as Colors
1216import LineChart.Container as Container
1317import LineChart.Dots as Dots
@@ -19,6 +23,22 @@ import LineChart.Legends as Legends
1923import LineChart.Line as Line
2024
2125
26+row children =
27+ Html.div
28+ [ Attr.style "display" "flex"
29+ , Attr.style "flex-direction" "row"
30+ ]
31+ children
32+
33+
34+column children =
35+ Html.div
36+ [ Attr.style "display" "flex"
37+ , Attr.style "flex-direction" "column"
38+ ]
39+ children
40+
41+
2242main =
2343 Browser.document
2444 { init =
@@ -32,12 +52,58 @@ main =
3252 , body =
3353 [ Html.div
3454 [ class "container" ]
35− ([ viewNodes model.data
36− , viewFps model.data
37− , viewTimeToPaint model.data
38− ]
39− ++ List.map viewTimeDistribution model.data
40− )
55+ [ row
56+ (List.map viewLinks model.data)
57+ , row
58+ [ viewNodes model.data
59+ , viewFps model.data
60+ , viewTimeToPaint model.data
61+ ]
62+ , row
63+ [ column
64+ (List.map
65+ (\data ->
66+ viewRenderBreakdown
67+ { get = .coldRender
68+ , getCount = .count
69+ , name = data.name
70+ , flavor = "Cold render"
71+ , range = (0, 1.2)
72+ }
73+ (List.sortBy .count data.results)
74+ )
75+ model.data
76+ )
77+ , column
78+ (List.map
79+ (\data ->
80+ viewRenderBreakdown
81+ { get = .warmRender
82+ , getCount = .count
83+ , name = data.name
84+ , flavor = "Warm render"
85+ , range = (0, 1.2)
86+ }
87+ (List.sortBy .count data.results)
88+ )
89+ model.data
90+ )
91+ , column
92+ (List.map
93+ (\data ->
94+ viewRenderBreakdown
95+ { get = .extendedRender
96+ , getCount = .count
97+ , name = data.name
98+ , flavor = "Long Animation"
99+ , range = (0, 5)
100+ }
101+ (List.sortBy .count data.results)
102+ )
103+ model.data
104+ )
105+ ]
106+ ]
41107 ]
42108 }
43109 , update =
@@ -61,6 +127,20 @@ update msg model =
61127 ( { data = data }, Cmd.none )
62128
63129
130+viewLinks data =
131+ column
132+ (Html.h2 [] [ Html.text data.name ]
133+ :: (data.results
134+ |> List.sortBy .link
135+ |> List.map viewSingleLink
136+ )
137+ )
138+
139+
140+viewSingleLink result =
141+ Html.a [ Attr.href result.link ] [ Html.text result.name ]
142+
143+
64144
65145-- DATA
66146
@@ -79,11 +159,23 @@ type alias Data =
79159
80160
81161type alias Render =
82− { count : Float
162+ { name : String
163+ , count : Float
83164 , fps : Float
84165 , timeToFirstPaintMS : Float
85166 , nodes : Float
86− , layoutSeconds : Float
167+ , link : String
168+ , coldRender :
169+ Breakdown
170+ , warmRender :
171+ Breakdown
172+ , extendedRender :
173+ Breakdown
174+ }
175+
176+
177+type alias Breakdown =
178+ { layoutSeconds : Float
87179 , recalcStyleSeconds : Float
88180 , scriptDurationSeconds : Float
89181 }
@@ -112,12 +204,27 @@ getShape i =
112204 Dots.triangle
113205
114206
207+graphWidth =
208+ 800
209+
210+
211+graphHeight =
212+ 500
213+
214+
215+container =
216+ Container.styled "line-chart-1"
217+ [ ( "font-family", "monospace" )
218+ , ( "flex-shrink", "0" )
219+ ]
220+
221+
115222viewFps : List Data -> Html.Html msg
116223viewFps datums =
117224 LineChart.viewCustom
118− { y = Axis.default 800 "FPS" .fps
119− , x = Axis.default 1400 "Base Count" .count
120− , container = Container.styled "line-chart-1" [ ( "font-family", "monospace" ) ]
225+ { y = Axis.default graphHeight "FPS" .fps
226+ , x = Axis.default graphWidth "Base Count" .count
227+ , container = container
121228 , interpolation =
122229 -- Try out these different configs!
123230 -- Interpolation.linear
@@ -143,9 +250,9 @@ viewResult i data =
143250viewTimeToPaint : List Data -> Html.Html msg
144251viewTimeToPaint datums =
145252 LineChart.viewCustom
146− { y = Axis.default 800 "First Paint" (max 0 << .timeToFirstPaintMS)
147− , x = Axis.default 1400 "Base Count" .count
148− , container = Container.styled "line-chart-1" [ ( "font-family", "monospace" ) ]
253+ { y = Axis.default graphHeight "First Paint" (max 0 << .timeToFirstPaintMS)
254+ , x = Axis.default graphWidth "Base Count" .count
255+ , container = container
149256 , interpolation =
150257 -- Try out these different configs!
151258 -- Interpolation.linear
@@ -167,9 +274,9 @@ viewTimeToPaint datums =
167274viewNodes : List Data -> Html.Html msg
168275viewNodes datums =
169276 LineChart.viewCustom
170− { y = Axis.default 800 "Nodes" .nodes
171− , x = Axis.default 1400 "Base Count" .count
172− , container = Container.styled "line-chart-1" [ ( "font-family", "monospace" ) ]
277+ { y = Axis.default graphHeight "Nodes" .nodes
278+ , x = Axis.default graphWidth "Base Count" .count
279+ , container = container
173280 , interpolation =
174281 -- Try out these different configs!
175282 -- Interpolation.linear
@@ -188,62 +295,79 @@ viewNodes datums =
188295 (List.indexedMap viewResult datums)
189296
190297
191−viewTimeDistribution : Data -> Html.Html msg
192−viewTimeDistribution data =
193− let
194− sorted =
195− List.sortBy .count data.results
196− in
197− LineChart.viewCustom
198− { y = Axis.default 800 (data.name ++ "(s)") .seconds
199− , x = Axis.default 1400 "Base Count" .count
200− , container = Container.styled "line-chart-1" [ ( "font-family", "monospace" ) ]
201− , interpolation =
202− -- Try out these different configs!
203− -- Interpolation.linear
204− Interpolation.monotone
205−
206− -- Interpolation.stepped
207− , intersection = Intersection.default
208− , legends = Legends.default
209− , events = Events.default
210− , junk = Junk.default
211− , grid = Grid.default
212− , area = Area.stacked 0.5
213− , line = Line.default
214− , dots = Dots.default
215− }
216− [ LineChart.line (getColor 0)
217− (getShape 0)
218− "Layout"
219− (List.map
220− (\x ->
221− { seconds = x.layoutSeconds
222− , count = x.count
298+viewRenderBreakdown :
299+ { get : Render -> Breakdown
300+ , getCount : Render -> Float
301+ , name : String
302+ , flavor : String
303+ , range : (Float, Float)
304+ }
305+ -> List Render
306+ -> Html.Html msg
307+viewRenderBreakdown { get, getCount, name, flavor, range } results =
308+ Html.div []
309+ [ Html.h2 [] [ Html.text (name ++ ", " ++ flavor) ]
310+ , LineChart.viewCustom
311+ { y =
312+ Axis.custom
313+ { title = Title.default (name ++ "(s)")
314+ , variable = Just << .seconds
315+ , pixels = graphHeight
316+ , range = Range.window (Tuple.first range) (Tuple.second range)
317+ , axisLine = AxisLine.full Colors.black
318+ , ticks = Ticks.default
223319 }
320+ , x = Axis.default graphWidth "Base Count" .count
321+ , container = container
322+ , interpolation =
323+ -- Try out these different configs!
324+ -- Interpolation.linear
325+ Interpolation.monotone
326+
327+ -- Interpolation.stepped
328+ , intersection = Intersection.default
329+ , legends = Legends.default
330+ , events = Events.default
331+ , junk = Junk.default
332+ , grid = Grid.default
333+ , area = Area.stacked 0.5
334+ , line = Line.default
335+ , dots = Dots.default
336+ }
337+ [ LineChart.line (getColor 0)
338+ (getShape 0)
339+ "Layout"
340+ (List.map
341+ (\x ->
342+ { seconds = .layoutSeconds (get x)
343+ , count = getCount x
344+ }
345+ )
346+ results
224347 )
225− sorted
226− )
227− , LineChart.line (getColor 1)
228− (getShape 1)
229− "RecalcStyle"
230− (List.map
231− (\x ->
232− { seconds = x.recalcStyleSeconds
233− , count = x.count
234− }
348+ , LineChart.line (getColor 1)
349+ (getShape 1)
350+ "RecalcStyle"
351+ (List.map
352+ (\x ->
353+ { seconds =
354+ .recalcStyleSeconds (get x)
355+ , count = getCount x
356+ }
357+ )
358+ results
235359 )
236− sorted
237− )
238− , LineChart.line (getColor 2)
239− (getShape 2)
240− "Script"
241− (List.map
242− (\x ->
243− { seconds = x.scriptDurationSeconds
244− , count = x.count
245− }
360+ , LineChart.line (getColor 2)
361+ (getShape 2)
362+ "Script"
363+ (List.map
364+ (\x ->
365+ { seconds =
366+ .scriptDurationSeconds (get x)
367+ , count = getCount x
368+ }
369+ )
370+ results
246371 )
247− sorted
248− )
372+ ]
249373 ]
src/Internal/Model.elm+1
@@ -16,6 +16,7 @@ module Internal.Model exposing
1616 , LayoutContext(..)
1717 , Length(..)
1818 , Location(..)
19+ , NearbyChildren(..)
1920 , NodeName(..)
2021 , Option(..)
2122 , OptionRecord