umbraco / Umbraco-CMS

Umbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.
https://umbraco.com
Other
4.49k stars 2.69k forks source link

Nest content poor performance #5530

Closed brendan-rice closed 3 years ago

brendan-rice commented 5 years ago

I have a nest content data type with over 20 associated document types. The idea is to use the nested content as a page builder.

When I add the nested content data type to a page document type, the performance is very slow when I try to add a new item.

On load of the page Chrome's network tab shows:

If I don't wait for the full 20 seconds and click on the icon to add content to the nested content data type, it only partially gets loaded and errors appear in the console.

Reproduction

Bug summary

The issue seems to stem from the number of calls to the following URL (contentTypeAlias change on each call):

http://localhost:56167/umbraco/backoffice/UmbracoApi/Content/GetEmpty?contentTypeAlias=teasersBasic&parentId=-20

This call is made 22 times, once for each associated document type in the nested content data type. Each call take typically .5 seconds, so adds up to around 50% of the total load time for the page.

Below are all the JavaScript references to GetEmpty in the codebase:

https://github.com/umbraco/Umbraco-CMS/search?l=JavaScript&q=GetEmpty

Specifics

Steps to reproduce

  1. Create 22 document types to use in a nested content data type
  2. Create a nested content data type and add the 22 document types to it
  3. Create a document type for a page and allow it at the root. Add the nested content data type to the page document type
  4. Add a new content item and add the page document type
  5. Reload the page wait until the + button shows to add content to the nested content. The modal may not appear on first click, keep clicking until it appears

Expected result

The nested content should load 22 doc types

Actual result

Only some of the doc types will be loaded

Potential fix

As the issue seems to stem from the number of requests made to load the data types, how can the number of requests be reduced to 1 per nested content data type?

Content PageBuilder

kjac commented 5 years ago

Hi @brendan-rice,

I actually tried making NC fetch all scaffolds (the calls to GetEmpty) in one go. It didn't help load time; if anything it made things worse, strangely enough. There must be some parallel fetching going on.

That being said... the site I'm currently working on has 14 (and counting) doctypes in NC, and it's by no means horribly slow. I mean you can see that it's loading, but it's at most two seconds.

I did submit a PR to put NC in loading state while it's initializing: #5446 - that should solve your immediate problems with console errors and whatnot.

Lastly: The 124 requests aren't all NC 😄 there's a ton of things going on in the backoffice that requires data from the server. Plus it seems you have cache disabled in your Chrome devtools, which probably is the reason for the huge download size (and likely also a large portions of the requests).

brendan-rice commented 5 years ago

Hi @kjac,

thanks for the quick reply. I understand that the 124 requests aren't all NC, there is 22 requests that I can see that are directly related to NC and are taking up half the load time.

Even when I enable caching I get the same issue.

The loading state is a good idea and would at least let the user know what is going on but it doesn't address the issue of slow load time.

How could we speed it up?

Thanks,

Brendan

nul800sebastiaan commented 5 years ago

Thanks @brendan-rice - I've lined #5446 as a fix for the console error at least.

We'd appreciate any help in getting the performance up for very large nested content items, apparently bundling the calls didn't help according to @kjac so we'd be happy for other ideas and a pull request for the implementation of those ideas.

kjac commented 5 years ago

I think we need to take a deep dive into how the scaffolds are created on the server.

@brendan-rice do you have any latency issues, e.g. distance between the web server and the database? Is the backoffice generally feeling sluggish or is it only when using NC?

brendan-rice commented 5 years ago

@kjac no latency issues. It is on a development environment, with a high spec machine so the problem would be worse when the solution get deployed to a server.

The same issue seems to happen on the Settings > Doc Type > Composition button. I can see the 22 calls in the Chrome network tab. The requests all fire but they take around 8 seconds to complete, during that 8 seconds if I hit the Composition button either nothing happens or the compositions partially list the Doc Types.

brendan-rice commented 5 years ago

@nul800sebastiaan thanks for looking into this and putting the fix in. Sorry I can't help with the pull request, unfortunately I'm under pressure with projects and won't be freed up for a while. I'd really like to get involved more when things calm down.

@kjac it's interesting that reducing the requests had a negative impact on performance, have you got any more details on what you tried. Maybe if I had a better understanding of what you tried it might trigger a few ideas?

brendan-rice commented 5 years ago

@kjac @nul800sebastiaan I've been mulling this one over and have an idea, but no idea how to implement it.

How about on save of the doc types we cache a json file. Then we just reference/parse that 1 json file rather than making multiple requests?

The only issue that we may hit with this approach is that we'd need to allow .json as a mime type in the web.config.

How does that sound?

kjac commented 5 years ago

@brendan-rice creative thinking is always much obliged.

There are plenty existing cache methods in the core. If this is indeed an issue that can be solved by means of caching, adding a new cache layer isn't the solution 😄

brendan-rice commented 5 years ago

@kjac you've got me interested. How can json be cached on the client currently in core?

kjac commented 5 years ago

@brendan-rice oh, you can't at this point. Nor should you, at least not this kind of data. You'd be in a world of cache busting pain.

I'm referring to the serverside. If there is a performance issue when creating scaffolds (e.g. if the database is hit several times during creation), there are plenty of caching mechanisms in the codebase to make it more performant.

@nul800sebastiaan perhaps some of the clever core people could have a glance at this, maybe attach a profiler to see what's going on? Might be interesting to create a "light" scaffold for element types (i.e. don't care about permissions, allowed children etc).

lee-mccroskey commented 5 years ago

@brendan-rice Are you running into excessive time waiting for your content to save too? Our setup has ~19 nested items in 1 data type. We have created a test content page to that had ~14 different components on it. When we attempt to Save and Publish, the call to PostSave take from 35-40 seconds on every attempt.

brendan-rice commented 5 years ago

@lee-mccroskey I haven't really tried saving the content. 35-40 seconds is a long time.

I'm having second thoughts about Nested Content as the poor performance means a really bad editor experience.

I'm waiting for the V8 doctype grid editor to be released before I pick up on trying to build a pagebuilder type component. Either that or I'm going to switch back to v7.

You can follow the progress of the v8 doctype grid editor here:

https://github.com/umco/umbraco-doc-type-grid-editor/pull/137

umbrabot commented 3 years ago

Hiya @brendan-rice,

Just wanted to let you know that we noticed that this issue got a bit stale and might not be relevant any more.

We will close this issue for now but we're happy to open it up again if you think it's still relevant (for example: it's a feature request that's not yet implemented, or it's a bug that's not yet been fixed).

To open it this issue up again, you can write @umbrabot still relevant in a new comment as the first line. It would be super helpful for us if on the next line you could let us know why you think it's still relevant.

For example:

@umbrabot still relevant This bug can still be reproduced in version x.y.z

This will reopen the issue in the next few hours.

Thanks, from your friendly Umbraco GitHub bot :robot: :slightly_smiling_face: