Dart: static vs dynamic resource utilization

Issue

In Dart, when you run cross-compiled JavaScript, there are two ways of creating an instance of an element, such as a ButtonElement:

Dynamically (creating a new button and adding it to the browser DOM):

ButtonElement button = new ButtonElement();
button
    ..name="fizz"
    ..id="blah"
    ..onClick.listen(handle);

window.document.body.children.add(button);

Statically (loading an existing button that already exists in the browser DOM):

ButtonElement button = querySelector("#button") as ButtonElement;
button
    ..name="fizz"
    ..id="blah"
    ..onClick.listen(handle);

I’m interested in both speed and memory considerations between the two methods above:

  • Which is faster, and why?
  • Which has a smaller memory footprint, and why?

My guess is that the former method is slower because it forces JavaScript to create the ButtonElement (which eats up CPU cycles), which must then be added to the browser DOM.

But I have absolutely no idea which method is more efficient w.r.t. memory, or even how to test for such a thing.

Solution

You are right, it is definitely faster to load an existing button rather than create one. Parsing markup is highly optimized in browsers, plus having to create and add the element to the DOM is extra overhead, as you mentioned. I ran a simple benchmark with the Stopwatch class:

ButtonElement button1 = querySelector("#button") as ButtonElement
    ..name = "fizz"
    ..onClick.listen(handle);

Stopwatch s = new Stopwatch()
    ..start();

for(int i = 0; i < 1000; i++) {
  ButtonElement button1 = querySelector("#button") as ButtonElement
      ..name = "fizz$i"
      ..onClick.listen(handle);
}
s.stop();

print('queried button: ${s.elapsedMilliseconds / 1000} ms');

ButtonElement button2 = new ButtonElement()
    ..name = "fizz2"
    ..onClick.listen(handle);
document.body.children.add(button2);  

s.start();
for(int i = 0; i < 1000; i++) {
  ButtonElement button2 = new ButtonElement()
      ..name = "fizz2$i"
      ..onClick.listen(handle);

  document.body.children.add(button2);  
}

s.stop();

print('created button: ${s.elapsedMilliseconds / 1000} ms');

Results: queried button: 0.01 ms, created button: 0.022 ms.

Answered By – ringstaff

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *