본문 바로가기
카테고리 없음

flutter 개발시 주의할 코드 (성능, 안정성, 유지보수)

by lifechecking 2025. 3. 12.
반응형

flutter 개발시 주의할 코드

 

Flutter 개발을 할 때 잘못된 코드 패턴을 사용하면 앱 성능 저하, 유지보수의 어려움, 심각한 버그등 많은 문제를 야기할 수 있습니다. 특히 성능 최적화와 안정성을 고려하지 않은 코드 작성은 앱 실행 속도를 늦추고, 사용자의 경험을 저하시켜 앱 접근성을 낮추는 주요 원인이 될 수 있습니다. 이번 글에서는 Flutter 개발자가 반드시 피해야 할 사용 금지 코드를 정리하여 안정적이고 효율적인 앱을 개발하는 데 도움을 드리겠습니다.

1. setState() 남용 – 불필요한 reBuild 유발

Flutter에서 setState()는 UI를 갱신하는 중요한 기능이지만, 이를 과도하게 사용하면 성능 저하를 초래할 수 있습니다. setState()가 호출되면 해당 위젯과 그 하위 위젯이 다시 빌드되므로, 불필요한 성능 낭비를 유발할 수 있습니다.

 

❌ 이렇게 사용하면 안 됩니다.


class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Count: $counter'),
        ElevatedButton(
          onPressed: () {
            setState(() {
              counter++;
            });
          },
          child: Text('Increment'),
        ),
      ],
    );
  }
}

 

위 코드는 setState()가 호출될 때마다 전체 위젯이 다시 빌드되어 비효율적입니다.

 

✅ 이렇게 개선하세요.


class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => CounterProvider(),
      child: Column(
        children: [
          Consumer(
            builder: (context, counter, child) => Text('Count: ${counter.value}'),
          ),
          ElevatedButton(
            onPressed: () {
              Provider.of(context, listen: false).increment();
            },
            child: Text('Increment'),
          ),
        ],
      ),
    );
  }
}

class CounterProvider with ChangeNotifier {
  int _value = 0;
  int get value => _value;

  void increment() {
    _value++;
    notifyListeners();
  }
}

 

이렇게 Provider를 활용하면 불필요한 setState() 호출 없이 원하는 특정 위젯만 리빌드 할 수 있습니다.

2. 무거운 위젯을 리스트에 직접 사용 – 성능 저하 유발

리스트뷰에서 많은 아이템을 직접 생성하는 경우, 불필요한 메모리 사용이 증가하여 성능 문제가 발생할 수 있습니다.

 

❌ 이렇게 사용하면 안 됩니다.


ListView(
  children: List.generate(1000, (index) => MyCustomWidget(index)),
);

 

이 방식은 리스트의 모든 항목을 한 번에 메모리에 로드하기 때문에 메모리 낭비가 매우 심합니다.

 

✅ 이렇게 개선하세요.


ListView.builder(
  itemCount: 1000,
  itemBuilder: (context, index) => MyCustomWidget(index),
);

 

ListView.builder는 필요한 항목만 동적으로 생성하기 때문에 성능 개선에 많은 도움을 줍니다.

3. FutureBuilder에서 불필요한 API 호출 – 과부하 발생

FutureBuilder를 사용할 때 API 호출을 잘못하면, 동일한 API 요청이 여러 번 호출되어 과도한 API 호출을 일으킬 수 있습니다.

 

❌ 이렇게 사용하면 안 됩니다.


FutureBuilder(
  future: fetchData(), // 매번 빌드될 때마다 API 호출됨
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    } else if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    } else {
      return Text('Data: ${snapshot.data}');
    }
  },
);

 

이 방식은 위젯이 리빌드될 때마다 fetchData()가 다시 호출됩니다.

 

✅ 이렇게 개선하세요.


class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State {
  late Future _futureData;

  @override
  void initState() {
    super.initState();
    _futureData = fetchData(); // 한 번만 API 호출
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _futureData,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return Text('Data: ${snapshot.data}');
        }
      },
    );
  }
}

 

이렇게 하면 fetchData()가 한 번만 실행되므로 불필요한 API 호출을 미리 방지할 수 있습니다.

결론

Flutter 개발을 할 때는 성능과 유지보수를 고려하여 최적화된 코드를 작성하는 것이 매우 중요합니다. 이를 위해,

  • setState() 남용을 피하고 Provider 같은 상태 관리 도구를 활용하여 개발하세요.
  • ListView.builder를 사용하여 메모리 낭비를 줄여보세요.
  • FutureBuilder에서 API 호출을 최적화하여 불필요한 요청을 미리 방지하세요.

이러한 금지 코드 패턴을 피하고 올바른 개발 방법을 적용하면, Flutter 앱의 성능을 개선하고 유지보수성을 높일 수 있습니다.

반응형