【问题标题】:Is it possible to delay-load PRISM / Xamarin Forms components that aren't immediately needed?是否可以延迟加载不需要的 PRISM / Xamarin Forms 组件?
【发布时间】:2019-03-05 12:28:46
【问题描述】:
我有以下 AppDelegate 需要很长时间才能加载:
Syncfusion.ListView.XForms.iOS.SfListViewRenderer.Init();
new Syncfusion.SfNumericUpDown.XForms.iOS.SfNumericUpDownRenderer();
Syncfusion.SfCarousel.XForms.iOS.SfCarouselRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfSegmentedControlRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfCheckBoxRenderer.Init();
new Syncfusion.XForms.iOS.ComboBox.SfComboBoxRenderer();
//Syncfusion.XForms.iOS.TabView.SfTabViewRenderer.Init();
new Syncfusion.SfRotator.XForms.iOS.SfRotatorRenderer();
new Syncfusion.SfRating.XForms.iOS.SfRatingRenderer();
new Syncfusion.SfBusyIndicator.XForms.iOS.SfBusyIndicatorRenderer();
当我知道其中一些组件对于主屏幕来说不需要,但对于子屏幕来说,我应该考虑哪些选项?
我正在使用 PRISM,似乎每个选项卡都在允许显示或与最终用户交互之前立即预加载。我可以做些什么来延迟 Prism TabView 在显示界面之前进行的预渲染?
我应该使用Lazy<T>吗?什么是正确的方法?
我应该将这些组件移到另一个初始化部分吗?
【问题讨论】:
标签:
xamarin.forms
prism
appdelegate
syncfusion
lazy-initialization
【解决方案1】:
您可以通过多种方式最终实现这一目标,这完全取决于您的真正目标是什么。
如果您的目标是确保尽可能快地访问 Xamarin.Forms 页面,以便您拥有某种活动指示器,它实质上是对用户说,“没关系,我没有冻结,我们“只是在做一些事情为你做准备”,那么你可以尝试创建一个“SpashScreen”页面,你可以在其中进行额外的加载。设置可能如下所示:
public partial class AppDelegate : FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App(new iOSInitializer()));
return base.FinishedLaunching(app, options);
}
}
}
public class iOSInitializer : IPlatformInitializer, IPlatformFinalizer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterInstance<IPlatformFinalizer>(this);
}
public void Finalize()
{
new Syncfusion.SfNumericUpDown.XForms.iOS.SfNumericUpDownRenderer();
Syncfusion.SfCarousel.XForms.iOS.SfCarouselRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfSegmentedControlRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfCheckBoxRenderer.Init();
}
}
public class App : PrismApplication
{
protected override async void OnInitialized()
{
await NavigationService.NavigateAsync("SplashScreen");
}
}
public class SplashScreenViewModel : INavigationAware
{
private IPlatformFinalizer _platformFinalizer { get; }
private INavigationService _navigationService { get; }
public SplashScreenViewModel(INavigationService navigationService, IPlatformFinalizer platformFinalizer)
{
_navigationService = navigationService;
_platformFinalizer = platformFinalizer;
}
public async void OnNavigatedTo(INavigationParameters navigationParameters)
{
_platformFinalizer.Finalize();
await _navigationService.NavigateAsync("/MainPage");
}
}
如果您正在使用模块,则可以采用类似的方法,尽管在启动时初始化的任何模块仍然会在您设置要导航到的页面之前调用 Init 渲染器。也就是说,使用模块确实给您带来了许多好处,因为您只需要初始化应用程序此时实际需要的东西。
所有这一切都表明,如果您看到很多收益,我会感到惊讶,因为这些 Init 调用通常是空方法,仅旨在防止链接器将它们链接出来...如果您没有链接或者有一个链接器文件,您可以简单地指示链接器不理会您的 Syncfusion 和其他库。