In JavaScript it depends on the order of script tags and their attributes. It's really hard to determine what code is actually run at application startup, and what the initial state is.
Making the top-level only declarations means that the programmer knows what code runs first (the first line in main()) and the VM knows that the order of evaluating the declarations doesn't matter. It can evaluate them all and cache the result so that subsequent runs are fast, it can execute main() before other declarations and evaluate them on an as-needed basis, or something in between.
OT: script tag soup is, for first party stuff anyway, avoided with a single script for a module loader these days.
Also, if you import a library that contains this top-level imperative code, how do you invoke it? Is it invoked automatically? When? How does that play with cyclic imports?
The small amount of overhead of a main() method solves all of that.
This is not really possible if you must interpret top level code to build up your top-level declarations, as done in JS.
Using snapshots, the Dart authors have said it should be possible to improve script start up time by 10x over V8. This is a big win for large script heavy apps.
Edit: link https://www.dartlang.org/articles/snapshots/