Çok basit bir yol ile Flutter'da ram kullanımını azaltmak

Mirkan
Flutter İzmir
Published in
2 min readMay 25, 2022

--

Uzun zamandır Flutter’la uğraşsam da Sentry’de pek crash görmediğimden performans ve memory optimizasyonu yapmaya, DevTool ile bakmaya pek vakit ayırmadım. Fakat yeni tasarımcının çok yüksek çözünürlüklü görseller yapması ve yeni reklam kampanyasiyla çok fazla kullanıcının app’e gelmesiyle 750 kullanıcıdan 1500 crash gördüm 2 günde.

Olaya gelirsek,

Misal siz 2000x1500 çözünürlükte bir görsel kullanıyorsunuz, nereden baksanız 6–8 mb. Fakat sadece thumbnail göstermek istiyorsunuz, constrainedbox, sizedbox, container kullanarak bir şekilde resmi 100x75 şeklinde ekrana koydunuz.

DevTools, memory view. Allocated memory uzaya giderken, crash yemeden önceki son saniyeler

Fakat Flutter’ın renderer’ı bu resmi tam çözünürlükte cache’liyor,
ve evet, cached_network_image kullanmasanız da cacheleniyor.

200 adet bu boyutlarda görseller kullandınız, 6mb’tan 1.2 gb ram tüketildi. misal bir IMDB tarzı veya Spotify gibi bir uygulamadan bir sayfa, veya kullanıcı listesi çok fazla görsel barındırabilir.

iPhone 12 Pro Max’te bile, 800 kullanıcılık listeyi kaydırdığımda 1gb 2gb derken 3'e gelirken crash atıyordu.

Peki nasıl optimize ediyoruz?

Öncelikle bu görselleri saptamamız lazım. App widget'ında, build methodunda, return material app demeden önce(ya da ne return ediyorsanız), şunu ekleyin:

debugInvertOversizedImages = true

Bu çizdiğinden fazla memory’de piksel kullanan resimleri hem ters çeviriyor, hem de renkleri ters yüz ediyor, böylece görüyorsunuz. hem de konsola:

Image null has a display size of 990×603 but a decode size of 6943×3454, which uses an additional 121792KB. Consider resizing the asset ahead of time, supplying a cacheWidth parameter of 990, a cacheHeight parameter of 603, or using a ResizeImage.

şeklinde hata mesajı düşürüyor. O hata da zaten cacheHeight, cacheWidth parametresine bu değerleri verin yazıyor.

bu arada 121792KB kısmına dikkat, 120 mb’lık tek resim geliyor 😅 bu uygulamanın backend'ini yazanlar da suyunu çıkarmış.

Image.asset(
‘assets/splash.png’,
cacheheight: 150,
cachewidth: 150,
),

şeklinde o değerleri verin. Image.networkiçin de aynı. CachedNetworkImageiçinse, parametreler memCacheHeight, memCacheWidth şeklinde.

Ben yine biraz daha büyük ekranlarda, responsive widgetlar içindeki görseller küçük gözükür diye bazı yerlerde değerleri 2 ile çarptım.

Sonuç olarak devtools’un memory allocation kısmından baktığımda allocated memory 3gb’tan 300mb’lara düştü.

değişikliklerden sonra aynı sayfa, ve aynı liste tamamen kaydırıldı👍

--

--