lianjiatech / keframe Goto Github PK
View Code? Open in Web Editor NEWComponents that optimize Flutter fluency.(Flutter 流畅度优化的通用方案,轻松解决卡顿问题)
License: MIT License
Components that optimize Flutter fluency.(Flutter 流畅度优化的通用方案,轻松解决卡顿问题)
License: MIT License
当一个tabview 嵌套多个CustomScrollView,使用keframe时,发现从一个CustomScrollView 切换到另一个CustomScrollView时, 列表会从底部快速往上滑动很多位置.
就是切换CustomScrollView时,发现列表位置变了, 去掉keframe后,正常了.
代码有点复杂, 涉及到好多文件, 贴不出来, 大佬 抹黑猜猜啥原因?
感谢大佬指点指点
因为image.net是异步加载的,所以即使分帧中调用了setState,image网络图片加载完成后仍会异步的调用Image组件的setState,大量图片加载完成后的调度仍是未分帧的,仍然是卡顿,此时keframe的作用基本没有效果,不知道是不是我的用法不对还是理解有误?
项目有两种列表样式,当切换列表后,有时候FrameSeparateWidget的占位 widget 没有消失,必须滑动一下才会消失。
使用了本插件后,性能得到了很大的提升,有原本的40+提升到了55+。
但是好像也带来了个新问题,使用了本插件后,在动态(朋友圈)场景下内存爆增,我不清楚是不是我的代码问题还是插件的特性。
通过调试发现好像在item==1的时候,整个列表的组件全部被加载出来了,并且用户通过滑动移动时,item移出视口外内存没有得到释放,用户通过上拉持续获取新的数据,当列表加载至百条时,内存就撑不住了。
比如SliverGrid
我看实现是,addPostFrameCallback 后setState加载,相当于是移到第二帧去build,但是如果我们这里连续5帧都是高耗时的呢?能否控制移到第6帧去加载,或者第x帧等
错误提示是:
======== A RenderSliverToBoxAdapter expected a child of type RenderBox but received a child of type RenderSliverList. RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.
尊重你我的时间
日志信息通过如下当时获取:
请将 keframe 的依赖改为分支
对于空安全之后的版本使用 debug
,非空安全使用 debug-before-null-safe
,这两个分支代码与非 debug 版没有任何区别,仅仅增加了一些日志信息。
之后运行你的程序,在 logcat 中筛选 BKFrame
关键字,粘贴到一个文件中。
我会尽快抽空回复,如果有不方便公开展示。
可以发到我的邮箱 [email protected] 中,
或者直接在我的公众号:进击的flutter 私聊我。
Hope this works :)
NewsStack
is a page containing NewsStackBody
and NewsStackMore
.
NewsStackBody
contains a list of FrameSeparatedWidget
where its child is NewsStackCard
NewsStackCard
is a widget that renders a FrameSeparateWidget
based on switch case
NewsStackMore
acts like a suggestion list, when clicked, it pushes the navigator to a new instance of NewsStack
The problem here is that, during the initial open of NewsStack
(from home page) everything loads perfectly, however, when opening another NewsStack
page by clicking on NewsStackMore
, the FrameSeparateWidget
seems to always be stuck in the placeholder
widget.
The code here is not entirely accurate, more of a pseudocode, but the main idea here is that, on initial open, nested FrameSeparateWidget
s work fine, when there are more layers, it gets stuck in placeholder.
Things i tried:
FrameSeparateWidget
, I tried using only one layer. Same thing happens, just takes slightly lesser time to loadNewsStack() =>
return Scaffold(
body: CustomScrollView(
slivers: [
NewsStackBody(),
NewsStackMore(),
],
),
);
NewsStackBody() =>
for (var content in list)
return FrameSeparateWidget(
placeHolder: customPlaceholder(),
child: NewsStackCard(),
);
NewsStackCard()=>
case (a) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetA(),
case (b) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetB(),
Just update your flutter to latest 3.0.0 release
/D:/flutter/.pub-cache/hosted/pub.dartlang.org/keframe-2.0.6/lib/src/frame_separate_task.dart:43:63: Warning: Operand of null-aware operation '!' has type 'SchedulerBinding' which excludes null.
- 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/D:/flutter/packages/flutter/lib/src/scheduler/binding.dart').
priority: entry.priority, scheduler: SchedulerBinding.instance!)) {
^
/D:/flutter/.pub-cache/hosted/pub.dartlang.org/keframe-2.0.6/lib/src/frame_separate_task.dart:89:28: Warning: Operand of null-aware operation '!' has type 'SchedulerBinding' which excludes null.
- 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/D:/flutter/packages/flutter/lib/src/scheduler/binding.dart').
await SchedulerBinding.instance!.endOfFrame;
^
/D:/flutter/.pub-cache/hosted/pub.dartlang.org/keframe-2.0.6/lib/src/frame_separate_widget.dart:71:22: Warning: Operand of null-aware operation '!' has type 'SchedulerBinding' which excludes null.
- 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/D:/flutter/packages/flutter/lib/src/scheduler/binding.dart').
SchedulerBinding.instance!.addPostFrameCallback((Duration t) {
^
点 setState增加20
按钮,_FrameSeparateWidgetState didUpdateWidget会被调用,此时 result 有可能已经是 oldWidget 的child,按分帧渲染
的理论是不是应该再重走一次 initState()中的逻辑? 目前是会先build oldWidget.child 再被transformWidget setState 替换为 widget.child
另外,_SizeCacheWidgetState 里的 NotificationListener 用法有误,泛型加上 LayoutInfoNotification 即可,NotificationListener 在调用 onNotification 时会先判断类型
@@ -44,15 +44,12 @@ class _SizeCacheWidgetState extends State<SizeCacheWidget> {
Widget build(BuildContext context) {
return Builder(
builder: (ctx) {
- return NotificationListener(
- onNotification: (dynamic notification) {
- if (notification is LayoutInfoNotification) {
- logcat(
- "size info : index = ${notification.index} size = ${notification.size.toString()}");
- saveLayoutInfo(notification.index, notification.size);
- return true;
- }
- return false;
+ return NotificationListener<LayoutInfoNotification> (
+ onNotification: (LayoutInfoNotification notification) {
+ logcat(
+ "size info : index = ${notification.index} size = ${notification.size.toString()}");
+ saveLayoutInfo(notification.index, notification.size);
+ return true;
},
child: widget.child,
);
使用如题的属性或者布局以后,列表是从中间往两边进行渲染
不知怎么上传视频
作者可以加个shrinkWrap试试效果
After using SizeCacheWidget and FrameSeparateWidget, UI-related instances such as widgets and elements are not released.
Remove SizeCacheWidget and only use FrameSeparateWidget. UI-related instances can be recycled normally.
在使用 SizeCacheWidget 和 FrameSeparateWidget 后,widget、element 等 UI相关的实例没有释放。如图一
去掉 SizeCacheWidget,只使用 FrameSeparateWidget。UI相关的实例可以正常被回收。如图二
The boost optimize for Key frame is amazing, but can be push to upstream?
Any thought push the optimize to flutter/flutter upstream?
I guess coding is easy ,but let it compatiable with all flutter version is hard .
场景是类似贴吧的一个listview,有很多帖子,如果帖子高度不高的话没有问题
但是如果有两篇帖子高度大于屏幕高度,这个时候可以向下滑动加载,但是想返回向上滑的时候就会卡住了。
一只不停的闪动,甚至会反向向下滑动。
如果需要演示视频,可以留一个邮箱,我发给您。
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
I/flutter ( 6453): ══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════
I/flutter ( 6453): [exception: Null check operator used on a null value]
I/flutter ( 6453): [library: Flutter framework]
I/flutter ( 6453): [stack: #0 RenderViewportBase.hitTestChildren (package:flutter/src/rendering/viewport.dart:727:26)
I/flutter ( 6453): #1 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #2 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #3 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #4 RenderIgnorePointer.hitTest (package:flutter/src/rendering/proxy_box.dart:3618:31)
I/flutter ( 6453): #5 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #6 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #7 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #8 RenderProxyBoxWithHitTestBehavior.hitTest (package:flutter/src/rendering/proxy_box.dart:183:19)
I/flutter ( 6453): #9 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #10 RenderProxyBoxWithHitTestBehavior.hitTest (package:flutter/src/rendering/proxy_box.dart:183:19)
I/flutter ( 6453): #11 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #12 RenderProxyBoxWithHitTestBehavior.hitTest (package:flutter/src/rendering/proxy_box.dart:183:19)
I/flutter ( 6453): #13 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #14 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #15 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #16 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #17 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #18 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #19 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:135:19)
I/flutter ( 6453): #20 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2511:11)
I/flutter ( 6453): #21 RenderSliverHelpers.hitTestBoxChild. (package:flutter/src/rendering/sliver.dart:1669:22)
I/flutter ( 6453): #22 BoxHitTestResult.addWithOutOfBandPosition (package:flutter/src/rendering/box.dart:902:31)
I/flutter ( 6453): #23 RenderSliverHelpers.hitTestBoxChild (package:flutter/src/rendering/sliver.dart:1666:19)
I/flutter ( 6453): #24 RenderSliverMultiBoxAdaptor.hitTestChildren (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:564:11)
I/flutter ( 6453): #25 RenderSliver.hitTest (package:flutter/src/rendering/sliver.dart:1287:11)
I/flutter ( 6453): #26 SliverHitTestResult.addWithAxisOffset (package:flutter/src/rendering/sliver.dart:858:31)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.