Request: Application Performance Analyzer

1 Answer 218 Views
GridView
Martin
Top achievements
Rank 2
Iron
Iron
Iron
Martin asked on 09 Sep 2021, 07:24 AM | edited on 09 Sep 2021, 07:44 AM

I'm using a RadGrid / GridView and the performance is horrible. 

I'm not doing anything fancy. I have 15 columns and about 2000 rows 

In HTML, this is piece of cake, blazing fast and 200hz when scrolling. 

in WPF this just sucks at 5 fps and a very laggy experience.

I'm reading through the optimization docs and there are somewhat 50+ nobs to turn in the hope that it makes a difference. 

 

My humble request is therefore : Some Telerik Application Analyzer that scans through the program and finds all the problematic settings or constructions that hurt performance. 

I guess it should be pretty simple to look at container element properties and instance properties of the RadGrid and tell the user which ones are hurting the performance or disabling scroll virtualization... coz i have no idea. 

PS. One of the performance tips are completely impossible to correct: 

  • Placing RadGridView in panels/controls which measure it with infinity disables the UI virtualization mechanism of the control and can greatly impact performance when dealing with large amounts of data. Examples of such panels include ScrollViewerStackPanel and Grid with a definition with Width/Height set to Auto.

MANY UI-elements use Grid in their internal workings: 

MainWindow - uses a Grid with height/width = auto
AdornerDecorator - uses a Grid with height/width = auto
Rootgrid - uses a Grid with height/width = auto
TabControl - uses a Grid with height/width = auto
TabItem - uses a Grid with height/width = auto
Border (Contentpresenter) - uses a Grid with height/width = auto
RadBusyIndicator - uses a Grid with height/width = auto

So how the heck am i supposed to correct all those problems without completely going insane and create a stinking pile of code ? 

1 Answer, 1 is accepted

Sort by
0
Dinko | Tech Support Engineer
Telerik team
answered on 14 Sep 2021, 06:51 AM

Hi Martin,

Thank you for the provided details.

I am sorry to hear that you are experiencing performance degradation while using our RadGridView control for WPF. As mentioned in the Tips and Tricks article, one of the main cases which could disable the UI Virtualization in the control is when it is placed inside a panel that measures its children with infinity. This way the control can't calculate the viewport area height/width which will lead to rendering all rows in the RadGridView. You can easily spot this behavior when you load the application and don't see scrollbars in the control. But don't worry I will do my best to suggest a way to workaround this.

To avoid any misunderstanding in the implementation on your side, may I ask you to share the whole XAML code where the RadGridView is placed. This way I can try to recreate your structure on my side and suggest a proper way to speed up the control.

Again, accept our apologies for any inconvenience it might have caused you and I am looking forward to your reply so I can further assist you. 

Regards,
Dinko
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Martin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 14 Sep 2021, 08:49 AM | edited

Ahh.. 

So your tips and tricks regarding container is only the parent of the RadGrid. 
I tried using a fixed size container but the performance is still pretty bad (comparable to not having it) 

btw: Wouldn't it be rather simple to calculate the rendered size and then specify the size inside the component ? 


<UserControl x:Class="Modelkatalog.Client.Controls.CarBrowser"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:catalog="clr-namespace:Modelkatalog.Client.CatalogService"
             xmlns:converters="clr-namespace:Modelkatalog.Client.Converters"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:Modelkatalog.Client.Controls"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             x:Name="root"
             d:DataContext="{d:DesignInstance Type=local:CarBrowser}"
             d:DesignHeight="1000"
             d:DesignWidth="1860"
             mc:Ignorable="d">

    <UserControl.Resources>
        <converters:NullableIntConverter x:Key="NullInt" />
    </UserControl.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="525" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <local:CarVariantControl SelectedVariant="{Binding SelectedVariant}" />

        <StackPanel Grid.Row="1"
                    Height="35"
                    VerticalAlignment="Top"
                    Background="{DynamicResource MahApps.Brushes.Accent}"
                    Orientation="Horizontal">

            <Label Width="90" Margin="10,0,0,0" VerticalAlignment="Center" Foreground="{DynamicResource MahApps.Brushes.ThemeBackground}">Smart søgning</Label>

            <TextBox Width="500" Margin="10,5,0,5" Text="{Binding ElementName=root, Path=Query, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

            <Label Margin="10,0,0,0" VerticalAlignment="Center" Foreground="{DynamicResource MahApps.Brushes.ThemeBackground}">Ã…rgang:</Label>

            <TextBox Width="50" Margin="10,5,0,5" Text="{Binding ElementName=root, Path=VintageYear, Converter={StaticResource NullInt}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

            <!--<CheckBox Height="28" Margin="10,0,0,0" IsChecked="{Binding ElementName=root, Path=ShowDeactivated}">
                <TextBlock Foreground="{DynamicResource MahApps.Brushes.ThemeBackground}">Vis Deaktiverede</TextBlock>
            </CheckBox>-->

            <Button Height="25" Margin="10,0,0,0" Click="ClearFilters_Click" Content="Ryd filtre" />

            <Button Height="25"
                    Margin="10,0,0,0"
                    Click="RefreshList_Click"
                    Content="Genopfrisk Liste"
                    IsEnabled="{Binding CanChangeVariant}" />

            <Button Height="25" Margin="10,0,0,0" Click="Jotform_Click" Content="JotForm" />

        </StackPanel>

        <telerik:RadBusyIndicator Grid.Row="1"
                                  Margin="0,35,0,0"
                                  BusyContent="Henter GUI TabelData"
                                  DataContext="{Binding ElementName=root}"
                                  IsBusy="{Binding IsLoading}"
                                  IsIndeterminate="True">

            <telerik:RadGridView x:Name="radgrid"
                                 d:DataContext="{d:DesignInstance Type=catalog:GuiModel}"
                                 AutoGenerateColumns="False"
                                 Background="{DynamicResource MahApps.Brushes.ThemeBackground}"
                                 CanUserFreezeColumns="False"
                                 CanUserSearch="True"
                                 CanUserSearchInHiddenColumns="False"
                                 ColumnWidth="*"
                                 GroupRenderMode="Flat"
                                 IsFilteringAllowed="True"
                                 IsReadOnly="True"
                                 IsSearchingDeferred="False"
                                 ItemsSource="{Binding ElementName=root, Path=CombinedCarModels}"
                                 Loaded="GridView_Loaded"
                                 MouseDoubleClick="radgrid_MouseDoubleClick"
                                 RowIndicatorVisibility="Collapsed"
                                 SearchMode="MatchAllTerms"
                                 SelectedItem="{Binding ElementName=root, Path=SelectedGuiModel}"
                                 SelectionMode="Single">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ModelVariantId}" Header="VariantID" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding FabrikatNavn}" Header="Fabrikat" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ModelNavn}" Header="Model" />
                    <telerik:GridViewDataColumn Width="300" DataMemberBinding="{Binding Variantbetegnelse}" Header="Variantnavn" />

                    <telerik:GridViewDataColumn DataMemberBinding="{Binding YearRange}" Header="Ã…rgang">
                        <telerik:GridViewDataColumn.FilteringControl>
                            <local:CustomGridFilter Aargang="{Binding ElementName=root, Path=VintageYear, Mode=TwoWay}" />
                        </telerik:GridViewDataColumn.FilteringControl>
                    </telerik:GridViewDataColumn>

                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ModelserieNavn}" Header="Serienavn" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding KarosseritypeNavn}" Header="Karosseri" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding DoereAntal}" Header="Antal Døre" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding DrivmiddeltypeNavn}" Header="Drivmiddel" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding HybridTypeNavn}" Header="HybridType" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding TransmissiontypeNavn}" Header="Transmission" />

                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Modelseriegenerationsnummer}" Header="Generation" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Modelseriefaceliftnummer}" Header="Facelift" />

                    <telerik:GridViewDataColumn DataMemberBinding="{Binding TransmissionVersionId}" Header="TransmissionVersionId" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ModelVersionId}" Header="ModelVersionId" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding MotorID}" Header="MotorID" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding MotorVersionId}" Header="MotorVersionId" />

                    <telerik:GridViewDataColumn DataMemberBinding="{Binding DatoOprettet}" Header="DatoOprettet" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding DatoDeaktiveret}" Header="DatoDeaktiveret" />

                </telerik:RadGridView.Columns>
            </telerik:RadGridView>
        </telerik:RadBusyIndicator>
    </Grid>

</UserControl>

There are up to 113.000 rows in the grid. Typically its only showing 100s up to few thousands

ModelVariantId : int32?
FabrikatNavn: string
ModelNavn: string
Variantbetegnelse: string
YearRange: Custom control (ill post it)
ModelserieNavn: string
KarosseritypeNavn: string
DoereAntal: int32?
DrivmiddeltypeNavn: string
HybridTypeNavn: string
TransmissiontypeNavn: string
Modelseriegenerationsnummer: byte?
Modelseriefaceliftnummer: byte?
TransmissionVersionId: int32
ModelVersionId: int32
MotorID: int32
MotorVersionId: int32
DatoOprettet: datetime
DatoDeaktiveret: datetime?

Martin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 14 Sep 2021, 12:54 PM

Just want to say that the scrollbar is visible at all times - regardless of the container dimmensions. 
Dinko | Tech Support Engineer
Telerik team
commented on 16 Sep 2021, 09:47 AM

Thank you for the provided details. If the vertical scrollbar is visible, the virtualization is working. To test your scenario I have created a sample project using the provided code snippet. When I run the project, the controls are loaded fast. Can you check it out and let me know how it goes on your side? You could modify the project and include any missing code from your application (custom filtering control, for example). Can you also confirm that you are experiencing performance degradation when loading the control or in some other state?

Martin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 16 Sep 2021, 10:56 AM

Hi 

Thanks for making this small sample to test the performance. 

The Control and App loads very fast !

But scroll-performance is similar to what I'm experiencing in my other apps. 

I just assumes that it would scroll somewhat similar to a Web-browser with tons and tons of HTML (or a huuuuge table) 

I know how scrollviewer virtualization works and know that the view needs to instantiate whatever is visible at the current scroll-height...

So i guess my question is: can it perform better ?

Dinko | Tech Support Engineer
Telerik team
commented on 17 Sep 2021, 11:53 AM

Looking at the RadGridView set-up the ColumndWidth property is set to star. Can you share is there a particular reason for that?  In this case, all columns will be shrunk to fit inside the ViewPort. If not, you can remove it. This way you can reduce the cells inside the viewport and the vertical scroll will be smoother. Could this approach work for you?
Martin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 17 Sep 2021, 12:36 PM

Hi Dinko

I just tried removing it but didn't experience any significant gain in scrolling performance.

I'll try setting a fixed Width on all columns and see if it makes a difference. 

Martin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 17 Sep 2021, 12:48 PM

I changed all the column widths in such a way that no data is overlapping. 

Scrolling (using the mouse and dragging the scollbar) still feels a bit heavy..

Reducing the amount of columns seems to make the biggest impact. 

eg: only having the first 4 columns massivly improves the experience.

for each column added, the experience gets worse..

Dinko | Tech Support Engineer
Telerik team
commented on 20 Sep 2021, 08:55 AM

I think I am missing something from your scenario. Can you double-check if there are binding errors inside the Output tab of VS? If there are, they could reduce the performance. Also, will it be possible to check the attached project which I use for testing purposes to mimic your implementation?
Martin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 24 Sep 2021, 08:43 AM

Hi 

I tried the V2 sample and scrolling is very comparable to my application. I think it's just a matter of virtualization being a bit heavy when you have several columns. 

Dinko | Tech Support Engineer
Telerik team
commented on 28 Sep 2021, 10:24 AM

What you can try to speed up the scrolling is to use Lightweight Templates and also set the IsPropertyChangedAggregationEnabled property to False. Give the attached project a second chance and share your test results. After using these modifications the scroll performance is optimized. Keep in mind that lightweight templates can only be applied with NoXaml binaries. The attached project uses NoXAML binaries with the Office_Black theme applied (default theme).
Tags
GridView
Asked by
Martin
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Dinko | Tech Support Engineer
Telerik team
Share this question
or