1

I'm working on an app that requires asynchronous loading before my main screen shows up. It initializes some provider classes, thus instead of initializing in main() and using the native splash screen (which I could not get the BuildContext required for provider), I decided to create my own splash screen as a widget.

This approach worked fine until I added a logo using Image.asset().

The image was loading too slowly, often slower than my original initialization, which means that my splash screen stays blank.

Just for reference, this is my splash screen layout:

Container(
  alignment: Alignment.center,
  color: Theme.of(context).scaffoldBackgroundColor,
  child: Center(
    child: Image.asset("logo.png"),
  )
);

I came across the function precacheImage(), but this also requires BuildContext, thus couldn't be used before the splash screen is shown.

Is there any better approach to this? Thanks in advance.

2
  • do you add in pubspec the path of image Commented Sep 11, 2020 at 1:34
  • @evan yes of course :) Commented Sep 11, 2020 at 2:03

3 Answers 3

1

I'll skip the obvious solutions like reducing the size of image.. Are you sure you're using precacheImage in the right place?

Correct usage would be like this:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    precacheImage(AssetImage("assets/images/logo.png"), context);
    return MaterialApp(
      title: 'MyApp',
      theme: myTheme,
      home: MySplashScreen(),
    );
  }
}

And in the MySplashScreen just do this:

ImageProvider logo = AssetImage("assets/images/logo.png");

Also, it may sound weird, but if you don't see improvement, try to use jpg instead of png.

P.S. and if you run it in debug mode it can be slow cuz of how Flutter is handled in this mode, production is many times faster, try it on real device with flutter run --release

Sign up to request clarification or add additional context in comments.

4 Comments

The image has a transparent background, so it couldn't be converted to jpg.
I thought precacheImage should be used way before the screen is shown instead of right before it? Tried your provided code and ran in release mode but seems like there is little to no improvements :(
Well in case your image is 8300x8300 no wonder it may lag.. and you need transparency, hmm.. Can't suggest much without seeing the image, but at this point I would try to think of ways of optimising the image itself =/
Yeah I reduced the image size and it obviously improved much. You're right, I'll try to do something to the image then.
1

My splash screen build is similar. What is the file size of your logo?

Update: My logo is 512x512 and 32k.

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        key: UniqueKey(),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                  decoration: null,
                  margin: EdgeInsets.symmetric(horizontal: _margin),
                  child: Image.asset("assets/meds.png"),
              ),
              SizedBox(
                height: 10,
              ),
              SpinKitDoubleBounce(
                color: Theme.of(context).primaryColor,
              ),
            ],
          ),
        ),
      ),
    );
  }

1 Comment

Mine is currently 8300x8300. I thought about reducing image size, but I am already seeing sharp edges on target screens. I guess I should just try reducing it a bit.
0

There's always a delay between the app start and the flutter first paint, you will get better performance by implementing a splash screen natively.

https://android.jlelse.eu/launch-screen-in-android-the-right-way-aca7e8c31f52

3 Comments

I have to initialize provider models which requires BuildContext, so I couldn't be initializing it in main (where the native splash screen is shown).
No, the native splash screen is built outside of Flutter code in android and ios seperately.
I think we're talking about different stuff. I know you could build native ios/android splash screens, which is the screen shown when main() is executed and before runApp(). You could initialize stuff before runApp, but that way you couldn't get BuildContext. This is why I have to make my custom splash screen instead of going native.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.