The solution is to add a RadGrid_PreRender event (it fires after NeedDataSource) to loop through the grid and collapse.
Protected Sub RadGrid1_PreRender(sender As Object, e As EventArgs) Handles RadGrid1.PreRender
If Not Page.IsPostBack Then
For Each item As GridGroupHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)
item.Expanded = False
Next
End If
End Sub
That’s all you need — a clean, collapsed RadGrid on first load without any client-side hacks.