Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

L-utenti kollha jieħdu tnedija mgħaġġla u UI li tirreaġixxi fl-applikazzjonijiet mobbli bħala fatt. Jekk l-applikazzjoni tieħu żmien twil biex tniedi, l-utent jibda jħossu imdejjaq u rrabjat. Tista 'faċilment tħassar l-esperjenza tal-klijent jew titlef kompletament lill-utent anki qabel ma jibda juża l-applikazzjoni.

Darba skoprejna li l-app Dodo Pizza tieħu 3 sekondi biex titnieda bħala medja, u għal xi "xxurtjati" tieħu 15-20 sekonda.

Taħt il-qatgħa hemm storja bi tmiem kuntenti: dwar it-tkabbir tad-database Realm, tnixxija tal-memorja, kif akkumulajna oġġetti nested, u mbagħad ġibna lilna nfusna flimkien u ffissajna kollox.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila
Awtur tal-artikolu: Maxim Kachinkin — Żviluppatur Android f'Dodo Pizza.

Tliet sekondi minn meta tikklikkja fuq l-ikona tal-applikazzjoni għal onResume() tal-ewwel attività hija infinita. U għal xi utenti, il-ħin tal-istartjar laħaq 15-20 sekonda. Dan kif huwa anki possibbli?

Sommarju qasir ħafna għal dawk li m'għandhomx ħin biex jaqraw
Id-database tal-Isfera tagħna kibret bla tmiem. Xi oġġetti nested ma ġewx imħassra, iżda kienu kontinwament akkumulati. Il-ħin tal-istartjar tal-applikazzjoni żdied gradwalment. Imbagħad aħna rranġawha, u l-ħin tal-istartjar wasal għall-mira - sar inqas minn sekonda 1 u m'għadux żdied. L-artiklu fih analiżi tas-sitwazzjoni u żewġ soluzzjonijiet - waħda ta' malajr u waħda normali.

Tiftix u analiżi tal-problema

Illum, kull applikazzjoni mobbli trid titnieda malajr u tirreaġixxi. Imma mhux biss dwar l-app mobbli. L-esperjenza tal-utent ta 'interazzjoni ma' servizz u kumpanija hija ħaġa kumplessa. Pereżempju, fil-każ tagħna, il-veloċità tal-kunsinna hija waħda mill-indikaturi ewlenin għas-servizz tal-pizza. Jekk il-kunsinna tkun veloċi, il-pizza tkun sħuna, u l-klijent li jrid jiekol issa ma jkollux għalfejn jistenna ħafna. Għall-applikazzjoni, min-naħa tiegħu, huwa importanti li tinħoloq sensazzjoni ta 'servizz mgħaġġel, għaliex jekk l-applikazzjoni tieħu biss 20 sekonda biex titnieda, allura kemm se jkollok tistenna l-pizza?

Għall-ewwel, aħna stess konna ffaċċjati bil-fatt li kultant l-applikazzjoni kienet tieħu ftit sekondi biex titnieda, u mbagħad bdejna nisimgħu lmenti minn kollegi oħra dwar kemm damet. Imma ma stajniex nirrepetu din is-sitwazzjoni b’mod konsistenti.

Kemm hu twil? Skond Dokumentazzjoni Google, jekk bidu kiesaħ ta 'applikazzjoni jieħu inqas minn 5 sekondi, allura dan jitqies "bħallikieku normali". Tnediet l-app Dodo Pizza Android (skond il-metriċi ta' Firebase _app_start) fi bidu kiesaħ bħala medja fi 3 sekondi - "Mhux kbir, mhux terribbli," kif jgħidu.

Iżda mbagħad bdew jidhru lmenti li l-applikazzjoni damet ħafna, ħafna, ħafna żmien biex titnieda! Biex nibdew, iddeċidejna li nkejlu x'inhu "ħafna, ħafna, twil ħafna". U użajna Firebase traċċa għal dan App tibda traċċa.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Din it-traċċa standard tkejjel iż-żmien bejn il-mument li l-utent jiftaħ l-applikazzjoni u l-mument li jiġi esegwit l-onResume() tal-ewwel attività. Fil-Firebase Console din il-metrika tissejjaħ _app_start. Irriżulta li:

  • Il-ħinijiet tal-istartjar għall-utenti 'l fuq mill-95 perċentil huma kważi 20 sekonda (xi wħud saħansitra itwal), minkejja li l-ħin medjan tal-istartjar kiesaħ huwa inqas minn 5 sekondi.
  • Il-ħin tal-istartjar mhuwiex valur kostanti, iżda jikber maż-żmien. Imma kultant ikun hemm qtar. Sibna dan il-mudell meta żidna l-iskala tal-analiżi għal 90 jum.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Ġew f’moħħna żewġ ħsibijiet:

  1. Xi ħaġa qed tnixxi.
  2. Din "xi ħaġa" hija reset wara r-rilaxx u mbagħad tnixxi mill-ġdid.

"Probabbilment xi ħaġa mad-database," ħsibna, u kellna raġun. L-ewwelnett, nużaw id-database bħala cache; waqt il-migrazzjoni aħna nneħħiha. It-tieni nett, id-database titgħabba meta tibda l-applikazzjoni. Kollox jaqbel flimkien.

X'hemm ħażin fid-database Realm

Bdejna niċċekkjaw kif il-kontenut tad-database jinbidel matul il-ħajja tal-applikazzjoni, mill-ewwel installazzjoni u aktar waqt l-użu attiv. Tista 'tara l-kontenut tad-database Realm permezz stetho jew f'aktar dettall u b'mod ċar billi tiftaħ il-fajl permezz Realm Studio. Biex tara l-kontenut tad-database permezz tal-ADB, ikkopja l-fajl tad-database Realm:

adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME}

Wara li ħares lejn il-kontenut tad-database fi żminijiet differenti, sibna li n-numru ta 'oġġetti ta' ċertu tip qiegħed dejjem jiżdied.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila
L-istampa turi framment ta 'Realm Studio għal żewġ fajls: fuq ix-xellug - il-bażi tal-applikazzjoni xi żmien wara l-installazzjoni, fuq il-lemin - wara użu attiv. Wieħed jista 'jara li n-numru ta' oġġetti ImageEntity и MoneyType kibret b'mod sinifikanti (l-screenshot turi n-numru ta 'oġġetti ta' kull tip).

Relazzjoni bejn it-tkabbir tad-database u l-ħin tal-istartjar

It-tkabbir mhux ikkontrollat ​​tad-database huwa ħażin ħafna. Imma dan kif jaffettwa l-ħin tal-istartjar tal-applikazzjoni? Huwa pjuttost faċli li tkejjel dan permezz tal-ActivityManager. Minn Android 4.4, logcat juri r-reġistru bl-istring Displayed u l-ħin. Dan il-ħin huwa ugwali għall-intervall mill-mument li titnieda l-applikazzjoni sat-tmiem tar-rendi tal-attività. Matul dan iż-żmien iseħħu l-avvenimenti li ġejjin:

  • Ibda l-proċess.
  • Inizjalizzazzjoni ta' oġġetti.
  • Ħolqien u inizjalizzazzjoni ta 'attivitajiet.
  • Ħolqien ta 'tqassim.
  • Rendiment ta' applikazzjoni.

jaqbel lilna. Jekk tmexxi ADB bil-bnadar -S u -W, tista 'tikseb output estiż bil-ħin tal-istartjar:

adb shell am start -S -W ru.dodopizza.app/.MainActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAIN

Jekk taqbadha minn hemm grep -i WaitTime ħin, tista 'awtomatizza l-ġbir ta' din il-metrika u tħares viżwalment lejn ir-riżultati. Il-graff hawn taħt turi d-dipendenza tal-ħin tal-istartjar tal-applikazzjoni fuq in-numru ta 'startjar kiesaħ tal-applikazzjoni.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Fl-istess ħin, kien hemm l-istess natura tar-relazzjoni bejn id-daqs u t-tkabbir tad-database, li kibret minn 4 MB għal 15 MB. B'kollox, jirriżulta li maż-żmien (bit-tkabbir tal-bidu kiesaħ), żdiedu kemm il-ħin tat-tnedija tal-applikazzjoni kif ukoll id-daqs tad-database. Għandna ipoteżi fuq idejna. Issa baqa’ biss li tikkonferma d-dipendenza. Għalhekk, iddeċidejna li nneħħu l-"tnixxijiet" u naraw jekk dan iħaffef it-tnedija.

Raġunijiet għat-tkabbir tad-database bla tarf

Qabel ma tneħħi "tnixxijiet", ta 'min jifhem għaliex dehru fl-ewwel lok. Biex tagħmel dan, ejja niftakru x'inhu l-Isfera.

Realm hija database mhux relazzjonali. Jippermettilek tiddeskrivi relazzjonijiet bejn oġġetti b'mod simili għal kemm huma deskritti databases relazzjonali ORM fuq Android. Fl-istess ħin, Realm jaħżen oġġetti direttament fil-memorja bl-inqas ammont ta 'trasformazzjonijiet u mappings. Dan jippermettilek taqra data mid-diska malajr ħafna, li hija s-saħħa tal-Realm u għaliex hija maħbuba.

(Għall-finijiet ta 'dan l-artikolu, din id-deskrizzjoni se tkun biżżejjed għalina. Tista' taqra aktar dwar Realm fil-beraħ dokumentazzjoni jew fil tagħhom akkademja).

Ħafna żviluppaturi huma mdorrijin jaħdmu aktar ma 'databases relazzjonali (per eżempju, databases ORM b'SQL taħt il-barnuża). U affarijiet bħat-tħassir tad-data cascading spiss jidhru bħala mogħtija. Imma mhux fl-Isfera.

Mill-mod, il-karatteristika tat-tħassir tal-kaskata ilha mitluba għal żmien twil. Dan reviżjoni и ieħor, assoċjat magħha, ġie diskuss b'mod attiv. Kien hemm sensazzjoni li dalwaqt se jsir. Iżda mbagħad kollox tradott fl-introduzzjoni ta 'rabtiet b'saħħithom u dgħajfa, li wkoll issolvi awtomatikament din il-problema. Kien pjuttost ħaj u attiv f'dan il-kompitu talba tal-ġibda, li għalissa twaqqaf minħabba diffikultajiet interni.

Tnixxija tad-dejta mingħajr tħassir kaskata

Kif eżattament titnixxi d-dejta jekk tiddependi fuq tħassir ta 'kaskata ineżistenti? Jekk għandek oġġetti tal-Realm imnaqqsa, allura għandhom jitħassru.
Ejja nħarsu lejn eżempju (kważi) reali. Għandna oġġett CartItemEntity:

@RealmClass
class CartItemEntity(
 @PrimaryKey
 override var id: String? = null,
 ...
 var name: String = "",
 var description: String = "",
 var image: ImageEntity? = null,
 var category: String = MENU_CATEGORY_UNKNOWN_ID,
 var customizationEntity: CustomizationEntity? = null,
 var cartComboProducts: RealmList<CartProductEntity> = RealmList(),
 ...
) : RealmObject()

Il-prodott fil-karrettun għandu oqsma differenti, inkluża stampa ImageEntity, ingredjenti personalizzati CustomizationEntity. Ukoll, il-prodott fil-karrettun jista 'jkun combo bis-sett ta' prodotti tiegħu stess RealmList (CartProductEntity). L-oqsma kollha elenkati huma oġġetti ta' Realm. Jekk indaħħlu oġġett ġdid (copyToRealm() / copyToRealmOrUpdate()) bl-istess id, allura dan l-oġġett jinkiteb kompletament. Iżda l-oġġetti interni kollha (immaġni, customizationEntity u cartComboProducts) jitilfu l-konnessjoni mal-ġenitur u jibqgħu fid-database.

Peress li l-konnessjoni magħhom tintilef, m'għadniex naqrawhom jew inħassruhom (sakemm ma naċċessawhomx b'mod espliċitu jew inneħħu t-"tabella") kollha. Aħna sejħu dan "tnixxijiet tal-memorja".

Meta naħdmu ma 'Realm, irridu ngħaddu b'mod espliċitu mill-elementi kollha u espliċitament inħassru kollox qabel tali operazzjonijiet. Dan jista 'jsir, pereżempju, bħal dan:

val entity = realm.where(CartItemEntity::class.java).equalTo("id", id).findFirst()
if (first != null) {
 deleteFromRealm(first.image)
 deleteFromRealm(first.customizationEntity)
 for(cartProductEntity in first.cartComboProducts) {
   deleteFromRealm(cartProductEntity)
 }
 first.deleteFromRealm()
}
// и потом уже сохраняем

Jekk tagħmel dan, allura kollox jaħdem kif suppost. F'dan l-eżempju, nassumu li m'hemm l-ebda oġġett ieħor tal-Realm ibejjed ġewwa immaġini, customizationEntity, u cartComboProducts, u għalhekk m'hemm l-ebda loops u tħassir nested oħra.

Soluzzjoni ta 'malajr

L-ewwel ħaġa li ddeċidejna li nagħmlu kienet inaddfu l-oġġetti li qed jikbru malajr u niċċekkjaw ir-riżultati biex naraw jekk dan isolvix il-problema oriġinali tagħna. L-ewwel, saret l-aktar soluzzjoni sempliċi u intuwittiva, jiġifieri: kull oġġett għandu jkun responsabbli għat-tneħħija tat-tfal tiegħu. Biex tagħmel dan, introduċejna interface li rritornat lista tal-oġġetti tal-Realm imnaqqxa tagħha:

interface NestedEntityAware {
 fun getNestedEntities(): Collection<RealmObject?>
}

U implimentajnaha fl-oġġetti tal-Isfera tagħna:

@RealmClass
class DataPizzeriaEntity(
 @PrimaryKey
 var id: String? = null,
 var name: String? = null,
 var coordinates: CoordinatesEntity? = null,
 var deliverySchedule: ScheduleEntity? = null,
 var restaurantSchedule: ScheduleEntity? = null,
 ...
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       coordinates,
       deliverySchedule,
       restaurantSchedule
   )
 }
}

В getNestedEntities nirritornaw lit-tfal kollha bħala lista fissa. U kull oġġett tifel jista 'wkoll jimplimenta l-interface NestedEntityAware, li jindika li għandu oġġetti ta' Realm interni x'tħassar, pereżempju ScheduleEntity:

@RealmClass
class ScheduleEntity(
 var monday: DayOfWeekEntity? = null,
 var tuesday: DayOfWeekEntity? = null,
 var wednesday: DayOfWeekEntity? = null,
 var thursday: DayOfWeekEntity? = null,
 var friday: DayOfWeekEntity? = null,
 var saturday: DayOfWeekEntity? = null,
 var sunday: DayOfWeekEntity? = null
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       monday, tuesday, wednesday, thursday, friday, saturday, sunday
   )
 }
}

U l-bqija, it-tbejjit ta 'oġġetti jista' jiġi ripetut.

Imbagħad niktbu metodu li b'mod rikorsiv iħassar l-oġġetti kollha nested. Metodu (magħmul bħala estensjoni) deleteAllNestedEntities iġib l-oġġetti u l-metodu tal-ogħla livell deleteNestedRecursively Tneħħi b'mod rikorsiv l-oġġetti kollha nested billi tuża l-interface NestedEntityAware:

fun <T> Realm.deleteAllNestedEntities(entities: Collection<T>,
 entityClass: Class<out RealmObject>,
 idMapper: (T) -> String,
 idFieldName : String = "id"
 ) {

 val existedObjects = where(entityClass)
     .`in`(idFieldName, entities.map(idMapper).toTypedArray())
     .findAll()

 deleteNestedRecursively(existedObjects)
}

private fun Realm.deleteNestedRecursively(entities: Collection<RealmObject?>) {
 for(entity in entities) {
   entity?.let { realmObject ->
     if (realmObject is NestedEntityAware) {
       deleteNestedRecursively((realmObject as NestedEntityAware).getNestedEntities())
     }
     realmObject.deleteFromRealm()
   }
 }
}

Għamilna dan bl-oġġetti li qed jikbru malajr u ċċekkajna x’ġara.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Bħala riżultat, dawk l-oġġetti li koprejna b'din is-soluzzjoni waqfu jikbru. U t-tkabbir ġenerali tal-bażi naqas, iżda ma waqafx.

Is-soluzzjoni "normali".

Għalkemm il-bażi bdiet tikber aktar bil-mod, xorta kibret. Għalhekk bdejna nħarsu aktar. Il-proġett tagħna jagħmel użu attiv ħafna mill-caching tad-dejta f'Realm. Għalhekk, il-kitba ta 'l-oġġetti kollha nested għal kull oġġett hija intensiva fil-ħidma, flimkien ma' r-riskju ta 'żbalji jiżdied, għaliex tista' tinsa li tispeċifika l-oġġetti meta tbiddel il-kodiċi.

Ridt niżgura li ma użajtx interfaces, iżda li kollox ħadem waħdu.

Meta rridu li xi ħaġa taħdem waħedha, irridu nużaw ir-riflessjoni. Biex nagħmlu dan, nistgħu ngħaddu minn kull qasam tal-klassi u niċċekkjaw jekk huwiex oġġett ta' Realm jew lista ta' oġġetti:

RealmModel::class.java.isAssignableFrom(field.type)

RealmList::class.java.isAssignableFrom(field.type)

Jekk il-qasam huwa RealmModel jew RealmList, imbagħad żid l-oġġett ta 'dan il-qasam ma' lista ta 'oġġetti mnaqqsa. Kollox huwa eżattament l-istess kif għamilna hawn fuq, biss hawn se jsir waħdu. Il-metodu tat-tħassir tal-kaskata innifsu huwa sempliċi ħafna u jidher bħal dan:

fun <T : Any> Realm.cascadeDelete(entities: Collection<T?>) {
 if(entities.isEmpty()) {
   return
 }

 entities.filterNotNull().let { notNullEntities ->
   notNullEntities
       .filterRealmObject()
       .flatMap { realmObject -> getNestedRealmObjects(realmObject) }
       .also { realmObjects -> cascadeDelete(realmObjects) }

   notNullEntities
       .forEach { entity ->
         if((entity is RealmObject) && entity.isValid) {
           entity.deleteFromRealm()
         }
       }
 }
}

Estensjoni filterRealmObject jiffiltra u jgħaddi biss oġġetti Realm. Metodu getNestedRealmObjects permezz tar-riflessjoni, isib l-oġġetti kollha tal-Realm imnaqqxa u jpoġġihom f'lista lineari. Imbagħad nagħmlu l-istess ħaġa b'mod rikorsiv. Meta tħassar, trid tiċċekkja l-oġġett għall-validità isValid, minħabba li jista 'jkun li oġġetti ġenitur differenti jista' jkollhom dawk identiċi mnaqqsa. Huwa aħjar li tevita dan u sempliċement tuża awto-ġenerazzjoni ta 'id meta toħloq oġġetti ġodda.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Implimentazzjoni sħiħa tal-metodu getNestedRealmObjects

private fun getNestedRealmObjects(realmObject: RealmObject) : List<RealmObject> {
 val nestedObjects = mutableListOf<RealmObject>()
 val fields = realmObject.javaClass.superclass.declaredFields

// Проверяем каждое поле, не является ли оно RealmModel или списком RealmList
 fields.forEach { field ->
   when {
     RealmModel::class.java.isAssignableFrom(field.type) -> {
       try {
         val child = getChildObjectByField(realmObject, field)
         child?.let {
           if (isInstanceOfRealmObject(it)) {
             nestedObjects.add(child as RealmObject)
           }
         }
       } catch (e: Exception) { ... }
     }

     RealmList::class.java.isAssignableFrom(field.type) -> {
       try {
         val childList = getChildObjectByField(realmObject, field)
         childList?.let { list ->
           (list as RealmList<*>).forEach {
             if (isInstanceOfRealmObject(it)) {
               nestedObjects.add(it as RealmObject)
             }
           }
         }
       } catch (e: Exception) { ... }
     }
   }
 }

 return nestedObjects
}

private fun getChildObjectByField(realmObject: RealmObject, field: Field): Any? {
 val methodName = "get${field.name.capitalize()}"
 val method = realmObject.javaClass.getMethod(methodName)
 return method.invoke(realmObject)
}

Bħala riżultat, fil-kodiċi tal-klijent tagħna nużaw "cascading delete" għal kull operazzjoni ta 'modifika tad-dejta. Per eżempju, għal operazzjoni ta 'inserzjoni tidher bħal din:

override fun <T : Entity> insert(
 entityInformation: EntityInformation,
 entities: Collection<T>): Collection<T> = entities.apply {
 realmInstance.cascadeDelete(getManagedEntities(entityInformation, this))
 realmInstance.copyFromRealm(
     realmInstance
         .copyToRealmOrUpdate(this.map { entity -> entity as RealmModel }
 ))
}

Metodu l-ewwel getManagedEntities jirċievi l-oġġetti kollha miżjuda, u mbagħad il-metodu cascadeDelete Tħassar b'mod rikorsiv l-oġġetti kollha miġbura qabel ma tikteb oħrajn ġodda. Nispiċċaw nużaw dan l-approċċ matul l-applikazzjoni kollha. It-tnixxijiet tal-memorja f'Realm spiċċaw kompletament. Wara li wettaq l-istess kejl tad-dipendenza tal-ħin tal-istartjar fuq in-numru ta 'bidu kiesaħ tal-applikazzjoni, naraw ir-riżultat.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Il-linja ħadra turi d-dipendenza tal-ħin tal-istartjar tal-applikazzjoni fuq in-numru ta 'startjar kiesaħ waqt it-tħassir awtomatiku tal-kaskata ta' oġġetti nested.

Riżultati u konklużjonijiet

Id-database Realm li dejjem tikber kienet qed tikkawża li l-applikazzjoni titnieda bil-mod ħafna. Ħarġajna aġġornament b'"cascading delete" tagħna stess ta' oġġetti nested. U issa aħna nissorveljaw u nevalwaw kif id-deċiżjoni tagħna affettwat il-ħin tat-tnedija tal-applikazzjoni permezz tal-metrika _app_start.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Għall-analiżi, nieħdu perjodu ta 'żmien ta' 90 jum u naraw: il-ħin tat-tnedija tal-applikazzjoni, kemm il-medjan kif ukoll dak li jaqa 'fuq il-95 perċentil tal-utenti, beda jonqos u m'għadux jiżdied.

Ir-rakkont ta' kif it-tħassir tal-kaskata f'Realm rebaħ fuq tnedija twila

Jekk tħares lejn it-tabella ta' sebat ijiem, il-metrika _app_start tidher kompletament adegwata u hija inqas minn sekonda.

Ta’ min iżżid ukoll li b’mod awtomatiku, Firebase jibgħat notifiki jekk il-valur medjan ta’ _app_start jaqbeż il-5 sekondi. Madankollu, kif nistgħu naraw, m'għandekx tistrieħ fuq dan, iżda pjuttost tidħol u tiċċekkjaha b'mod espliċitu.

Il-ħaġa speċjali dwar id-database Realm hija li hija database mhux relazzjonali. Minkejja l-faċilità ta 'użu, ix-xebh ma' soluzzjonijiet ORM u konnessjoni ta 'oġġetti, m'għandux tħassir tal-kaskata.

Jekk dan ma jitqiesx, allura l-oġġetti nested jakkumulaw u "jnixxu". Id-database se tikber b'mod kostanti, li mbagħad taffettwa t-tnaqqis jew l-istartjar tal-applikazzjoni.

Qsamt l-esperjenza tagħna dwar kif malajr nagħmlu tħassir ta’ kaskata ta’ oġġetti f’Realm, li għadha mhix barra mill-kaxxa, iżda ilha titkellem dwarha jgħidu и jgħidu. Fil-każ tagħna, dan għaġġel ħafna l-ħin tal-istartjar tal-applikazzjoni.

Minkejja d-diskussjoni dwar id-dehra imminenti ta 'din il-karatteristika, in-nuqqas ta' tħassir ta 'kaskata f'Realm isir permezz tad-disinn. Jekk qed tfassal applikazzjoni ġdida, imbagħad ikkunsidra dan. U jekk diġà qed tuża Realm, iċċekkja jekk għandekx problemi bħal dawn.

Sors: www.habr.com

Żid kumment