Flutter 애플리케이션 개발에서의 성능 향상 Tips

Fluter 응용 프로그램의 성능을 개선하기 위해서, 구체적으로 무엇을 할 수 있는지 열거해 보았다.

GridView의 shrinkWrap을 정말로 설정하지 않음


shrinkWrap에는 다음과 같은 설명이 있습니다.
스크롤 보기에 수축 필름이 없으면 스크롤 보기는 스크롤 다이렉션이 허용하는 최대 사이즈로 확장됩니다.
스크롤 보기의 scrollDirection에 무한한 제한이 있다면 shrinkWrap은 진짜여야 합니다.
스크롤 보기의 내용을 수축 처리하는 것은 스크롤 보기의 내용을 최대 수용 가능한 크기로 확장하는 것보다 더 많은 비용을 들인다.
내용이 스크롤 중에 확대되고 축소될 수 있기 때문이다.즉, 스크롤 위치가 바뀔 때마다 스크롤 보기의 크기를 다시 계산해야 한다.
원소수가 가변적이라면 GridView.builder와 배치에 따라 유연하게 활용할 수 있다SliverGrid.
shrinkWrap을 가짜로 만들기 위해서는 넘치지 않도록 주의해야 한다.
GridView.builder(
    shrinkWrap: false,
    itemCount: _itemCount,
    gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
      maxCrossAxisExtent: 100.0,
      crossAxisSpacing: 16,
      mainAxisSpacing: 16,
      childAspectRatio: 1 / 2,
    ),
    itemBuilder: (BuildContext context, int index) {
      return Text('index: $index');
    }
),
API 등을 통해 얻은 가변 길이 데이터는 다음과 같이 나타나면 스크롤의 느슨함과 fps의 감소를 초래할 수 있다.

GridView.count(
  shrinkWrap: true,
  crossAxisCount: 3
  children: _apiResults(), // API 結果によって可変長のWidgetを表示する
),

이미지 캐시


메모리에 대한 부하를 줄이기 위해 네트워크를 통해 얻은 이미지는 캐시를 사용할 수 있습니다.
cached_network_image 간단한 IF를 추천합니다.

CachedNetworkImage(
  imageUrl: "http://via.placeholder.com/350x150",
  placeholder: (context, url) => CircularProgressIndicator(),
  errorWidget: (context, url, error) => Icon(Icons.error),
),

재구축할 필요가 없는 Widget에 const 설치

TextEdgeInsets는 다양한 기능이 있는데 상수만 나타내는 역할도 있다고 생각합니다.
이런 상황에서 const를 더하면 재건축이 없다는 것을 명확히 할 수 있기 때문에 충분히 이용해야 한다.

Container(
  child: const Text('hoge')
),

재구성된 Widget 최소화


statefulWidgetsetState을 사용하면 State를 유지하는 모든 Widget이 재구성됩니다.
따라서 다시 그려야 할 Widget만 다시 그리려면 StreamBuilder 를 사용하십시오.
상태 관리 방법에는 여러 가지 방법이 있습니다공식 페이지.
다음은 Fluter를 사용하여 프로젝트를 만들 때 기본적으로 적용된 수정 버전StreamController입니다.
전체 항목을 참조하려는 사람은 샘플 항목를 참조하십시오.
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  final StreamController<int> _streamController = StreamController<int>();

  void _incrementCounter() {
    // setState(() {
    //   _counter++;
    // });

    _counter++;
    _streamController.sink.add(_counter);
  }

  
  void dispose() {
    _dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            StreamBuilder(
              stream: _streamController.stream,
              builder: (BuildContext context, snapshot) {
                return Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  void _dispose() {
    _streamController.close();
  }

}

analysis_options.설정


성능을 직접 개선할 수는 없지만, Linter 설정을 통해 이상적인 코드가 되고, 결과적으로 성능 개선으로 이어질 수 있다.
const를 사용하고 불필요한 import을 피하는 것이 큰 도움이 됐다고 지적할 수 있습니다.
설정 방법은 매우 간단하다. pubspec.yaml의 같은 층의 설정 파일analysis_options.yaml만 있으면 된다.
Linter의 규칙적인 내용이지만 제 경우는 공식화의analyysis입니다.options.yaml 참고했어요.

참고 자료


Flutter 성능 향상
Stateful Widget의 성능을 고려한 올바른 처리 방법

좋은 웹페이지 즐겨찾기