Web view is too slow - flutter

Web view takes more than 4 sec to load the webpage. The same page takes less than 2 sec in Native app. Is there a way to speedup the load time. I tried both Official webview_flutter and flutter_webview_plugin.

If you app relies on WebView, just choose other tools: Swift for iOS & Kotlin for Android.
Here is why:
WebView actually does not load pages slow. Instead, creating the WebView widget is slow;
In order to solve 1, you might want use a cached WebView. Unfortunately, that is not easy. Layout changes (e.g. animation) might trigger a WebView "recreating" (the cached WebView becomes invalid/staled). And the "recreating" is very slow;
Flutter's widgets depend on "state" outside of the widgets, and widgets' creating are supposed to be fast/simple. Unfortunately, WebView (which is not a native widget) is not the case. WebView has its complex internal "state", a recreation simple discard everything and you returns to the WebView's initial state (initial URL). And it is very slow (Creating time + LoadTime: Network overhead);
It is very hard to create a "external state" outside a WebView, therefore after a WebView's recreating it cannot resume from the external state;
Since WebView's recreating is very slow, it totally kills animation and gives user a very bad experience. A solution might be put a WebView as your main page and never try to animate to a new WebView (just like a Wiki App Demo in YouTube).
Conclusion:
So, now, WebView in flutter is not ready and please don't consider use it seriously.
Discussion:
Flutter's widgets design is quite "unusual" since they are basically immutable. States outside widgets (external state) are used. When state changes, instead of modify the widget, Flutter choose to create a new widget based on the new state. Therefore, widgets are deigned to be light weighted so they can be created/destroyed very quickly. Unfortunately, WebView cannot fall into this category. WebView is as complex as the whole Flutter framework, so it cannot be a native widget but a plug-in. And WebView has its own internal state which is not compatible with the framework, which results in keep on being destroyed/recreated by the framework.
I am not sure why Flutter's widgets are designed in this way, maybe it is easier/faster for creating the framework? I saw some complex examples (~100 lines) using Redux/BLOC/Steam just in order to "change" a widget, which might just need a one-line of code in other frameworks.
Performance is also an issue. Rebuild a complex widgets tree is slow. Then you need writing a lot of code (Redux/BLOC/Stream/ScoppedModel...) in order to implement a partial widgets tree build.
Even for a very simple app, performance of Flutter is still not as good as native (https://thoughtbot.com/blog/examining-performance-differences-between-native-flutter-and-react-native-mobile-development). In fact, I'd like considering Flutter as "native" since it is compiled into machine code instead of Java's ByteCode.
Finally:
I am a new Flutter learner and start playing with Flutter for a couple of weeks. The widgets framework and the WebView plug-in just made me headache. A lot of time spent on the UI interface instead of the core logic of my app.
I am not saying Flutter is not good. Actually, I think it is the best cross-platform framework for iOS/Android. It just might be something (e.g. complex external widget like WebView) was not being taken into consideration while the framework was being designed. Hope the Flutter team can find a solution for this, maybe a special case for handling a complex external plug-in?
I will keep on learning/playing with Flutter.

And now Hybrid-Composition is default in webview_flutter 3.0.0:
https://pub.dev/packages/webview_flutter/changelog
Just tried it on my side and since it's not perfect, it's much more faster
cheers!

Updated to webview_flutter 1.0.x and adopted Hybrid-Composition. It performances much better on Android now.
Announcement: announcing-flutter-1-22-44f146009e5f
How to: webview_flutter
Docs: Hybrid-Composition

Related

how to iterate through rendred widgets in flutter?

I have 4 widgets named OptionCard (it's their Type) i'de like to iterate through them to check the value of their variables how can I do it ?
tried OptionCard.forEach but it doesn't work
This is not the way Flutter widgets are supposed to be used. Widgets (even StatefulWidgets) generally do not hold application state. They should only provide a view on state managed elsewhere.
There are many proven methods of application state management that are popular and well supported in Flutter.

Can I build a Frontend in FlutterFlow then export to Flutter to finish coding?

I am learning flutter and dart at the moment. I came across FlutterFlow and I was wondering, could I use FlutterFlow to build the UI of the app, then turn around, take the code, and add it to my IDE and finish coding it with Flutter and dart there?
As I found, you can view the code of the UI and copy it from Developer Menu -> View Code as shown in the following image:
You will see the code with a copy button in the top right corner as shown in the following image:
Bounce:
When you click on a widget in the screen, it shows only the code of it to let you focus on its implementation.
Edit:
In the same developer menu, there is a Download Code button which allows you to download the source code of the application but it's not available in the Free Plan, Standard and Pro only.
Lastly: As a piece of personal advice, if you are learning Flutter, then stay away from tools like FlutterFlow until you reach a good level in Flutter Development, so these tools become just an acceleration for your work, not too highly dependent on them.
Yes, it's possible. You must either be using the "standard" plan to be able to export the source code of the app or, if you just need a tool to create the UI for a flutter app, you can then use the playground area of flutterflow to have access to the source code of that view.

flutter, after push a native viewController from flutter, is this possible display more content above native viewController with flutter again?

I have a native viewController which implement from a framework, I can't directly change it into flutter view.
So I think I can:
Display the UI in native ViewController(a 3rd party native video player) from flutter main app.
Then I need display some extra content(for example user avatar, some text message and so on) above/on native ViewController
But I would prefer implement this extra content with flutter, if it's possible?
Is this good approach ? If not, then I think have to do the things bellow:
Display the UI in native ViewController(a video player) from flutter main app.
Then display some extra content with native code.
PS: why I can't change the native VideController into flutter ? it's because it integration with a native video player which integration cache logic and I can't change the source code in that.
According to [1] it is fine to have some component native, because there just are not all features in new cross platform frameworks like flutter.
According to [2] you could use Decorators from Container to show content in layers, taken that you can show the native content embedded to the Flutter code. In that case, definitely use approach 1.
However, I could only find platform-channels type of solution from Flutter documentation [4] to do native code execution and there it states for example this:
To comply with channels’ UI thread requirement, you may need to jump from a background thread to Android’s UI thread to execute a channel method.
and in other post [3] on platform-channels:
When the user clicks back I want to navigate back to flutter [..]
Both imply everything that is native happens in native thread and view, so I don't see possibility other than your second approach, where all is native.
So, all depends how you fit the native element to Flutter. If you embed, use Flutter for overlays, otherwise do all native. I think good way to measure this is that if you see anything from Flutter generated code when inside the native viewer, you have chances to overlay, otherwise just go native.
[1] Open native UIViewController in Flutter
[2] https://cogitas.net/overlay-text-icon-image-flutter/
[3] How to change the root view controller back to flutter from native iOS?
[4] https://flutter.dev/docs/development/platform-integration/platform-channels

Positioning a sap.m.list

I'd like to create a twitter like stream out of a sap.m.list, hence when I get more data with a pulltorefresh control, I'd like to update the list with the additional rows, but should not move the list at all, and be hidden until the user scrolls the list down.
Any standard ways of doing this, or alternatively, custom CSS/JS recommended ways of doing this?
Thanks,
Matt
There's no need to drop down to jQuery here as OpenUI5 already contains the awesome iScroll library.
I've just setup a test app for you to have a look at here: https://github.com/js1972/ui5_pull_to_refresh.
Clone this; check the readme; then just run grunt serve to open the app in your default browser. You can use Chrome dev tools to emulate an iphone or android, etc.
I think this does what you're after - it works just like the GMail mobile app. You pull down to refresh items and at the end of the refresh your still looking at the same items but can now scroll up to see the new ones.
Will be interesting to see the performance if you have a thousand items... iScroll gives you allot of settings to play that may help (which aren't discussed in the UI5 SDK).
One thing to be careful of with browser scrolling is paint times. If the browser is not 100% done painting then iScroll can't calculate all the element dimensions it needs and you get strange results - typically just no scrolling. Sometimes you've just got to give a little time back to the browser by wrapping things in setTimeout(scroll_stuff, 0).
Hope this helps...
While not quite the answer I was after, looked into doing it another way, and provided you can work with automatically generated Id's that you'll need to calculate based on the row number, the following is one brute force way of doing it (I've borrowed it from another SO question and kept the animation for fun - Referenced SO Link):
var pOffset = $("#__item0-App--Main--MyList-76").position().top;
$("#App--Main--myPage-cont").animate({scrollTop: ( pOffset)}, 800);

Proper way to break apart a GWT widget into smaller chunks

I just want to know if this is the proper way to go about splitting up widgets in GWT that get too large, or if I am missing the concept of widgets/proper GWT usage all together.
I started out with a single class (widget), PCBuilder. As PCBuilder became too large, I decided to branch off and make two classes SuggestionPanel, and BuildControlPanel, both of which just split off PCBuilder's code into separate classes that still have access to the methods in PCBuilder:
This way, in my PCBuilder class, I can do something like this to add the SuggestionPanel and the BuildControlPanel to the tabs (TabLayoutPanel) that are specified in the UiBinder of PCBuilder while allowing for SuggestionPanel and BuildControlPanel to have their own separate UiBinder specifications:
My question is: Is this proper? Part of me thinks "no" just because it's not a nice way of doing it. On the other hand it works just fine, and my web application is somewhat broken up into manageable "sections" which is what I wanted.
Thanks for any insight.
It's fine apart from the fact that you have circular dependencies between classes.
Why do SuggestionPanel and BuildControlPanel need to call PCBuilder? Is there any business logic in it? RPC maybe? Separate that into another class.
First, you might want to take a look at GIN - this handles dependency injection. This is good for testability.
Second, if your app goes beyond one "page", then take a look at GWT MVP.
You should not consider your PCBuilder as a widget. Quoting gwt -
You construct user interfaces in GWT applications using widgets that are contained within panels. Widgets allow you to interact with the user. Panels control the placement of user interface elements on the page.
Coming back to your question, my take is to create widgets only if I can reuse the same element more than once. The rest of my layout logic goes into the view. Layout shouldn't be a part of the definition of the widget as much as possible.To conclude, push styling in css, push layout in the views; widgetize only if re-usable (and core) or if adding additional functionality to existing widgets.