Blockly Rendering Times

627 views
Skip to first unread message

Neil Fraser

unread,
Jan 24, 2015, 2:56:31 AM1/24/15
to blo...@googlegroups.com, christoph...@gmail.com
Christopher Casilli raised the point that block rendering times were exponentially nasty for large programs

Rendering times for Blockly have improved significantly over the past week.  Loading blocks from XML now happens headlessly, then a single render pass displays everything (as opposed to the recursive O(n^2) approach used earlier).  The graph is still not linear, and further investigation is needed to determine where this curve is coming from.  None the less, this represents a significant improvement.


--
Neil Fraser
https://neil.fraser.name

Chris Casilli

unread,
Jan 25, 2015, 8:38:33 AM1/25/15
to blo...@googlegroups.com, christoph...@gmail.com, ro...@neil.fraser.name
Hi Neil,

Awesome! I tried it out and it is much better for the smaller programs. I still get the spinning cursor for larger programs as predicted by your analysis, but it is much better for smaller stuff.
Looking forward to continued enhancements regarding speed!
Thanks again for you attention to this matter.

Chris

Neil Fraser

unread,
Jan 26, 2015, 7:59:04 AM1/26/15
to blo...@googlegroups.com, Chris Casilli
Rendering times are now linear.


On Saturday, January 24, 2015 at 2:56:31 AM UTC-5, Neil Fraser wrote:
Christopher Casilli raised the point that block rendering times were exponentially nasty for large programs

Rendering times for Blockly have improved significantly over the past week.  Loading blocks from XML now happens headlessly, then a single render pass displays everything (as opposed to the recursive O(n^2) approach used earlier).  The graph is still not linear, and further investigation is needed to determine where this curve is coming from.  None the less, this represents a significant improvement.


--
Neil Fraser
https://neil.fraser.name

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Casilli

unread,
Jan 26, 2015, 10:54:52 AM1/26/15
to blo...@googlegroups.com, christoph...@gmail.com, ro...@neil.fraser.name
Hi Neil,

You Rock!
Works awesome! thank you so much. Now I can convert back and forth between Blockly and code for any of my programs!

Chris Casilli

Chris Casilli

unread,
Feb 3, 2015, 11:38:26 AM2/3/15
to blo...@googlegroups.com, christoph...@gmail.com, ro...@neil.fraser.name
Hi Neil,

I've been working with the improved speed version (love it) and noticed there are a few areas where we still hit O^2 time (or at least it seems like it to me). It appears if you render from xml a large program and then open the toolbar and it needs to redraw to make room for the toolbar to display blocks in toolbar. (I might be able to avoid this if I move the initial render away from toolbar area with positions in xml) Also if you collapse all blocks and then expands them back. If possible and you get time can you please look into this.

Many thanks,
Chris

GB-)

unread,
Apr 8, 2017, 8:33:44 AM4/8/17
to Blockly, christoph...@gmail.com, ro...@neil.fraser.name
This is very helpful.

Would you know what machine specification was used for these tests?
Cheers
GB-)

Neil Fraser

unread,
Apr 8, 2017, 9:29:25 AM4/8/17
to blo...@googlegroups.com
On 8 April 2017 at 13:33, GB-) <gbu...@gmail.com> wrote:
> This is very helpful.
>
> Would you know what machine specification was used for these tests?

According to my records:
MacBook Pro 15" Unibody Mid 2010
Released April 2010 / 2.4, 2.53 GHz Core i5 or 2.66, 2.8 GHz Core i7
Processors

GB-)

unread,
Apr 9, 2017, 4:03:23 AM4/9/17
to Blockly, ro...@neil.fraser.name
Thank you again.
Do you run the same tests on each release on the same machine specs and publish the stats?

I hope you're having as lovely weekend.
GB-)

Erik Pasternak

unread,
Apr 10, 2017, 1:40:30 PM4/10/17
to Blockly, ro...@neil.fraser.name
Not currently. Testing is still a manual process for us but we're working on it (slowly).

GB-)

unread,
Apr 10, 2017, 5:56:05 PM4/10/17
to Blockly, ro...@neil.fraser.name
Thank you yet again.
I apologise for asking lots of questions, I am trying to understand how everything works on several fronts.

Cheers
G B-)

Kartheek Gollanapalli

unread,
Aug 3, 2017, 5:17:24 AM8/3/17
to Blockly, christoph...@gmail.com, ro...@neil.fraser.name

Hi Neil, I've tried a lot to reach you through other social media but unfortunately I couldn't find any. I wanted to seek your help on:
1. Making Blockly rendering asynchronous for each block.
2. Know if Blockly supports binary XML instead of XML for performance benefits.

We're facing a critical bug. Felt that you'd be the best man to ask about Blockly. Kindly help. Thanks.

Neil Fraser

unread,
Aug 3, 2017, 5:52:21 AM8/3/17
to blo...@googlegroups.com
On 3 August 2017 at 10:17, Kartheek Gollanapalli <kartheek.g...@flytxt.com> wrote:

Hi Neil, I've tried a lot to reach you through other social media but unfortunately I couldn't find any. I wanted to seek your help on:
1. Making Blockly rendering asynchronous for each block.
2. Know if Blockly supports binary XML instead of XML for performance benefits.

We're facing a critical bug. Felt that you'd be the best man to ask about Blockly. Kindly help. Thanks.

With respect to asynchronously rendering each block, that's rather challenging since a block's shape (think 'if' or 'repeat' or '+') is dictated by size and shape of the blocks it encloses.  Thus a block can't draw itself until its children have done so.  Additionally, the location of each block is dictated by the location, size and shape of the blocks above it in the stack.  Thus a block can't position itself until its parents have done so.  Taken all together, this doesn't seem to lend itself to an asynchronous algorithm.

A binary XML format would certainly reduce the memory costs associated with saved programs.  However, parsing and rendering binary XML is not supported natively by the browser, whereas normal XML is.  Accordingly, if one is looking for processor performance, then it's difficult to beat XML.  Browsers are highly optimized XML parsing machines.

XML is quite verbose, which does imply that network performance would be poorer.  However, that verbosity comes from repeated strings.  Nearly all HTTP sessions are compressed, so in effect one gets binary XML over the wire.

I'm no longer actively working on Blockly, but the team at Google is very focused on performance.  I'm sure they will weigh in once the sun comes up in California.

Kartheek Gollanapalli

unread,
Aug 3, 2017, 10:16:46 AM8/3/17
to Blockly, ro...@neil.fraser.name
Hi Neil,

Thanks a lot for the detailed answer. It certainly cleared many doubts. I've one last question - and before that, please correct if the summary of the below is incorrect:
  • Rendering each block asynchronously doesn't seem to be a good idea in order to reduce total time.
  • XML is better than binary XML when looking at performance and compatibility.

Here's a bit of background of my project before we get to the main issue:
  • Big data analytics product which integrates Blockly to create a job to do some heavy data processing.
  • The current job has over 400 blocks which include 'field extractors', 'if-else blocks', 'variables', 'constants', 'custom blocks' etc.

Issue: After creating, saving and reopening the job, it's taking incredibly long time to load all the Blockly blocks. (50-70 seconds)



In scripting, supposedly, the logic calculation is being done. We're looking for a solution which can bring down the total time. Do you think using a web worker will help as it does scripting in the background?

Or is there any other way to cut down the loading time? We're in a dire need of a quick solution.

I appreciate that you're taking time out for helping. It'd be great if you could also give a few contacts of people currently in Blockly team. 

Thanks a lot, Neil.

Erik Pasternak

unread,
Aug 3, 2017, 11:44:32 AM8/3/17
to Blockly, Neil Fraser
Hi Kartheek,

I'm a current member of the Blockly team. If possible, we prefer to discuss issues on this public list so that other developers can find a solution if they have the same issue. If you can't discuss publicly for business reasons let me know and we'll figure something out.

As for the performance issue you're having, 400 blocks in a workspace is not too many. Blockly shouldn't have any trouble loading and rendering a workspace of that size in a few seconds. If you load up the Playground and click the airstrike button it adds ~600 blocks to the workspace in one giant stack which is the worst case for rendering.

Have you dug into the timing at all to see how much of those scripting and rendering portions are happening in Blockly? Is there something else that's triggering a full rerender on every change? Also, does the time increase linearly with the number of blocks or even faster?

Cheers,
Erik

--
You received this message because you are subscribed to a topic in the Google Groups "Blockly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/blockly/klkra6Z66e4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to blockly+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Erik Pasternak | Master of the House | epas...@google.com     

Erik Pasternak

unread,
Aug 3, 2017, 3:58:18 PM8/3/17
to Blockly
Sorry, spaghetti button, not airstrike.

On Thu, Aug 3, 2017 at 8:44 AM, Erik Pasternak <epas...@google.com> wrote:
Hi Kartheek,

I'm a current member of the Blockly team. If possible, we prefer to discuss issues on this public list so that other developers can find a solution if they have the same issue. If you can't discuss publicly for business reasons let me know and we'll figure something out.

As for the performance issue you're having, 400 blocks in a workspace is not too many. Blockly shouldn't have any trouble loading and rendering a workspace of that size in a few seconds. If you load up the Playground and click the airstrike button it adds ~600 blocks to the workspace in one giant stack which is the worst case for rendering.

Have you dug into the timing at all to see how much of those scripting and rendering portions are happening in Blockly? Is there something else that's triggering a full rerender on every change? Also, does the time increase linearly with the number of blocks or even faster?

Cheers,
Erik

Kartheek Gollanapalli

unread,
Aug 6, 2017, 11:32:02 PM8/6/17
to Blockly, christoph...@gmail.com, ro...@neil.fraser.name, epas...@google.com

Hi Erik,

Thanks a lot for your response. 

Following your suggestions and after debugging, I've found the following:

I've used the Spaghetti button and realized that there're as many as 3000 blocks and are loading in 3-4 seconds. In our current job, we've upto 810 blocks but still it's taking on an average of 50 seconds. So, it's highly likely that something else in our code could be the reason for the poor performance.

Also, we've created jobs with <50, <100, <200 blocks and - yes, the time does linearly increase with the number of blocks. The higher the number of blocks, the longer it's taking to display them.

I've done profiling for the whole job and am attaching screenshots for your reference.

                                                                                                                                     1. Picture #1


2. Picture #2



3. Picture #3






I've found that Blockly.Xml.domTOWorkspace() method in Blockly_init_function() is taking almost 35 seconds (70% of total time). 

Also, in response to your question on whether something is triggering a full renderer on every change, I've seen that Blocly.Xml.domTOBlockHeadless_  (in picture #2) is being called repeatedly, multiple times. Could it possibly  be the one triggering the full renderer?

Could you please suggest how to discern how much of the loading and rendering time is taken by Blockly, and how much by our code?


Kindly help.

Kartheek Gollanapalli

Erik Pasternak

unread,
Aug 7, 2017, 12:40:43 PM8/7/17
to Kartheek Gollanapalli, Blockly, christoph...@gmail.com, Neil Fraser
Interesting, from the timing it looks like you have 800 nested blocks? (Child blocks that keep extending to the right).

I was expecting to see domToWorkspace called multiple times like this:

But since it's one big call that means there's only one block at the top that all the blocks are nested under, more like this:


However, even nested it shouldn't be taking that long​ and I'm not able to reproduce an increase in delay as I nest blocks (I nested up to ~80 deep without any slowdown). This probably means there's something in your specific blocks that's taking longer than expected during the creation of each block. Try zooming in at the very bottom of your stack to see if it's taking more than ~1ms/block at the lowest level. You might have an extension or some custom code that runs on each block as it's created that's slowing things down.

Here's what the last few blocks should look like, with the last calls to domToBlockHeadless_ taking ~0.8ms and the calls above them taking a bit less than 1ms per block total.


Kartheek Gollanapalli

unread,
Aug 8, 2017, 9:21:10 AM8/8/17
to Blockly, christoph...@gmail.com, ro...@neil.fraser.name, epas...@google.com
Hi Erik,

I've zoomed to the bottom of the stack and this is what I've found:

1. Bottom most node timing (~0.15 ms)



The bottom most node i.e., getAttribute took (0.15ms), and the last Blockly.Xml.domToBlockHeadless_ block took (71ms). /* the one before BlockSvg.initSvg */


2. Recalculate Style 

Also, in the above image, there's a warning about 'Recalculate Style' that it could possibly be a performance bottleneck.
And 'Recalculate Style' is called several hundreds of times - from the top of the tree till the very bottom, as shown below:

 


 (and so on till the end..)



I see that this performance bottleneck exists in the profiling of Spaghetti in playground too. Do you think this attributes to the majority of time taken in 'Rendering' section? If yes, how do we optimize it?

Kindly suggest how to proceed from here.


Thanks. 


On Saturday, January 24, 2015 at 1:26:31 PM UTC+5:30, Neil Fraser wrote:

Erik Pasternak

unread,
Aug 8, 2017, 1:11:17 PM8/8/17
to Kartheek Gollanapalli, Blockly, Chris Casilli, Neil Fraser
That trace at the bottom is definitely unusual. A couple months ago we did some optimizations during loading so that things like recalculateStyle and getScreenCTM wouldn't be called until after everything was loaded. If you compare your trace to what you get in the playground you can see many of those calls don't happen.

Some things to try:
  • If your copy of Blockly is out of date try updating. We may have fixed some of these performance problems since your last update.
  • If that doesn't help, you may have added something to your blocks that's triggering recalculateStyle. You can try stepping through loading a workspace with just a few blocks to see when those calls are made and hopefully identify the code responsible.
Cheers,
Erik
Reply all
Reply to author
Forward
0 new messages