Flutter optimization of splitting widgets into methods will affect rendering performance

 

Everyone is welcome to pay attention to the [ cross-platform development those things ] public account , and regularly push the practice of cross-platform development technology.

In the React Native cross-platform development box, we often see that when the interface component level is deeply nested and the component interaction involves business logic, in order to concise and clear the code level, the component will be split into methods, and then in the main layout Introduced in, for example:

render() {
  return (
      <View style={{ flex: 1, backgroundColor: Color.white }}>
           <NavBar />
         { this. this._renderContent() }
      </View>
  )
}

Due to the complexity of the content, we abstracted the business logic and UI display into the method.

Many friends have a common complaint after contacting with Flutter development, that is, this layout is too difficult to write, and a simple layout must be nested in many layers. So many developers will split it into methods, and have seen some open source projects also use this method before, so is this method applicable in Flutter?

Problem display

For example, there is the following piece of code:

@override
Widget build(BuildContext context) {
  return Scaffold(
	body: Center(
	  child: Column(
	    mainAxisAlignment: MainAxisAlignment.center,
	    children: <Widget>[
	      Text(
	        widget.title,
	      ),
	      Center(
	        child: Text(result,)
	      ),
	      Row(
	        children: [
		      MaterialButton(
		        color: Theme.of(context).primaryColor,
		        child: Text("1", style: TextStyle(color: Colors.white)),
		        onPressed: () => onPressCallback('startActivity'),
		      ),
		      ......
	        ]
	      )
	    ],
	  ),
	),
  );
}

When I first saw the UI code of Flutter, some friends might feel that the nesting level is a bit crazy. Since widgets may be a bit templated, the first solution that comes to mind is to split the nested parts into separate methods. At this point you will have the following code:

@override
Widget build(BuildContext context) {
  return Scaffold(
	body: Center(
	  child: Column(
	    mainAxisAlignment: MainAxisAlignment.center,
	    children: <Widget>[
	      Text(
	        widget.title,
	      ),
	      Center(
	        child: Text(result,)
	      ),
	      this._buildRowBtnWidget() // 拆分为组件方法
	    ],
	  ),
	),
  );
}

/**
 * 组件方法模块
 */
Widget _buildRowBtnWidget() {
  return Row(
	children: [
	  MaterialButton(
		color: Theme.of(context).primaryColor,
		child: Text("1", style: TextStyle(color: Colors.white)),
		onPressed: () => onPressCallback('startActivity'),
	  ),
	  ......
	]
  )
}

At this time it looks very beautiful, so will there be any problems with this writing?

The way to split widgets into methods, at first glance, it makes sense to split long build methods into small functions. In fact, we should not do this. Assuming that there is currently a state value num, whenever we trigger num data update through setState (), _buildRowBtnWidget () will be called, which will cause the widget tree to be rebuilt again and again. The components in _buildRowBtnWidget () do not need to be updated and displayed, that is, stateless component modules. When the application is more complex, there will be a significant rendering performance impact (CPU scheduling).

Optimization

Flutter create components into two ways: stateful (StatefulWidget)  & stateless (StatelessWidget)  components. So instead of splitting the build methods into smaller methods, we split them into stateless widgets, namely: StatelessWidgets. Let's take a look at the code after refactoring:

@override
Widget build(BuildContext context) {
  return Scaffold(
	body: Center(
	  child: Column(
	    mainAxisAlignment: MainAxisAlignment.center,
	    children: <Widget>[
	      Text(
	        widget.title,
	      ),
	      Center(
	        child: Text(result,)
	      ),
	      const _RowBtnWidget() // 拆分为组件方法
	    ],
	  ),
	),
  );
}

/**
 * 组件
 */
class _RowBtnWidget extends StatelessWidget {

  const _RowBtnWidget();

  @override
  Widget build(BuildContext context) {
	return Row(
	  children: [
		MaterialButton(
		  color: Theme.of(context).primaryColor,
	      child: Text("1", style: TextStyle(color: Colors.white)),
		  onPressed: () => onPressCallback('startActivity'),
		),
		......
	  ]
	)
  }
}

It can be seen that the above code is much more "bloated" than split into methods, but this _RowBtnWidget will only be built once, reducing the performance overhead of unnecessary component reconstruction. 

in conclusion

When creating stateless components, we split them into StatelessWidgets. Reduce the performance overhead of rebuilding static widgets. In optimizing the performance of the Flutter application, it is also a very simple optimization method.

Published 214 original articles · praised 371 · 920,000 views

Guess you like

Origin blog.csdn.net/u013718120/article/details/85209616