【问题标题】:Xamarin.Forms Help optimize load timesXamarin.Forms 帮助优化加载时间
【发布时间】:2021-09-23 05:31:58
【问题描述】:

我正在 Xamarin Forms 中创建一个应用程序,并且在加载应用程序时我有一个登录名。情况是,当我放入数据时,我调用了一个 API,它以 json 的形式返回了一系列数据。

然后我通过json,检查每个数据是否存在于我的本地数据库(sqlite)中,如果存在,我更新它,如果它不存在,我插入它。

一旦它完成了所有的 json,它就会加载以下活动,或者屏幕......

问题在于,进行下一个活动很容易需要 10 到 15 秒。

知道如何优化这个过程吗?或者,我应该修改 API 以获取更少的数据吗?

代码:

Login.xaml.cs

namespace WorkersApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Login : ContentPage
    {
        public Login()
        {
            InitializeComponent();
        }
        public string user = "";
        public string password = "";

        private async void btnEncript_Clicked(object sender, EventArgs e)
        {
            if (userEntry.Text != null && passwordEntry.Text != null)
            {
                user = userEntry.Text;
                password = EncriptarMD5.MD5Hash(passwordEntry.Text);

                string url = "https://api.com/?f=login&u=" + user + "&pw=" + password;

                await GetDataFromApi(url);

            }
        }
        public async Task GetDataFromApi(string url)
        {

            HttpClient myClient = new HttpClient();
            try
            {
                var response = await myClient.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();

                    //ERRORES
                    var error = JsonConvert.DeserializeObject<Errores>(content);
                    List<string> errror = new List<string>();
                    foreach (var item in error.error)
                    {
                        errror.Add(item.Value);
                    }
                    //Tiro error.
                    if (errror[0] != "0")
                    {
                        Preferences.Set("IdError", errror[0]);
                        Preferences.Set("Nombre", errror[1]);
                        return;
                    }
                    else
                    {
                        Preferences.Set("IdError", errror[0]);
                        Preferences.Set("Nombre", errror[1]);
                    }

                    //HOTELES

                    var hoteles = JsonConvert.DeserializeObject<Hoteles>(content);

                    List<Model.Hoteles> lista_hoteles = await App.Database.GetHotelesAsync();
                    List<Model.Bloques> lista_bloques = await App.Database.GetBloquesAsync();

                    foreach (var item in hoteles.hoteles)
                    {
                        Model.Hoteles h = new Model.Hoteles();
                        
                        h = JsonConvert.DeserializeObject<Model.Hoteles>(item.Value.ToString());
                        h.ID = item.Key.ToString();

                        var bloques = JsonConvert.DeserializeObject<Bloques>(item.Value.ToString());
                        bool existe = false;
                        foreach (var bloque in bloques.bloques)
                        {
                            existe = false;
                            Model.Bloques b = new Model.Bloques();
                            b.ID = bloque.Key.ToString();
                            b.Nombre = bloque.Value.ToString();
                            b.IDHotel = item.Key.ToString();
                            foreach (var iLista in lista_bloques)
                            {
                                if (b.ID == iLista.ID)
                                {
                                    existe = true;
                                }
                            }
                            if (existe)
                            {
                                await App.Database.UpdateBloquesAsync(b);
                            }
                            else
                            {
                                await App.Database.SaveBloquesAsync(b);
                            }
                        }

                        existe = false;
                        //if exists
                        foreach (var iLista in lista_hoteles)
                        {
                            if (h.ID == iLista.ID)
                            {
                                existe = true;
                            }
                        }
                        if (existe)
                        {
                            await App.Database.UpdateHotelesAsync(h);
                        }
                        else
                        {
                            await App.Database.SaveHotelesAsync(h);
                        }

                    }

                    //SECCIONES
                    var secciones = JsonConvert.DeserializeObject<Secciones>(content);

                    List<Model.Seccion> lista_secciones = await App.Database.GetSeccionesAsync();
                    

                    foreach (var item in secciones.secciones)
                    {
                        Model.Seccion s = new Model.Seccion
                        {
                            ID = item.Key.ToString(),
                            Nombre = item.Value
                        };
                        bool existe = false;
                        //if exists
                        foreach (var iLista in lista_secciones)
                        {
                            if (s.ID == iLista.ID)
                            {
                                existe = true;
                            }
                        }
                        if (existe)
                        {
                            await App.Database.UpdateSeccionAsync(s);
                        }
                        else{
                            await App.Database.SaveSeccionAsync(s);
                        }

                    }
                    string data = Preferences.Get("IdError", "");

                    if (data == "0")
                    {
                        Application.Current.MainPage = new HomePage();
                    }
                    else
                    {
                        await DisplayAlert("Error", Preferences.Get("Nombre", ""), "Cerrar");
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine("EXCEPTION:::: " + exc);
                await DisplayAlert("Error", exc.ToString(), "Cerrar");
            }

        }
    }
}

HomePage.xaml.cs

namespace WorkersApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class HomePage : Shell
    {
        public IList<Seccion> Secciones { get; set; }
        public HomePage()
        {
            InitializeComponent();
            Task.Run(async () =>
                Secciones = await App.Database.GetSeccionesAsync()).Wait();
            foreach(var item in Secciones)
            {
                Console.WriteLine(item.Nombre);
                switch (item.Nombre)
                {
                    case "Partes":
                        FlyPartes.IsVisible = true;
                        //Meter Partes en Parte
                        string url = "https://api.com/?f=partes.getList";
                        Task task = GetPartesFromApi(url);
                        break;
                    case "Auditorias":
                        FlyAuditorias.IsVisible = true;
                        break;
                    case "Maquinas":
                        FlyMaquinaria.IsVisible = true;
                        break;
                    case "Pisos":
                        FlyPisos.IsVisible = true;
                        break;
                }
            }
        }

        public async Task GetPartesFromApi(string url)
        {

            HttpClient myClient = new HttpClient();
            try
            {
                var response = await myClient.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();

                    var error = JsonConvert.DeserializeObject<Errores>(content);
                    List<string> errror = new List<string>();
                    foreach (var item in error.error)
                    {
                        errror.Add(item.Value);
                    }

                    if (errror[0] != "0")
                    {
                        Preferences.Set("IdError", errror[0]);
                        Preferences.Set("Nombre", errror[1]);
                        return;
                    }
                    else
                    {
                        Preferences.Set("IdError", errror[0]);
                        Preferences.Set("Nombre", errror[1]);
                    }

                    var partes = JsonConvert.DeserializeObject<Objetos.Partes>(content);

                    List<Model.Partes> lista = await App.Database.GetPartesAsync();
                    foreach (var item in partes.partes)
                    {
                        Model.Partes p = new Model.Partes();
                        
                        p = JsonConvert.DeserializeObject<Model.Partes>(item.Value.ToString());
                        p.ID = item.Key.ToString();
                        bool existe = false;
                        //if exists
                        foreach (var iLista in lista)
                        {
                            if (p.ID == iLista.ID)
                            {
                                existe = true;
                            }
                        }
                        if (existe)
                        {
                            await App.Database.UpdatePartesAsync(p);
                        }
                        else
                        {
                            await App.Database.SavePartesAsync(p);
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine("EXCEPTION:::: " + exc);
                await DisplayAlert("Error", exc.ToString(), "Cerrar");
            }

        }
    }
}

Partes.xaml.cs

namespace WorkersApp.Pageviews
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Partes : ContentPage
    {
        public IList<Model.Partes> Partess { get; set; }
        public Partes()
        {
            InitializeComponent();

            Task.Run(async () =>
                Partess = await App.Database.GetPartesAsync()).Wait();
            int contador = 0;
            foreach (var item in Partess)
            {
                Color c = Color.Black;
                if (contador % 2 == 0)
                {
                    c = Color.FromRgb(64, 64, 64);
                }
                var partesBoxClick = new BoxView()
                {
                    WidthRequest = 900,
                    HeightRequest = 120,
                    HorizontalOptions = LayoutOptions.Start,
                    VerticalOptions = LayoutOptions.Start,
                    BackgroundColor = c,
                    ClassId = item.ID

                };
                var partesBoxClick_tap = new TapGestureRecognizer();
                partesBoxClick_tap.Tapped += (s, e) =>
                {
                    //OPEN PARTE
                    GetDatosParteFromApi("https://api.com/?f=partes.get&id= " + partesBoxClick.ClassId, partesBoxClick.ClassId);
                };
                partesBoxClick.GestureRecognizers.Add(partesBoxClick_tap);
                PartesListaView.Children.Add(partesBoxClick, 0, contador);
                Color color = Color.Red;

                Console.WriteLine("COLOR::::  " + item.Operacion);
                switch (item.Operacion)
                {
                    case "nuevo":
                        color = Color.Red;
                        break;
                    case "asignado":
                        color = Color.GreenYellow;
                        break;
                    case "en progreso":
                        color = Color.Orange;
                        break;
                    case "anulado":
                        color = Color.Gray;
                        break;
                    case "en ejecucion":
                        color = Color.DeepSkyBlue;
                        break;
                    case "cerrado":
                        color = Color.Green;
                        break;
                    case "terceros":
                        color = Color.Firebrick;
                        break;
                }

                PartesListaView.Children.Add(new BoxView() { BackgroundColor = color, WidthRequest = 5, HeightRequest = 120, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start }, 0, contador);
                PartesListaView.Children.Add(new Label { Text = item.Titulo, FontSize=16, FontAttributes=FontAttributes.Bold, Padding = new Thickness(10, 0, 0, 0), HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start }, 0, contador);
                PartesListaView.Children.Add(new Label { Text = item.Departamento, Padding = new Thickness(10, 0, 10, 18), HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.End }, 0, contador);
                PartesListaView.Children.Add(new Label { Text = item.Hotel, Padding = new Thickness(10, 0, 10, 0), HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.End }, 0, contador);
                PartesListaView.Children.Add(new Label { Text = item.Fecha, Padding = new Thickness(10, 0, 10, 18), HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.End }, 0, contador);
                PartesListaView.Children.Add(new Label { Text = item.Prioridad, Padding = new Thickness(10, 0, 10, 0), HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.End }, 0, contador);
                contador++;
            }
        }

        public async Task GetDatosParteFromApi(string url, string id)
        {

            HttpClient myClient = new HttpClient();
            try
            {
                var response = await myClient.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();

                    //GET ERROR
                    var error = JsonConvert.DeserializeObject<Errores>(content);
                    List<string> errror = new List<string>();
                    foreach (var item in error.error)
                    {
                        errror.Add(item.Value);
                    }

                    if (errror[0] != "0")
                    {
                        Preferences.Set("IdError", errror[0]);
                        Preferences.Set("Nombre", errror[1]);
                        return;
                    }
                    //GET DATOS
                    List<string> ids = new List<string>();
                    List<string> idsh = new List<string>();
                    var Datos = JsonConvert.DeserializeObject<Parte>(content);
                    string parte_datos = "";
                    string parte_fotos = "";
                    string parte_historico = "";
                    foreach (var item in Datos.parte)
                    {
                        if (item.Key.ToString() == "datos")
                        {
                            List<Model.Parte> datosParte = await App.Database.GetDatosParteAsync();
                            parte_datos = item.Value.ToString();
                            Model.Parte parte = new Model.Parte();
                            parte = JsonConvert.DeserializeObject<Model.Parte>(parte_datos);
                            parte.ID_Parte = id;
                            bool existe = false;
                            foreach (var iLista in datosParte)
                            {
                                if (parte.ID_Parte == iLista.ID_Parte)
                                {
                                    existe = true;
                                }
                            }
                            if (existe)
                            {
                                await App.Database.UpdateDatosParteAsync(parte);
                            }
                            else
                            {
                                await App.Database.SaveDatosParteAsync(parte);
                            }
                        }
                        else if (item.Key.ToString() == "fotos")
                        {
                            parte_fotos = item.Value.ToString();
                            List<Model.Fotos> fotos = await App.Database.GetFotosAsync();
                            List<Model.Fotos> FotoList = new List<Model.Fotos>();
                            //foto = JsonConvert.DeserializeObject<Model.Fotos>(parte_fotos);
                            FotoList = JsonConvert.DeserializeObject<List<Model.Fotos>>(parte_fotos);

                            foreach(var fotoI in FotoList)
                            {
                                Model.Fotos foto = new Model.Fotos();
                                foto = fotoI;
                                foto.ID_Parte = id;
                                bool existe = false;
                                ids.Add(foto.ID_Foto);
                                foreach (var iLista in fotos)
                                {
                                    if (foto.ID_Foto == iLista.ID_Foto)
                                    {
                                        existe = true;
                                    }
                                }
                                if (existe)
                                {
                                    await App.Database.UpdateFotoAsync(foto);
                                }
                                else
                                {
                                    await App.Database.SaveFotoAsync(foto);
                                }
                            }

                        }
                        else if (item.Key.ToString() == "historico")
                        {
                            parte_historico = item.Value.ToString();
                            List<Model.Historico> historicos = await App.Database.GetHistoricoAsync();
                            List<Model.Historico> HistoricoList = new List<Model.Historico>();
                            HistoricoList = JsonConvert.DeserializeObject<List<Model.Historico>>(parte_historico);

                            foreach (var historicoI in HistoricoList)
                            {
                                Model.Historico historico = new Model.Historico();
                                historico = historicoI;
                                historico.idHistorico = id + historico.fechaEvento;
                                bool existe = false;
                                idsh.Add(historico.idHistorico);
                                foreach (var iLista in historicos)
                                {
                                    if (historico.idHistorico == iLista.idHistorico)
                                    {
                                        existe = true;
                                    }
                                }
                                if (existe)
                                {
                                    await App.Database.UpdateHistoricoAsync(historico);
                                }
                                else
                                {
                                    await App.Database.SaveHistoricoAsync(historico);
                                }
                            }
                        }
                    }

                    string data = Preferences.Get("IdError", "");

                    if (data == "0")
                    {
                        await Navigation.PushAsync(new DatosParte(id, ids, idsh));
                    }
                    else
                    {
                        await DisplayAlert("Error", Preferences.Get("Nombre", ""), "Cerrar");
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine("EXCEPTION:::: " + exc);
                await DisplayAlert("Error", exc.ToString(), "Cerrar");
            }

        }

        private void Filter_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new FiltroPartes());
        }
    }
    
}

感谢阅读。

编辑:::::

清理 API 后,现在我检查是否更新或保存 indo 本地 sqlite 的 Ticket 更少了。

但我只是注意到我仍然需要检查整个 BBDD 才能登录。

API 现在检查从 curdate 开始的过去 30 天的票证

operation_state <> "Closed"

我想我正在登录(1 次调用 API 以检查用户是否良好) 然后在主页中获取所有门票(1 次调用 API 以获取门票) 然后。当我单击门票菜单时,它会加载到列表视图中。 (所以再过 15 秒)。

我相信我需要删除主页中的 API 调用。并在我点击工单菜单时添加它。

一段时间后会检查。或者明天。

编辑:

所以我检查了一下,我是对的,当我点击门票菜单时,我更改了应用程序以获取所有门票。

感谢阅读。

【问题讨论】:

  • 为了进行优化,您需要确定哪些特定部分很慢

标签: android loops optimization xamarin.forms


【解决方案1】:

Cristian,这在移动应用开发中很正常。根据我们获得的数据量,加载需要时间。

尽管您已经提到您正在调用服务并在不存在时插入数据并在存在时更新,所以这些数据是动态的并且每次调用时都会更改?如果不是而不是再次更新或调用服务,请使用本地数据库中的数据。

如果不是,您可以使用猴子缓存,这将帮助您提高应用性能。但仅在静态数据的情况下使用它。

另一件事不是一次从服务中获取所有数据,而是尝试仅获取所需的数据并将在您的使用中使用,这也将提高您的应用程序的性能。并且还减少了它使用的互联网数据量。

更多详情请参考:https://heartbeat.fritz.ai/techniques-for-improving-performance-in-a-xamarin-forms-application-b439f2f04156

您还可以从应用程序中删除图像并为此使用 FontAwesome 图标。

希望这会对您有所帮助!

【讨论】:

  • 这是一个工单解决应用程序,所以只有最近/未关闭的工单在 API 数据检索中很重要...所以我认为获得已关闭的工单并不重要?
  • 是的,正确的。您必须识别这些不必要的数据并将其删除。
  • 稍后会检查 API 并选择答案。感谢您今天成为我的小橡皮鸭!
  • 好吧,延迟加载数据是优化应用性能和改善应用外观和感觉的最佳方法之一。您始终可以使用现有的 XF 组件来执行此操作,但您可以在 NuGet 上找到一些包,它们可以让您的用户体验稍微好一点
  • 延迟加载数据如何工作?我想它会很感兴趣。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 2011-05-06
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多