Flutter'da Performans Optimizasyonu 2026: Impeller, Yeniden Oluşturmalar ve En İyi Uygulamalar
Flutter uygulamalarını 2026'da Impeller, disiplinli widget yeniden oluşturmaları, RepaintBoundary ve DevTools profillemesiyle sabit 60 veya 120 fps'de tutmanın yolu.

Flutter'da 2026'da performans optimizasyonu, akıcı uygulamaların nasıl kurulduğunu değiştiren iki dönüşüme dayanır: Impeller render motoru artık iOS ve Android'de varsayılan olarak gelir ve framework'ün yeniden oluşturma modeli, widget ağaçlarını küçük ve değişmez tutan geliştiricileri ödüllendirir. Her iki kaldıraçtan da yararlanan ekipler, her kareyi elle ayarlamadan sabit 60 veya 120 fps'yi korur.
Çoğu Flutter uygulamasındaki en büyük kazanç, const yapıcılar eklemek ve büyük build yöntemlerini bölmektir; böylece bir setState çağrısı tüm ekran yerine tek bir düğmeyi yeniden çizer.
Impeller, Flutter performans referansını neden yeniden belirliyor
Impeller, Flutter'ın render motorudur ve mobil platformlarda varsayılan olarak Skia'nın yerini almıştır. Fark en çok bir animasyonun ilk saniyelerinde önemlidir. Skia, shader'larını tam zamanında, belirli bir efekt ekranda ilk kez göründüğünde derliyordu; bu da Flutter uygulamalarının eleştirildiği o meşhur ilk çalıştırma takılmasını üretiyordu. Impeller bu shader'ları önceden, derleme sırasında derler; böylece bir animasyonun ilk karesi yüzüncüsü kadar akıcıdır.
Impeller ayrıca doğrudan modern grafik API'lerini hedefler: iOS'ta Metal, Android'de Vulkan ve eski Android donanımı için OpenGL yedeği. GitHub'daki Impeller motoru belgeleri render mimarisini ve platform destek matrisini ayrıntılı olarak anlatır.
| Yön | Skia (eski) | Impeller (2026 varsayılanı) | |--------|---------------|-------------------------| | Shader derlemesi | Çalışma zamanında, ilk çalıştırmada takılmaya neden olur | Önceden, derlemede | | iOS arka ucu | OpenGL / Metal | Metal | | Android arka ucu | OpenGL | Vulkan, OpenGL yedeği | | İlk animasyonun akıcılığı | Ara sıra takılma | Sabit |
Çoğu proje için geçiş bedavadır: Yeni Flutter sürümleri Impeller'ı otomatik olarak etkinleştirir ve eski shader ısıtma geçici çözümleri (--purge-persistent-cache, paketlenmiş .sksl dosyaları) artık gerekli değildir ve silinebilir. Flutter'ın desteklediği GLSL alt kümesine göre yazılmış özel FragmentProgram shader'ları da çalışmaya devam eder, çünkü Impeller bunları framework'ün kendi efektleriyle aynı çevrimdışı işlem hattından derler.
Bir uygulamanın hangi motorda çalıştığını doğrulamak tek satır alır: bir hata ayıklama derlemesi başlangıçta etkin arka ucu yazdırır ve DevTools denetçisi bunu uygulamanın render ayrıntılarında bildirir. Impeller doğrulandıktan sonra kalan performans işi, framework'ün ekranın gerçekte değiştiğinden çok daha sık yeniden oluşturduğu widget katmanına yükselir. Bu kılavuzun geri kalanı buna odaklanır, çünkü hızlı bir motor, kendini saniyede yüzlerce kez yeniden çizen bir widget ağacını kurtaramaz.
const ve widget bölme ile Flutter yeniden oluşturmalarını azaltma
Her setState, widget'ını kirli olarak işaretler ve o eleman ile alt ağacı için build'i yeniden çalıştırır. İşin sırrı, o alt ağacı olabildiğince dar tutmaktır. İki alışkanlık işin çoğunu yapar: statik widget'ları const olarak işaretlemek ve durumu aşağıya iterek durumlu kısmı küçük tutmak.
Bir const widget tek bir örneğe kanonikleştirilir; böylece bir ebeveyn yeniden oluştuğunda Flutter aynı referansı karşılaştırır, hiçbir değişiklik görmez ve o dalın yeniden çizilmesini tamamen atlar.
// A cart update repaints the badge, not the header.
class ProductScreen extends StatefulWidget {
const ProductScreen({super.key});
State<ProductScreen> createState() => _ProductScreenState();
}
class _ProductScreenState extends State<ProductScreen> {
int _cartCount = 0;
Widget build(BuildContext context) {
return Column(
children: [
const ProductHeader(), // const: never rebuilds on setState
CartBadge(count: _cartCount), // only this subtree rebuilds
FilledButton(
onPressed: () => setState(() => _cartCount++),
child: const Text('Add to cart'),
),
],
);
}
}analysis_options.yaml içinde prefer_const_constructors lint'ini etkinleştirmek bu disiplini bir derleyici denetimine dönüştürür; böylece const fırsatları asla sessizce geri gitmez. İlgili prefer_const_literals_to_create_immutables kuralı aynı garantiyi widget'lara geçirilen listelere ve haritalara genişletir.
Widget anahtarları da burada anılmayı hak eder. Bir liste yeniden sıralandığında ya da bir widget aynı türü korurken kimliği değiştiğinde, bir ValueKey veya ObjectKey, Flutter'ın eski elemanı doğru yeni widget örneğiyle eşleştirmesini sağlar; durumu yıkıp yeniden oluşturmak yerine. Anahtar eksikliği, dinamik listelerde kayan konum kaybının ve sıfırlanan animasyonların yaygın bir nedenidir ve neden olduğu ek yeniden oluşturma işini gözden kaçırmak kolaydır.
Yeniden oluşturmaları değişen veriyle sınırlama
Durum ağacın yukarısında yaşadığında, iyi bölünmüş bir düzen bile çokça yeniden oluşur. Çözüm, bir değeri yayınlamak ve tek bir widget'ın onu dinlemesine izin vermektir. Flutter, tam bu amaçla ValueNotifier ve ValueListenableBuilder sağlar; harici bir paket gerekmez.
// A scroll-to-top button that rebuilds alone, not the whole page.
class ArticleList extends StatefulWidget {
const ArticleList({super.key});
State<ArticleList> createState() => _ArticleListState();
}
class _ArticleListState extends State<ArticleList> {
final _showFab = ValueNotifier<bool>(false);
final _controller = ScrollController();
void initState() {
super.initState();
// Update the notifier, not setState: the list never rebuilds
_controller.addListener(() => _showFab.value = _controller.offset > 400);
}
void dispose() {
_showFab.dispose();
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
controller: _controller,
itemCount: 200,
itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
),
floatingActionButton: ValueListenableBuilder<bool>(
valueListenable: _showFab,
builder: (_, visible, __) => visible
? FloatingActionButton(
onPressed: () => _controller.jumpTo(0),
child: const Icon(Icons.arrow_upward),
)
: const SizedBox.shrink(),
),
);
}
}Durum yönetimi kütüphaneleri aynı fikri genelleştirir. Riverpod'un ref.watch(provider.select(...)) ifadesi ve Provider'ın Selector widget'ı yalnızca durumun seçilen bir dilimi değiştiğinde yeniden oluşur; bu da veri yoğun ekranlarda akıcı ile takılmalı arasındaki belirleyici etkendir. Bu kütüphaneler arasındaki ödünleşimler Flutter'da 2026'da durum yönetimi kılavuzunda ele alınır.
Bir ekranın köküne yakın setState çağırmak ya da tüm bir sayfayı üst düzey bir Consumer içine sarmak, her değişiklikte sessizce yüzlerce widget'ı yeniden çizer. Bir ekranın ucuz olduğunu varsaymadan önce DevTools'taki yeniden oluşturma sayacıyla profil çıkarın.
Flutter mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Pahalı yeniden çizimleri RepaintBoundary ile izole etme
Yeniden oluşturmak ve yeniden çizmek ayrı aşamalardır. Bir widget yeniden oluşturmayı atlayıp yine de yeniden çizilebilir, çünkü gürültülü bir komşu onun katmanını paylaşır. RepaintBoundary bir alt ağaca kendi katmanını verir; böylece animasyonlu bir grafik, statik kartları her karede yeniden çizmeye zorlayamaz.
// The live chart repaints on its own layer, cards stay untouched.
class Dashboard extends StatelessWidget {
const Dashboard({required this.ticker, super.key});
final Stream<double> ticker;
Widget build(BuildContext context) {
return Column(
children: [
// SummaryCards is static, so isolate it from the animation below
const RepaintBoundary(child: SummaryCards()),
RepaintBoundary(
child: StreamBuilder<double>(
stream: ticker,
builder: (_, snap) => LivePriceChart(value: snap.data ?? 0),
),
),
],
);
}
}RepaintBoundary bedava değildir: her biri bir katman ayırır, bu yüzden onu her yere serpiştirmek yardımdan çok zarar verir. Gerçekten animasyonlu bölgeler ve uzun kaydırılan listeler için kullanın ve kazancı zaman çizelgesinde doğrulayın. RepaintBoundary API başvurusu hata ayıklama yeniden çizim katmanının hangi katmanların gerçekten yeniden çizildiğini nasıl vurguladığını belgeler.
build yöntemini ucuz ve yan etkisiz tutma
Bir build yöntemi her yeniden oluşturmada çalışır, bu yüzden içindeki pahalı her şey çoğalır. Kural, build'in durumu okuyup widget döndürmesidir, fazlası değil. build içinde bir ScrollController, AnimationController veya Future ayırmak onu her karede yeniden oluşturur ve önceki örneği sızdırır. Bu nesneler initState'e ya da dispose içinde serbest bırakılan bir late final alana aittir.
Ağır senkron iş ikinci tuzaktır. build içinde JSON ayrıştırmak, büyük bir listeyi filtrelemek veya tarihleri biçimlendirmek, temeldeki veri değişmese bile bu işi her yeniden çizimde tekrar çalıştırır. Girdi değiştiğinde sonucu bir kez hesaplayıp önbelleğe alın ya da framework'ün onu beklerken bir kareyi engellememesi için bir FutureBuilder içine taşıyın. Başka değerlerden türetilen değerler için, bunları yalnızca bağımlılıkları değiştiğinde yeniden hesaplayan bir getter arkasında bellekleyin.
Opacity widget'ı adı anılmayı hak eden belirli bir suçludur. Bir alt ağacı Opacity içine sarmak ekran dışı bir saveLayer'ı zorlar; bu, işlem hattındaki en pahalı işlemlerden biridir. Bir solma animasyonu için AnimatedOpacity ya da bir FadeTransition daha ucuzdur ve sabit bir renk tonu için rengi bir foregroundDecoration veya shader aracılığıyla boya düzeyinde uygulamak katmandan tamamen kaçınır. Aynı dikkat, büyük yüzeylerde kenar yumuşatmalı ClipPath ve ClipRRect için de geçerlidir; bunlar da perde arkasında bir saveLayer tetikler.
Son olarak, const koleksiyonları ve her yapımda yeni kapanışlar yakalamayan geri çağırmaları tercih edin. Varsayılan olarak geçirilen bir const [] ve satır içi bir lambda yerine bir yöntem referansı, widget eşitlik denetimlerini ucuz tutar; bu da daha önce anlatılan const kısa devresinin gerçekten tetiklenmesini sağlar.
Uzun listeleri ve görselleri verimli oluşturma
Uzun akışlar ve görsel ızgaraları, saf Flutter kodunun kare düşürdüğü yerdir. İki kural çoğu durumu kapsar: satırları tembel oluşturmak ve görselleri kaynak çözünürlüğünde değil, gösterildikleri boyutta çözmek.
// Lazy rows plus right-sized image decoding keep scrolling at 60fps.
class Feed extends StatelessWidget {
const Feed({required this.posts, super.key});
final List<Post> posts;
Widget build(BuildContext context) {
return ListView.builder(
itemCount: posts.length, // build on demand, not all at once
cacheExtent: 600, // pre-build past the viewport edge
itemBuilder: (context, index) {
final post = posts[index];
return ListTile(
leading: Image.network(
post.thumbnailUrl,
width: 48,
height: 48,
cacheWidth: 96, // decode at display size, save memory
),
title: Text(post.title),
);
},
);
}
}48 piksellik bir avatara sıkıştırılmış tam çözünürlüklü 3000 piksellik bir görsel, her biri için bellek ve kod çözme süresi harcar. cacheWidth ayarlamak motora hedef boyutta çözmesini söyler; bu tek başına bir listenin bellek ayak izini bir büyüklük derecesi azaltabilir. Flutter'ın performans en iyi uygulamaları aynı ilkeyi izleyen Opacity, saveLayer ve kırpma kullanımına dair daha fazla rehberliği bir araya getirir.
2026'da Flutter optimizasyonunu DevTools ile ölçme
Yukarıdaki her kural varsayılmamalı, doğrulanmalıdır. Flutter DevTools gerçeğin kaynağıdır. Performans katmanı (hata ayıklama konsolunda P ya da flutter run --profile) iki grafik çizer, UI ve raster, ve yeşil çizgiyi aşan her çubuk düşen bir karedir. Zaman çizelgesi görünümü sonra her yavaş kareyi belirli bir build, düzen veya boyama çağrısına atfeder.
Her zaman fiziksel bir cihazda --profile modunda profil çıkarın. Hata ayıklama derlemeleri optimize edilmemiş Dart çalıştırır ve her ölçümü şişirir; bu yüzden hata ayıklamada takılan bir ekran çoğu zaman derlendikten sonra kusursuz çalışır. DevTools performans kılavuzu kare grafiğini okumayı ve takılma kaynaklarını saptamayı adım adım anlatır ve aynı profilleme kası Flutter animasyonları ve render üzerine mülakatlarda da ortaya çıkar.
Profile modunda çalıştırın, takılan etkileşimi yeniden üretin, zaman çizelgesini açın ve kareleri süreye göre sıralayın. En kötü kare neredeyse her zaman tek bir aşırı büyük yeniden oluşturmaya ya da önbelleğe alınmamış bir görsele işaret eder; bu, tahmin etmekten çok daha hızlıdır.
Flutter teknoloji merkezi, üretim düzeyinde bir performans stratejisini tamamlayan durum yönetimi, test ve render konularını birbirine bağlar.
Sonuç
2026'da Flutter performansı, mikro numaralardan çok, tutarlı biçimde uygulanan kısa bir alışkanlık listesiyle ilgilidir:
- Impeller üzerinde dağıtın ve eski shader ısıtma kodunu silin; ilk kare takılması sorunu motor düzeyinde çözülmüştür.
- Statik widget'ları
constolarak işaretleyin ve bunuprefer_const_constructorslint'iyle zorunlu kılın. - Durumlu widget'ları küçük parçalara bölün, böylece her
setStatemümkün olan en dar alt ağacı yeniden çizer. - Değişen değerleri tüm ekranları yeniden oluşturmak yerine
ValueListenableBuilderya daselecttarzı bir API aracılığıyla yayınlayın. - Gerçekten animasyonlu bölgeleri bir
RepaintBoundaryiçine sarın, ama daha fazlasını eklemeden önce ölçün. - Listeleri
ListView.builderile oluşturun ve görsellericacheWidthkullanarak gösterim boyutunda çözün. - Gerçek donanımda
--profilemodunda profil çıkarın ve sırada neyi optimize edeceğinize sezgiye değil DevTools'a karar verdirin.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Etiketler
Paylaş
İlgili makaleler

Dart Isolates ve 2026'da Eşzamanlılık: compute, Async ve Mülakat Soruları
Flutter uygulamaları için Dart izolasyonları, compute fonksiyonu ve async kalıplarında uzmanlaşın. Eşzamanlılık modelleri, performans optimizasyonu ve kod örnekleriyle yaygın mülakat sorularını kapsar.

Flutter Durum Yönetimi: Riverpod vs BLoC - Kapsamlı Karşılaştırma Rehberi
Flutter durum yönetimi için Riverpod ve BLoC arasında derinlemesine karşılaştırma. Mimari, performans, test edilebilirlik ve en iyi çözümü seçmek için kullanım senaryoları.

Mobil Geliştiriciler İçin En Önemli 20 Flutter Mülakat Sorusu
Flutter mülakatlarına en sık sorulan 20 soruyla hazırlanın. Widget yapısı, state management, Dart, mimari ve en iyi uygulamalar detaylı şekilde açıklanmaktadır.