title: Very simple image loaded pretty slow with Flutter
body: <p>I'm making a mobile application using the Flutter SDK and Dart, so far, I just got a simple User login form, the main widget over that is a ListView with the top widget as a Card widget with an image inside that works as a logo, my problem is, this logo takes like 1 to 2 seconds to load, and looks very ugly, I mean, when I launch the app, after the splash screen, all I see over my Card widget is a blank space, and after 1 to 2 seconds my image appears, it is very noticeable.</p>
  
  <p>I read many ways to avoid this but none seem to work, the most common is to use precacheImage method to preload the image but that doesn't seem to work, I also tried this over the built as release and same thing happen, I must clarify that this logo is very small in size (100kB). </p>
  
  <p>So far this is a part of my code, this HomeState class is just State of the Home stateful widget that is the body of a Scaffold widget that is the home of a MaterialApp, this is the main screen, so after the splash screen this is the first thing that loads, </p>
  
  <pre class="lang-dart prettyprint-override"><code>class HomeState extends State&lt;Home&gt; {
    var _minPad = 5.0;
    var _formKey = GlobalKey&lt;FormState&gt;();
    TextEditingController username = TextEditingController();
    TextEditingController password = TextEditingController();
    ImageProvider logo;
  
    @override
    void didChangeDependencies() async {
      logo = AssetImage('images/logo_rienpa.png');
      await precacheImage(logo, context);
      super.didChangeDependencies();
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
            title: Center(
                child: Text('Rutinas de Mantenimiento',
                    textAlign: TextAlign.center))),
        body: loginForm(),
        backgroundColor: Colors.blue,
      );
    }
  
    Form loginForm() {
      TextStyle titleStyle = Theme.of(context).textTheme.title;
      return Form(
          key: _formKey,
          child: Padding(
            padding: EdgeInsets.all(_minPad * 4),
            child: Center(
              child: ListView(
                children: &lt;Widget&gt;[
                  getLogo(),
                  Padding(
                      padding:
                          EdgeInsets.only(top: _minPad * 8, bottom: _minPad * 2),
                      child: TextFormField(
                        controller: username,
                        keyboardType: TextInputType.text,
                        style: titleStyle,
                        validator: (String value) {
                          if (value.isEmpty) {
                            return 'Por favor, ingresa tu nombre de usuario';
                          }
                        },
                        decoration: InputDecoration(
                            labelText: 'Usuario',
                            labelStyle: titleStyle,
                            hintText: 'Ingresa tu usuario',
                            border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(5.0))),
                      )),
                  Padding(
                    padding:
                        EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 4),
                    child: TextFormField(
                      controller: password,
                      obscureText: true,
                      style: titleStyle,
                      validator: (String value) {
                        if (value.isEmpty) {
                          return 'Por favor, ingresa una contraseña';
                        }
                      },
                      decoration: InputDecoration(
                          labelText: 'Contraseña',
                          labelStyle: titleStyle,
                          hintText: 'Contraseña personal',
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(5.0))),
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.only(
                        top: _minPad * 2,
                        bottom: _minPad * 2,
                        right: _minPad * 20,
                        left: _minPad * 20),
                    child: RaisedButton(
                        color: Theme.of(context).primaryColor,
                        textColor: Colors.white,
                        child: Text(
                          "Ingresar",
                          textScaleFactor: 1.5,
                        ),
                        onPressed: () {
                          setState(() {
                            if (_formKey.currentState.validate()) {
                              //code
                            }
                          });
                        }),
                  ),
                  Padding(
                      padding:
                          EdgeInsets.only(top: _minPad * 10, bottom: _minPad * 2),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: &lt;Widget&gt;[
                          Text(
                            "No tienes un usuario?, registrate ",
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white),
                          ),
                          InkWell(
                            child: Text(
                              'aqui',
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                  color: Colors.black,
                                  decoration: TextDecoration.underline),
                            ),
                            onTap: () {
                              Navigator.push(context,
                                  MaterialPageRoute(builder: (context) {
                                return Register();
                              }));
                            },
                          ),
                          Text(
                            ".",
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white),
                          )
                        ],
                      ))
                ],
              ),
            ),
          ));
    }
  
    Widget getLogo() {
      Image logoImage = Image(image: logo, width: 250.0, height: 167.0,);
      return Padding(
          padding: EdgeInsets.only(right: _minPad * 5, left: _minPad * 5),
          child: Card(
            color: Colors.white,
            elevation: 8.0,
            child: logoImage,
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
          ));
    }
  }
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>As requested, here is my full code, they are three files.</p>
  
  <p>main.dart:</p>
  
  <pre class="lang-dart prettyprint-override"><code>import 'package:flutter/material.dart';
  import 'package:rutinas_de_mantenimiento/screens/home.dart';
  
  void main() =&gt; runApp(MainApp());
  
  class MainApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      precacheImage(AssetImage('images/logo_rienpa.png'), context);
      return MaterialApp(
        title: "Rutinas de Mantenimiento",
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
            primarySwatch: Colors.blueGrey, primaryColor: Colors.blueGrey),
        home: Home(),
      );
    }
  }
  </code></pre>
  
  <p>home.dart (place where the image is loaded)</p>
  
  <pre class="lang-dart prettyprint-override"><code>import 'package:flutter/material.dart';
  import 'package:rutinas_de_mantenimiento/screens/register.dart';
  
  class Home extends StatefulWidget {
    @override
    State&lt;StatefulWidget&gt; createState() {
      return HomeState();
    }
  }
  
  class HomeState extends State&lt;Home&gt; {
    var _minPad = 5.0;
    var _formKey = GlobalKey&lt;FormState&gt;();
    TextEditingController username = TextEditingController();
    TextEditingController password = TextEditingController();
    ImageProvider logo = AssetImage('images/logo_rienpa.png');
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
            title: Center(
                child: Text('Rutinas de Mantenimiento',
                    textAlign: TextAlign.center))),
        body: loginForm(),
        backgroundColor: Colors.blue,
      );
    }
  
    Form loginForm() {
      TextStyle titleStyle = Theme.of(context).textTheme.title;
      return Form(
          key: _formKey,
          child: Padding(
            padding: EdgeInsets.all(_minPad * 4),
            child: Center(
              child: ListView(
                children: &lt;Widget&gt;[
                  getLogo(),
                  Padding(
                      padding:
                          EdgeInsets.only(top: _minPad * 8, bottom: _minPad * 2),
                      child: TextFormField(
                        controller: username,
                        keyboardType: TextInputType.text,
                        style: titleStyle,
                        validator: (String value) {
                          if (value.isEmpty) {
                            return 'Por favor, ingresa tu nombre de usuario';
                          }
                        },
                        decoration: InputDecoration(
                            labelText: 'Usuario',
                            labelStyle: titleStyle,
                            hintText: 'Ingresa tu usuario',
                            border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(5.0))),
                      )),
                  Padding(
                    padding:
                        EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 4),
                    child: TextFormField(
                      controller: password,
                      obscureText: true,
                      style: titleStyle,
                      validator: (String value) {
                        if (value.isEmpty) {
                          return 'Por favor, ingresa una contraseña';
                        }
                      },
                      decoration: InputDecoration(
                          labelText: 'Contraseña',
                          labelStyle: titleStyle,
                          hintText: 'Contraseña personal',
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(5.0))),
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.only(
                        top: _minPad * 2,
                        bottom: _minPad * 2,
                        right: _minPad * 20,
                        left: _minPad * 20),
                    child: RaisedButton(
                        color: Theme.of(context).primaryColor,
                        textColor: Colors.white,
                        child: Text(
                          "Ingresar",
                          textScaleFactor: 1.5,
                        ),
                        onPressed: () {
                          setState(() {
                            if (_formKey.currentState.validate()) {
                              //code
                            }
                          });
                        }),
                  ),
                  Padding(
                      padding:
                          EdgeInsets.only(top: _minPad * 10, bottom: _minPad * 2),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: &lt;Widget&gt;[
                          Text(
                            "No tienes un usuario?, registrate ",
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white),
                          ),
                          InkWell(
                            child: Text(
                              'aqui',
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                  color: Colors.black,
                                  decoration: TextDecoration.underline),
                            ),
                            onTap: () {
                              Navigator.push(context,
                                  MaterialPageRoute(builder: (context) {
                                return Register();
                              }));
                            },
                          ),
                          Text(
                            ".",
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white),
                          )
                        ],
                      ))
                ],
              ),
            ),
          ));
    }
  
    Widget getLogo() {
      Image logoImage = Image(image: logo, width: 250.0, height: 167.0,);
      return Padding(
          padding: EdgeInsets.only(right: _minPad * 5, left: _minPad * 5),
          child: Card(
            color: Colors.white,
            elevation: 8.0,
            child: logoImage,
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
          ));
    }
  }
  </code></pre>
  
  <p>And resgister.dart I think this is not needed but here it goes</p>
  
  <pre class="lang-dart prettyprint-override"><code>import 'package:flutter/material.dart';
  
  class Register extends StatefulWidget {
    @override
    State&lt;StatefulWidget&gt; createState() {
      return RegisterState();
    }
  }
  
  class RegisterState extends State&lt;Register&gt; {
    var _formKey = GlobalKey&lt;FormState&gt;();
    TextEditingController fullName = TextEditingController();
    TextEditingController username = TextEditingController();
    TextEditingController password = TextEditingController();
    TextEditingController confirmPwd = TextEditingController();
    TextEditingController email = TextEditingController();
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Center(
            child: Text(
              'Rutinas de Mantenimiento',
              textAlign: TextAlign.center,
            ),
          ),
          automaticallyImplyLeading: false,
        ),
        body: registerForm(),
        backgroundColor: Colors.blue,
      );
    }
  
    Form registerForm() {
      var _minPad = 5.0;
      TextStyle titleStyle = Theme.of(context).textTheme.title;
  
      return Form(
        key: _formKey,
        child: Padding(
          padding: EdgeInsets.all(_minPad * 4),
          child: Center(
            child: ListView(
              children: &lt;Widget&gt;[
                Text(
                  "Registro de usuario",
                  textAlign: TextAlign.center,
                  style: TextStyle(
                      decoration: null,
                      fontSize: 35.0,
                      color: Colors.white),
                ),
                Padding(
                  padding:
                  EdgeInsets.only(top: _minPad * 14, bottom: _minPad * 2),
                  child: TextFormField(
                    controller: fullName,
                    style: titleStyle,
                    textAlign: TextAlign.center,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor ingresa tu nombre completo';
                      }
                    },
                    decoration: InputDecoration(
                        hintText: "Nombre completo", hintStyle: titleStyle),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                  child: TextFormField(
                    controller: username,
                    style: titleStyle,
                    textAlign: TextAlign.center,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor ingresa un usuario';
                      }
                    },
                    decoration: InputDecoration(
                        hintText: "Nombre de usuario", hintStyle: titleStyle),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                  child: TextFormField(
                    controller: email,
                    style: titleStyle,
                    textAlign: TextAlign.center,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor ingresa tu Email';
                      }
                    },
                    decoration:
                    InputDecoration(hintText: "Email", hintStyle: titleStyle),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                  child: TextFormField(
                    controller: password,
                    obscureText: true,
                    style: titleStyle,
                    textAlign: TextAlign.center,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor ingresa una contraseña';
                      }
                    },
                    decoration: InputDecoration(
                        hintText: "Contraseña", hintStyle: titleStyle),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                  child: TextFormField(
                    controller: confirmPwd,
                    obscureText: true,
                    style: titleStyle,
                    textAlign: TextAlign.center,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor repita su contraseña';
                      }
                    },
                    decoration: InputDecoration(
                        hintText: "Confirme contraseña", hintStyle: titleStyle),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(
                      top: _minPad * 4,
                      bottom: _minPad * 2,
                      right: _minPad * 20,
                      left: _minPad * 20),
                  child: RaisedButton(
                      color: Theme.of(context).primaryColor,
                      textColor: Colors.white,
                      child: Text(
                        "Registrar",
                        textScaleFactor: 1.5,
                      ),
                      onPressed: () {
                        setState(() {
                          if (_formKey.currentState.validate()) {
                            //code
                          }
                        });
                      }),
                )
              ],
            ),
          ),
        ),
      );
    }
  }
  </code></pre>