Developer forum

Forum » Swift » Optimizing Page Speed and Component Usage

Optimizing Page Speed and Component Usage

Nicolai Jessen
Nicolai Jessen
Reply

Hello,

 

I'd like to share some insights and concerns regarding the use of Swift, specifically focusing on its "components" feature. In my recent testing, I noticed a correlation between the number of different components used and the page speed, especially when dealing with the product list page (PLP) containing a substantial number of items.

 

I conducted tests on a fresh Swift implementation (1.21.0) where I observed the PLP loading 48 products in under 1 second when displaying only product image and title per card. However, as I added more components like descriptions, "add to cart" functionality, and others, the loading time increased significantly, reaching up to 2 seconds and sometimes beyond. This trend became more pronounced as the number of components approached that of a real-world example for one of our clients where the list takes around 4-6+ seconds to load.

 

From my findings, it's apparent that Swift's performance can be affected by the number of components being loaded.
Furthermore, we've noticed that a component without a dummy product, might have an impact on the load time, as we noticed a significant drop in load time after filling out the dummy product field with a product resulting in the PLP loading twice as fast. It seems as it would load all products from the index without a dummy product.

 

For now, one potential solution to improve initial load times could be consolidating various components into a single component, reducing the number of template requests.
I used ?debug=true throughout the testing to see if it was held back by database requests but it does not seem to be the case for our client.

 

I hope these insights are helpful :-) 
I'm curious to know if Dynamicweb has any specific performance recommendations for Swift regarding how many components should be used, the number of products to display on the first load, and the test setups for evaluating Swift's speed on product list pages etc.

 

Best regards,

Nicolai Jessen


Replies

 
Adrian Ursu Dynamicweb Employee
Adrian Ursu
Reply

Hi Nicolai,

I can confirm that we have noticed the same thing.

We have not dug deep into the reasons, we have just consolidated the various elements into a single one.

I am also interested to find out DW's recommendations on this matter.

Thank you for investigating!

Adrian

 
Karsten Thuen Dynamicweb Employee
Karsten Thuen
Reply

Hi Nicolai and Adrian
 

We are aware of possible performance issues around the component setup. In the spring we did major performance update, regarding the setup. And it is acrually in the 1.21.0 release. 

Nicolai, initially I would have said that the dummy-product issue sounds a lot like the issue we had on the prior releases. But now I have tested it, and you are correct there is an issue here, eventhough I can not see the sense in this, in the code. Here are the results:
 

  • Productlist with 100 products, and a dummy product ~0.75 seconds 
  • Productlist with 100 products, and no dummy product ~0.9 seconds 
  • PDP with 1 component and a dummy product ~0.1 seconds 
  • PDP with 1 component and no dummy product ~0.1 seconds 
  • PDP with 8 components + components inside other components and a dummy product ~0.15 seconds 
  • PDP with 8 components + components inside other components and no dummy product ~0.15 seconds 
     

I could not recreate the PDP issues you are describing, though. But I can also see that there have been made small performance optimizations since Swift 1.21.0 - All my tests was done on DW10, which may also cause improvements.

 

In the current release there are issues that we can investigate:

  • Not having a dummy product causes performance issues - I have created bug #15987 for this 
  • The components uses settings from the page where they are built - This requires, possible, expensive calls and setups
    • There is a potential for performance issues as we are dependent of i.e. Content.Services.Pages.GetPage and Frontend.ContentViewModelFactory.CreatePageInfoViewModel
    • It is possible to set theme and padding (Comes from the page today) at i.e. the repeater instead of the component page
    • We just need to investigate how to make the change without breaking old setups
  • @RenderGrid and @RenderPartial are both ending in Template.Output(), maybe we can investigate if there are performance intensive leftovers, that is not needed in a ViewModel setup

 

I hope this gets us a little further, regarding the issues. Nicolai, I am, of course, still curious about your test with larger components setups. Maybe you can give it another try in latest Swift + DW10 - Relevant for that test would also be; Will the performance be the same if we have the same stuff in 2 components vs i.e. 8 or 10 

Best regards
Karsten Thuen

 
Karsten Thuen Dynamicweb Employee
Karsten Thuen
Reply

Hi again,

I decided to take this a bit further, as there were more ideas on how to further stress test it.

  • Tried to remove all "Dummy product" setups - There was 0 changes in speed in any of the setups from before
  • Tried to remove the GetPage and CreatePageInfoViewModel from the repeater - There was 0 changes in speed in any of the setups from before, even after restarting and emptying all caches

Of course there may be more to it. But these tests did not seem like it. 

Next test I did, was to make an insanly advanced, and ugly, product list card component, with many components inside components, with even more components inside:

image

Then I built the same product grid card, as close as I could, but with no sub components. And tried to make all the same settings on each paragraph.

  • Product list grid component, with many components inside, loading 100 products in ~1.7second
  • Product list grid component, with no components inside, loading 100 products in ~1.1second

Here we actually have a tracable difference. But the page size is also larger due to the added markup of rows inside rows. We went from 1.5mb down to 1.4mb without components inside components. Then i tried to simplify the markup needed for the components, and we got the page size down to 1.4mb for the components inside components, but the execution time was still around 1.7seconds.

Finally I took the test to DW9, wich is quite a lot slower:

  • Product list grid component, with many components inside, loading 100 products in ~2.8second
  • Product list grid component, with no components inside, loading 100 products in ~1.5second

​I think the conclusion we can make for now, is, yes there are difference in the use of many components inside components. It does not seem that changes to the frontend code does the huge difference, i.e. remove the extra page calls. There is a huge difference in running DW9 and DW10 - DW10 is the clear winner :) 

You were asking for recommendations. As it seems we will have to investigate if there can be done any backend improvements for @RenderGrid, I would recommend to make the component setups, mainly for the product lists, with thought behind what you are doing. More complex setups will impact the payload. But if a subcomponent or two is required for an efficient setup and a unique layout, I would not worry too much about it, if it is made for DW10


There are still more to be investigated. But I hope this helps
Karsten Thuen

 
Anders Ebdrup
Anders Ebdrup
Reply

Dear Karsten,

 

Is there any progress on the performance optimization here?

Have you considered implementing cache on the Item instantiation? Please see this example from a component based PLP:

08:36:14.617 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 31)
18 ms
10.405 ms
08:36:14.690 ItemViewModel.CreateInstance End
73 ms
10.478 ms
08:36:14.690 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 48)
0 ms
10.478 ms
08:36:14.714 ItemViewModel.CreateInstance End
24 ms
10.502 ms
08:36:14.714 ItemViewModel.CreateInstance Start (Swift_4ColumnsComponentEdit, 1)
0 ms
10.502 ms
08:36:14.722 ItemViewModel.CreateInstance End
8 ms
10.510 ms
08:36:14.722 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 72)
0 ms
10.510 ms
08:36:14.729 ItemViewModel.CreateInstance End
7 ms
10.517 ms
08:36:14.729 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 24)
0 ms
10.517 ms
08:36:14.736 ItemViewModel.CreateInstance End
7 ms
10.524 ms
08:36:14.736 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 51)
0 ms
10.524 ms
08:36:14.744 ItemViewModel.CreateInstance End
8 ms
10.532 ms
08:36:14.744 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 74)
0 ms
10.532 ms
08:36:14.750 ItemViewModel.CreateInstance End
6 ms
10.538 ms
08:36:14.750 ItemViewModel.CreateInstance Start (Swift_1ColumnComponentEdit, 102)
0 ms
10.538 ms
08:36:14.757 ItemViewModel.CreateInstance End
7 ms
10.545 ms

Best regards, Anders

 

You must be logged in to post in the forum