İçeriğe geç
academia.sh

Ders 13 / 14

Uygulama Boyutu Yönetimi

Uygulama boyutu yönetimi, ilk indirmenin neleri içereceğini ve hangi parçaların sonradan, isteğe bağlı olarak indiğini belirler. Ders, ilk indirmede gelmeyen bir varlık paketine bağlı özelliğin ne kadar çalıştığını ölçer.

Yayın Güncelleme

Bu derste

  • Uygulama boyutunun indirme kararına etkisini oran vermeden açıklar
  • İsteğe bağlı varlık paketini ve platforma göre bölünmüş paketi tanımlar
  • Kurulu varlık paketlerini yetenek olarak kurup özelliğin işlerliğini ölçer
  • İndirilmemiş paketin ertelenen olduğunu, bütçe aşımı olmadığını ölçümle gösterir
İçindekiler

Önceki ders eski sürümleri yeni sürüme yöneltmeyi anlattı. Yönelten her güncelleme aygıta bir şey indirir ve indirilen şey aygıtta yer kaplar. Bu ders, o indirmenin ne kadar büyük olması gerektiğini ve büyük olan parçanın nasıl sonraya bırakılabileceğini ele alır.

Kursun sorusu aynı kalır: bu koşulda bu özellik ne kadar çalışıyor? Bu derste koşul, aygıtta hangi varlık paketlerinin kurulu olduğudur.

Uygulama Boyutu ve İndirme Kararı

Kullanıcı bir uygulamayı indirmeden önce boyutuna bakar ve bu bakış her zaman bilinçli değildir. Bağlantısı sınırlı olan kullanıcı büyük bir uygulamayı ertelemeyi seçer. Aygıtında az yer kalan kullanıcı yeni bir uygulama için eskilerinden birini silmek zorunda kalır. Güncelleme de aynı kararı yeniden verdirir: büyük bir güncelleme, kullanıcının eski sürümde kalmasına yol açabilir ve bu, önceki dersin sorununu doğurur.

Burada oran ya da bayt vermiyoruz. Çünkü boyutun kullanıcıyı vazgeçirdiği eşik hem bağlantıya hem pazara hem de uygulamanın türüne göre değişir ve ekip bunu kendi sahasında ölçmelidir. Dersin söyleyebileceği şey yönü gösterir: ilk indirmeyi küçültmek, indirme kararını hafifletir.

Boyuta üç şey katkı yapar: uygulamanın kodu, uygulamanın içinde taşınan varlıklar ve çerçevenin çalışma zamanı. Kendi çizim motoruyla çalışan bir çerçeve motoru uygulamanın içinde taşır; yerel görünümlere köprüyle bağlanan bir çerçeve ise köprü katmanını. İkisinin payı ekibin kontrolünde değildir. Kontrolün olduğu yer varlıklardır: görüntüler, yazı tipleri, sesler, ek veriler.

İsteğe Bağlı Varlık Paketleri

Bütün varlıkların ilk indirmede gelmesi gerekmez. Her kullanıcı her özelliği kullanmaz. Fotoğraf filtreleri, ek dil verileri ya da ileri düzey bir oyun seviyesi, yalnız onu isteyen kullanıcıda gerekir. Bu varlıklar isteğe bağlı bir pakete ayrılır ve kullanıcı özelliği ilk kullandığında indirilir.

İsteğe bağlı paketin ilk karşılaşması bir indirmedir ve indirme ağa bağlıdır. Bağlantı yoksa paket inmez; paket inmediyse ona bağlı özellik çalışmaz. İşlerlik açısından bu durumun adı ertelenendir: özellik paket gelince çalışacak şekilde bekler. M31/K06’da bir indirme bütçesinin kaç örnekte aşıldığı soruldu. İsteğe bağlı varlık paketi indirilmemişse özellik ertelenendir; bu bir bütçe aşımı değildir. Aşım bir boyut sorusudur, ertelenen ise paketin henüz aygıtta olmamasıdır.

Aşağıdaki parça bir paketin istenişini gösterir; parça ölçülmez.

// Platform kodu: istege bagli varlik paketi
let request = NSBundleResourceRequest(tags: ["filters"])
request.beginAccessingResources { error in
    if error == nil { showFilters() } else { keepFiltersPending() }
}

Hata durumunda özelliğin kapatılması yerine bekletilmesi bir tasarım tercihidir. Özellik paket gelene kadar kullanıcıya “hazırlanıyor” gösterir ve paket indiğinde açılır. Kapatma, kullanıcıya özelliğin hiç olmadığını söyler; bekletme, özelliğin yakında hazır olacağını.

Platforma Göre Bölünmüş Paket

Aynı uygulamanın her aygıta aynı dosyaları götürmesi gerekmez. Bir aygıtın ekran yoğunluğu ve işlemci mimarisi bellidir; başka yoğunluk ve mimariler için hazırlanmış dosyalar o aygıtta işe yaramaz. Platformlar bunu bölünmüş paketle çözer: mağaza, yüklenen tek bir büyük pakette her aygıt için gereken parçayı seçer ve yalnız onu gönderir.

Android’de bölme, uygulama paketi yüklendiğinde varsayılan olarak açıktır; yapılandırma bloğu hangi bölmelerin üretileceğini ayarlar. iOS’ta ise mağaza benzer bir seçimi kendisi yapar ve ekip varlıkları etiketlerle düzenler. Aşağıdaki parça Android tarafını gösterir; parça ölçülmez.

// Platform kodu: platforma gore bolunmus paket
android {
    bundle {
        density { enableSplit = true }
        abi { enableSplit = true }
    }
}

Bölünmüş paket bir kaynak kazancıdır ve işlerliği ilk bakışta etkilemez: aygıt yalnız kendi parçasını alır ve özellikler aynı çalışır. Etkilediği yer indirme kararıdır.

Kullanılmayan Varlıklar

Bir uygulamanın büyümesinin sık görülen bir nedeni, artık kullanılmayan varlıkların pakette kalmasıdır. Bir ekran kaldırıldığında görselleri gitmeyebilir; bir kütüphane güncellendiğinde eski kopyası pakette kalabilir. Çözüm düzenli bir tarama alışkanlığıdır: hangi varlığın hangi koddan çağrıldığını bulmak ve çağrılmayanları ayıklamak. Her yayın öncesi bu taramayı yinelemek, boyutun sessizce büyümesini önler.

Taramanın bir sınırı vardır. Varlığa kodda bir ad dizgisiyle erişiliyorsa, tarama onu çağrılmıyor sanabilir. Silmeden önce o adın dinamik olarak kurulup kurulmadığı kontrol edilir. Yanlış silinen bir varlık, ancak kullanıcı o ekrana geldiğinde fark edilir.

Paketin Koşulunu Ölçmek

Ölçüm için üç özelliği ele alalım. Gallery galeridir; ağı ve temel paketi pack:base ister ve her kurulumda vardır. Filters fotoğraf filtreleridir; ağı ve pack:filters yeteneğini ister, paket yoksa ertelenen çalışır. Stickers çıkartmalardır; pack:stickers ister ve o da paket yoksa ertelenen çalışır. Çekirdek ilk dersten tanıdıktır ve her derste aynı biçimde yeniden verilir; ders ona dokunmaz.

// operability.mjs — bir ozelligin bir kosulda ne kadar calistigini siniflandirir
export const LEVELS = ["tam", "kisitli", "ertelenen", "kapali"];
const FALLBACKS = ["kisitli", "ertelenen"];

export function feature(name, needs, fallback = {}) {
  return { name, needs, fallback };
}

export function condition(name, has) {
  return { name, has };
}

function judge(item, cond) {
  const missing = item.needs.filter((need) => !cond.has.includes(need)).sort();
  let level = "tam";
  for (const need of missing) {
    const given = FALLBACKS.includes(item.fallback[need]) ? item.fallback[need] : "kapali";
    if (LEVELS.indexOf(given) > LEVELS.indexOf(level)) level = given;
  }
  return { level, feature: item.name, condition: cond.name, missing };
}

export function assess(features, conditions) {
  const records = [];
  for (const cond of conditions) {
    for (const item of features) records.push(judge(item, cond));
  }
  return records;
}

export function printLevels(records) {
  for (const r of records) {
    const missing = r.missing.length === 0 ? "-" : r.missing.join(",");
    console.log(`${r.level}: ${r.feature} @ ${r.condition} eksik=${missing}`);
  }
}

export function countLevels(records) {
  for (const name of LEVELS) {
    console.log(`${name}: ${records.filter((r) => r.level === name).length}`);
  }
  console.log(`etkilenen: ${records.filter((r) => r.level !== "tam").length}`);
}

Çekirdeğin ardından dersin yardımcı dosyası gelir. packsFor(install) kurulumdaki paketlerden bir koşul üretir: ağ her kurulumda vardır, her kurulu paket pack: önekiyle bir yetenek olur. assetsAtInstall(install) kurulumdaki varlık sayısını toplar; bu sayı dersin yerel sayacıdır ve kuralın girdisi değildir. Boyut bayt olarak değil, varlık sayısı olarak sayılır.

// packs.mjs — kurulu paketlerden kosul uretir, varlik sayisini toplar
import { feature, condition } from "./operability.mjs";

const assetCounts = { base: 30, filters: 12, stickers: 8 };

export function packsFor(install) {
  return condition(install.name, ["network", ...install.packs.map((name) => `pack:${name}`)]);
}

export function assetsAtInstall(install) {
  let total = 0;
  for (const name of install.packs) total += assetCounts[name];
  return total;
}

export const packFeatures = [
  feature("Gallery", ["network", "pack:base"]),
  feature("Filters", ["network", "pack:filters"], { "pack:filters": "ertelenen" }),
  feature("Stickers", ["network", "pack:stickers"], { "pack:stickers": "ertelenen" }),
];

YI9. Model, varlık sayısını boyutun vekili olarak kullanır: otuz, on iki ve sekiz birer varlık sayısıdır, bayt değildir. Bir varlık görüntü de olabilir, uzun bir ses dosyası da; sayı boyutu doğrudan vermez. Model yalnız iki kurulumu karşılaştırmak için yeterli bir sayaç sunar ve bu işlerliğin kuralını kurar; model çerçevenin kendisi değildir.

İlk ölçüm iki kurulumu yan yana koyar: yalnız temel paketi indiren ve bütün paketleri indiren kurulumlar. Önce her kurulumun varlık sayısı basılır, sonra altı kayıt gelir.

// main.mjs
import { assess, printLevels } from "./operability.mjs";
import { packsFor, assetsAtInstall, packFeatures } from "./packs.mjs";

const installs = [
  { name: "base-install", packs: ["base"] },
  { name: "full-install", packs: ["base", "filters", "stickers"] },
];
for (const install of installs) {
  console.log(`kurulum: ${install.name} varlik=${assetsAtInstall(install)}`);
}
printLevels(assess(packFeatures, installs.map(packsFor)));
kurulum: base-install varlik=30
kurulum: full-install varlik=50
tam: Gallery @ base-install eksik=-
ertelenen: Filters @ base-install eksik=pack:filters
ertelenen: Stickers @ base-install eksik=pack:stickers
tam: Gallery @ full-install eksik=-
tam: Filters @ full-install eksik=-
tam: Stickers @ full-install eksik=-

Temel kurulumda galeri tamdır; filtreler ve çıkartmalar ertelenen çıkar. Eksik olan paket yeteneğidir ve yedek tanımı ertelenendir. Tam kurulumda üç özellik de tamdır, ama ilk indirmedeki varlık sayısı otuzdan elliye çıkar. İşlerlik kazancı ile ilk indirmenin büyümesi aynı kararın iki yüzüdür.

Paket İndirilince

Kullanıcı filtreleri ilk kez açtığında paket iner ve kurulum değişir. Paket yeteneği koşula eklenir, Filters ertelenenden tama geçer. Çıkartma paketi hâlâ inmemiştir, ertelenen kalır.

İkinci ölçüm aynı kurulumu paket inmeden önce ve sonra koşar. Koşul adları farklıdır, çünkü iki koşulun adı aynı olamaz. Galeri iki durumda da tam olduğu için süzgeçle dışarıda bırakıldı.

// main.mjs
import { assess, printLevels } from "./operability.mjs";
import { packsFor, assetsAtInstall, packFeatures } from "./packs.mjs";

const before = { name: "base-install", packs: ["base"] };
const after = { name: "filters-downloaded", packs: ["base", "filters"] };
console.log(`indirme: varlik ${assetsAtInstall(before)} -> ${assetsAtInstall(after)}`);
const records = assess(packFeatures, [before, after].map(packsFor));
printLevels(records.filter((r) => r.feature !== "Gallery"));
indirme: varlik 30 -> 42
ertelenen: Filters @ base-install eksik=pack:filters
ertelenen: Stickers @ base-install eksik=pack:stickers
tam: Filters @ filters-downloaded eksik=-
ertelenen: Stickers @ filters-downloaded eksik=pack:stickers

Filtreler indirmeden sonra tamdır, çıkartmalar ertelenen kalır. İndirme yalnız indirilen paketin yeteneğini ekler; öteki paketleri etkilemez. Kurulu varlık sayısı otuzdan kırk ikiye çıkar.

YI10. Model, paketin indirmesini tek adımlı ve başarılı varsayar. Gerçekte indirme yarıda kesilebilir, aygıtta yer olmayabilir ya da paketin sürümü uygulamanın sürümüyle uyuşmayabilir. Kural bu ara durumları görmez; yalnız paket yeteneğinin koşulda olup olmadığına bakar.

Sınırlayıcı Ölçüm

Bu dersin odak kaydı Filters @ base-install’dır. Sınırlayıcı ölçüm iki şeyi birlikte gösterir. Birincisi, odak kayıt ertelenendir ve altı kaydın ikisi etkilenir. İkincisi, ertelenen bir bütçe aşımı değildir: ilk indirmedeki varlık sayısı için bir sınır konursa, sınırı aşan kurulum tam kayıtlı olandır; sınırı aşmayan kurulum ertelenen kayıtlıdır.

// main.mjs
import { assess, printLevels, countLevels } from "./operability.mjs";
import { packsFor, assetsAtInstall, packFeatures } from "./packs.mjs";

const installs = [
  { name: "base-install", packs: ["base"] },
  { name: "full-install", packs: ["base", "filters", "stickers"] },
];
const records = assess(packFeatures, installs.map(packsFor));
printLevels(records.filter((r) => r.feature === "Filters"));
countLevels(records);

const allowance = 40;
const within = (install) => (assetsAtInstall(install) <= allowance ? "icinde" : "asti");
console.log(`ilk indirme varlik: ${assetsAtInstall(installs[0])} ${assetsAtInstall(installs[1])}`);
console.log(`butce: ${installs[0].name} ${within(installs[0])} ${installs[1].name} ${within(installs[1])}`);
ertelenen: Filters @ base-install eksik=pack:filters
tam: Filters @ full-install eksik=-
tam: 4
kisitli: 0
ertelenen: 2
kapali: 0
etkilenen: 2
ilk indirme varlik: 30 50
butce: base-install icinde full-install asti

İlk iki satır dersin işlerliğini taşır: aynı özellik, aynı kod; yalnız paketin kurulu olup olmaması değişti ve kayıt ertelenenden tama geçti. Sayım satırları altı kayıttan dördünün tam, ikisinin ertelenen olduğunu söyler; etkilenen ikidir.

Son iki satır modelin sınırını gösterir. Dersin yerel sınırı kırk varlıktır. Temel kurulum bu sınırın içinde kalır ve filtreleri ertelenen bırakır. Tam kurulum sınırı aşar, ama üç özelliği de tamdır. Yani ertelenen olmak bir aşım belirtisi değildir, tam olmak da bir uyum belirtisi değildir. Kural sınırı görmez; yalnız paket yeteneğinin koşulda olup olmadığına bakar.

Bu ayrım kararı iki soruya böler. İlk indirme küçük mü, sorusu boyutun sorusudur. Filtreler çalışıyor mu, sorusu işlerliğin sorusudur. Boyutu küçültmek için paketi ayırmak ikinci sorunun cevabını tamdan ertelenene çevirir; bu bir bedeldir ve ekip onu bilerek öder.

Özet

  • Bu dersin işlerliği: ertelenen. Filters @ base-install, filtre paketi ilk indirmede gelmediği ve yedek tanımı ertelenen olduğu için ertelenen çıktı; aynı kurulumda Gallery tam kaldı.
  • İlk indirmeyi küçültmek indirme kararını hafifletir; boyutun kullanıcıyı vazgeçirdiği eşik ekibin kendi sahasında ölçeceği bir değerdir.
  • İsteğe bağlı varlık paketi sonradan iner; inmeyen paketin özelliği çalışmaz, ama paket gelince açılır. Platforma göre bölünmüş paket her aygıta yalnız gereken parçayı gönderir.
  • Altı kayıttan dördü tam, ikisi ertelenendi; etkilenen iki. Paket inince Filters tama geçti, Stickers ertelenen kaldı.
  • İlk indirme sınırını aşan kurulumun üç özelliği de tamdı; ertelenen bir bütçe aşımı değildir.

Sonraki Adım

Bu derste sorun, aygıtta bir şeyin bulunmamasıydı ve ekip bunu önceden bilebildi. Kursun son dersi, Çökme ve Kullanım İzleme, bilinmeyeni konu alır: sahada yayımlanmış bir yapı ne yapıyor, nerede çöküyor, hangi özelliği kim kullanıyor. Bağlantı dönene dek bekleyen çökme raporunu ve izlemenin kendi koşulunu ölçer.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ ↵ Esc gezin · aç · kapat