UI freezes for sometime after UI binding

Shashank Gaddam [C] 20 Reputation points
2025-06-15T17:09:15.28+00:00

My data is binding to UI quickly but the UI freezes for few seconds and I have only 2 records.

I am loading data in ContentView Loaded event

var newStops = await Task.Run(() =>
{
    return response.Stops
        .OrderByDescending(x => x.stopNumber)
        .Select(item => new StopListUIModel
        {
            StopId = item.stopId,
            Name = item.consigneeName,
            Email = item.consigneeEmail,
            ClientCode = item.clientCode,
            ServiceType = item.serviceType,
            StopNumber = item.stopNumber,
            TimeWindow = $"{FormatTime(item.windowStartTime)} - {FormatTime(item.windowEndTime)}",
            ActualTime = $"{FormatTime(item.actualStartTime)} - {FormatTime(item.actualEndTime)}",
            RouteStatus = item.status,
            IsSynced = false,
            ImageUrls = item.pictures.Select(e => e.url).ToList(),
            HasImages = item.pictures.Any(),
            Location = string.Join(", ", new[]
            {
        item.consigneeAddressLine1,
        item.consigneeCity,
        item.consigneeState,
        item.consigneeCountry,
        item.consigneeZip
            }.Where(s => !string.IsNullOrEmpty(s))),
            RouteStatusBackgroundColor = GetColor(item.status)
        })
        .ToList();
});
// ✅ Add all items at once on the UI thread
MainThread.BeginInvokeOnMainThread(() =>
{
    Model.StopsList = new ObservableCollection<StopListUIModel>(newStops);
    Model.IsSortVisible = newStops.Count > 0;
});
 <CollectionView
     x:Name="stopsList"
     Grid.Row="1"
     Margin="8,0,8,0"
     ItemsSource="{Binding Model.StopsList}">
     <CollectionView.ItemsLayout>
         <LinearItemsLayout ItemSpacing="8" Orientation="Vertical" />
     </CollectionView.ItemsLayout>
     <CollectionView.EmptyView>
         <Border
             BackgroundColor="White"
             IsVisible="{Binding Source={x:Static App.DynamicTabbedPageViewModel}, Path=IsDyamicPageBusy, Converter={StaticResource InvertedBoolConverter}}"
             StrokeShape="RoundRectangle 8"
             StrokeThickness="0"
             VerticalOptions="FillAndExpand">
             <Label
                 Margin="20"
                 FontFamily="RobotoRegular"
                 HorizontalTextAlignment="Center"
                 Text="{x:Static res:ResourcesFile.StopListInformationMsg}"
                 TextColor="Black"
                 VerticalOptions="CenterAndExpand" />
         </Border>
     </CollectionView.EmptyView>
     <CollectionView.ItemTemplate>
         <DataTemplate>
             <Border
                 x:Name="mainBorder"
                 Grid.Row="1"
                 Margin="{OnPlatform iOS='9,5,9,5',
                                     Android='0,0,0,0'}"
                 BackgroundColor="White"
                 StrokeShape="RoundRectangle 8"
                 StrokeThickness="0"
                 VerticalOptions="StartAndExpand">
                 <StackLayout>
                     <Grid
                         Margin="12"
                         ColumnDefinitions="0.15*,0.75*,0.1*"
                         ColumnSpacing="10"
                         HorizontalOptions="FillAndExpand"
                         RowDefinitions="*,*">
                         <Border
                             Grid.Row="0"
                             Grid.RowSpan="2"
                             Grid.Column="0"
                             Margin="0,0,0,8"
                             BackgroundColor="Black"
                             HeightRequest="50"
                             StrokeShape="RoundRectangle 30"
                             StrokeThickness="0"
                             WidthRequest="50">
                             <Label
                                 FontSize="Medium"
                                 HorizontalOptions="Center"
                                 Text="{Binding StopNumber}"
                                 TextColor="White"
                                 VerticalOptions="Center" />
                         </Border>
                         <Grid
                             Grid.Row="0"
                             Grid.RowSpan="2"
                             Grid.Column="1"
                             ColumnDefinitions="Auto,*"
                             ColumnSpacing="7"
                             RowDefinitions="*, *"
                             VerticalOptions="FillAndExpand">
                             <Image
                                 Grid.Column="0"
                                 Margin="0,3,0,0"
                                 Source="driverusericon.png"
                                 VerticalOptions="StartAndExpand" />
                             <Label
                                 Grid.Column="1"
                                 FontFamily="RobotoRegular"
                                 FontSize="14"
                                 Text="{Binding Name}"
                                 TextColor="Black"
                                 VerticalOptions="StartAndExpand"
                                 VerticalTextAlignment="Center" />
                             <Image
                                 Grid.Row="1"
                                 Grid.Column="0"
                                 Margin="0,0,0,0"
                                 Source="stoplisticon.png"
                                 VerticalOptions="StartAndExpand" />
                             <Label
                                 Grid.Row="1"
                                 Grid.Column="1"
                                 FontFamily="RobotoRegular"
                                 FontSize="14"
                                 Text="{Binding Location}"
                                 TextColor="Black"
                                 VerticalOptions="StartAndExpand"
                                 VerticalTextAlignment="Center" />
                         </Grid>
                         <Image
                             Grid.Column="3"
                             Margin="0,0,5,0"
                             HeightRequest="25"
                             HorizontalOptions="End"
                             IsVisible="False"
                             Source="synced.png">
                             <Image.Triggers>
                                 <DataTrigger
                                     Binding="{Binding IsSynced}"
                                     TargetType="Image"
                                     Value="False">
                                     <Setter Property="Source" Value="pending.png" />
                                 </DataTrigger>
                             </Image.Triggers>
                         </Image>
                     </Grid>
                     <Grid
                         Margin="8,2,0,12"
                         ColumnDefinitions="0.6*,0.4*"
                         RowDefinitions="*,*"
                         RowSpacing="10">
                         <StackLayout HorizontalOptions="StartAndExpand" Spacing="5">
                             <Label FontSize="12">
                                 <Label.FormattedText>
                                     <FormattedString>
                                         <FormattedString.Spans>
                                             <Span
                                                 FontFamily="RobotoMedium"
                                                 Text="{x:Static res:Resources.TimeWindowText}"
                                                 TextColor="#667085" />
                                             <Span
                                                 FontFamily="RobotoMedium"
                                                 Text="  "
                                                 TextColor="#667085" />
                                             <Span
                                                 FontFamily="RobotoMedium"
                                                 Text="{Binding TimeWindow}"
                                                 TextColor="#000000" />
                                         </FormattedString.Spans>
                                     </FormattedString>
                                 </Label.FormattedText>
                             </Label>
                             <Label
                                 Margin="0,0,8,0"
                                 FontSize="12"
                                 HorizontalOptions="StartAndExpand">
                                 <Label.FormattedText>
                                     <FormattedString>
                                         <FormattedString.Spans>
                                             <Span
                                                 FontFamily="RobotoMedium"
                                                 Text="{x:Static res:Resources.ActualTimeText}"
                                                 TextColor="#667085" />
                                             <Span
                                                 FontFamily="RobotoMedium"
                                                 Text="  "
                                                 TextColor="#667085" />
                                             <Span
                                                 FontFamily="RobotoMedium"
                                                 Text="{Binding ActualTime}"
                                                 TextColor="#000000" />
                                         </FormattedString.Spans>
                                     </FormattedString>
                                 </Label.FormattedText>
                             </Label>
                         </StackLayout>
                         <StackLayout
                             Grid.Column="1"
                             HorizontalOptions="FillAndExpand"
                             Spacing="5">
                             <Border
                                 HorizontalOptions="EndAndExpand"
                                 IsVisible="{Binding HasImages}"
                                 Stroke="#FFC1CA"
                                 StrokeThickness="1.5">
                                 <StackLayout
                                     Margin="12,2,12,2"
                                     Orientation="Horizontal"
                                     Spacing="8">
                                     <Image HeightRequest="15" Source="imageicon.png" />
                                     <Label
                                         FontFamily="RobotoMedium"
                                         FontSize="13"
                                         Text="{x:Static res:Resources.ViewText}"
                                         TextColor="#E41937" />
                                 </StackLayout>
                                 <Border.GestureRecognizers>
                                     <TapGestureRecognizer
                                         BindingContext="{Binding Source={x:Reference stopsList}, Path=BindingContext}"
                                         Command="{Binding ViewCommand}"
                                         CommandParameter="{Binding Source={x:Reference mainBorder}, Path=BindingContext}" />
                                 </Border.GestureRecognizers>
                             </Border>
                             <Border
                                 BackgroundColor="{Binding RouteStatusBackgroundColor}"
                                 HorizontalOptions="End"
                                 StrokeShape="RoundRectangle 15,0,15,0"
                                 StrokeThickness="0">
                                 <Label
                                     Margin="18,2,9,3"
                                     FontFamily="RobotoMedium"
                                     HorizontalOptions="Start"
                                     Text="{Binding RouteStatus}"
                                     TextColor="White"
                                     VerticalOptions="Center" />
                             </Border>
                         </StackLayout>
                     </Grid>
                 </StackLayout>
                 <Border.GestureRecognizers>
                     <TapGestureRecognizer Command="{Binding Source={x:Reference stopsList}, Path=BindingContext.StopClickedCommand}" CommandParameter="{Binding .}" />
                 </Border.GestureRecognizers>
             </Border>
         </DataTemplate>
     </CollectionView.ItemTemplate>
 </CollectionView>
Developer technologies | .NET | .NET MAUI
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Doaa Ali Hamdan AL-Jarwani 340 Reputation points
    2025-06-15T19:48:53.3566667+00:00

    Your UI is freezing because you’re assigning a large ObservableCollection all at once, even with just 2 records — the CollectionView layout and bindings can be layout-heavy and cause a visible delay.

    Fix in 2 Steps (Very Efficient):

    1. Clear and Add Items One by One Instead of Replacing the Whole Collection:

    MainThread.BeginInvokeOnMainThread(() =>

    {

        Model.StopsList.Clear();

        foreach (var item in newStops)

            Model.StopsList.Add(item);

        Model.IsSortVisible = Model.StopsList.Count > 0;

    });

    This reduces layout recalculation and avoids freezing the UI.

    2. Delay UI Update Slightly (Optional Improvement):

    If still laggy, add a slight delay before UI binding:

    await Task.Delay(100); // Small delay before touching UI

    MainThread.BeginInvokeOnMainThread(() => {

        // add items...

    });

    Why This Works:

    • Creating a new ObservableCollection triggers a full re-render of the CollectionView.

    • Using .Clear() and .Add() avoids XAML overhead caused by re-applying the entire DataTemplate.


  2. Shashank Gaddam [C] 20 Reputation points
    2025-06-16T05:35:47.4466667+00:00

    I found the issue, there is some other UI thread is running in the background

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.