几页深后,页面转换变得非常缓慢
Posted
技术标签:
【中文标题】几页深后,页面转换变得非常缓慢【英文标题】:Page transition becomes painfully slow after several pages deep 【发布时间】:2017-07-30 11:52:13 【问题描述】:我正在使用 Flutter 构建一个简单的***浏览器。由于没有原生的 Flutter Webview,我必须手动解析 html 片段并将其转换为等效的 Flutter 小部件。我设法做到了,但是在深入浏览了几页之后(通过单击蓝色链接),页面转换动画变得非常缓慢。
重现步骤:
添加以下依赖项
dependencies:
flutter:
sdk: flutter
fluro: "^1.1.0"
html: "^0.13.2"
粘贴并运行以下代码(在发布模式下以便更清晰地观察)。
import 'dart:async';
import 'dart:convert';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:fluro/fluro.dart';
import 'package:html/dom.dart' as DOM;
import 'package:html/parser.dart' show parse;
void main()
runApp(new MyApp());
class MyApp extends StatefulWidget
@override
_MyAppState createState() => new _MyAppState();
class _MyAppState extends State<MyApp>
final router = new Router(); // Fluro router
@override
void initState()
super.initState();
router.define(
'/wiki',
handler: new Handler(
handlerFunc: (_, params) => new WikiPage(title: params['q'])
)
);
@override
Widget build(BuildContext context)
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
onGenerateRoute: router.generator, // delegate to Fluro
routes:
'/': (BuildContext context) => new WikiPage(title: 'Firefox')
,
);
class WikiPage extends StatefulWidget
WikiPage(Key key, this.title) : super(key: key);
final String title;
@override
_WikiPageState createState() => new _WikiPageState();
class _WikiPageState extends State<WikiPage>
@override
void initState()
super.initState();
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(title: new Text(widget.title)),
body: new FutureBuilder<String>(
future: getPage(widget.title),
builder: (context, snapshot)
if (snapshot.hasError) return new Text('Error: $snapshot.error');
if (snapshot.hasData)
if (snapshot.data.isEmpty) return new Container(); // empty result
// parse HTML
DOM.Document document = parse(snapshot.data);
document.querySelector('.infobox')?.remove(); // remove the infobox table
List<DOM.Element> paragraphs = document.getElementsByTagName('p');
// convert HTML tree to Flutter widgets
return new ListView(
padding: const EdgeInsets.all(16.0),
children: paragraphs.map((paragraph) =>
new RichText(
text: new TextSpan(
text: '',
style: DefaultTextStyle.of(context).style,
children: paragraph.nodes.map((node)
if (node.toString() == '<html a>') // HTML <a> tag
String href = node.attributes['href'];
return new TextSpan( // as blue link
text: node.text,
style: Theme.of(context).textTheme.body1.copyWith(
color: Colors.blue
),
recognizer: new TapGestureRecognizer()
..onTap = () => Navigator.of(context).pushNamed(
'/wiki?q=$href.split('/')[2]'
)
);
else
return new TextSpan(text: node.text);
).toList()
)
)
).toList()
);
else // waiting for data
return new Center(child: new CircularProgressIndicator());
,
)
);
Future<String> getPage(String title) async
final String url = 'https://en.wikipedia.org/w/api.php?' +
'action=mobileview&format=json§ions=0&noimages=1&noheadings=1' +
'&formatversion=2&page=$Uri.encodeComponent(title)';
final response = await http.get(url);
final json = JSON.decode(response.body);
return json['mobileview']['sections'][0]['text']; // retrieve HTML string
-
单击任意蓝色***链接进行导航。最初的页面过渡动画(前 2-3 页)是平滑的。新页面从底部滑入(android 平台)。
但是页面转换在每次导航时都会变得不稳定,直到它只是冻结一段时间(自下而上的页面转换完全消失了)。
可能是什么问题?垃圾收集器问题?任何帮助表示赞赏。
[√] Flutter (on Microsoft Windows [Version 10.0.15063], locale en-US, channel master)
• Flutter at C:\Users\tzm\Downloads\flutter_sdk
• Framework revision 6655074b37 (2 days ago), 2017-07-28 15:44:38 -0700
• Engine revision 232f4636e5
• Tools Dart version 1.25.0-dev.7.0
【问题讨论】:
你的应用总是感觉生涩。我有一种预感,急躁是因为您在解析整个网页的同时构建小部件。也许,您只在小部件完成解析后才加载页面?无论哪种方式,我发现一个***颤振项目 github.com/namiwang/wiki-flutter 这里是颤振 pub.dartlang.org/packages/flutter_webview_plugin 的非集成 Web 视图 – user1462442 7 分钟前 @user1462442 我确信瓶颈不是解析。前几个页面加载非常流畅,但随着我们将更多 MaterialPageRoutes 推送到导航器中,它会变得越来越重。 动画在第一页跳动。 【参考方案1】:我找到了解决方案。诀窍是
使用 Dart Isolate 将昂贵的 HTML 解析卸载到单独的线程。 将 MaterialPageRoute 中的maintainState
设置为 false
,以便始终从内存中丢弃之前的计算。不利的一面是,当我们从当前页面弹出时,我们需要重新生成以前访问过的页面。
【讨论】:
以上是关于几页深后,页面转换变得非常缓慢的主要内容,如果未能解决你的问题,请参考以下文章
在 MS SQL Server 中,将行插入表变量突然变得非常缓慢