Gerçek savaş serisi ile değişmez bağlam açıklamasına tepki verin

Gerçek cehalet bilgi eksikliği değil, bilgi edinmeyi reddetmektir! -Popper (düşünür filozof)

Amaçları

  • fark algoritması
  • Optimizasyon yöntemi
  • Değişmez ve alternatifler [Anahtar noktalar]

Makale akışı

Tepki- > Karşılaşma sorunları - > Optimizasyon > Optimizasyon yöntemi > İlke ve seçim

Fark algoritmasının ilk kısmı ve problemler

React, bir özellik (props) ve durum (durum) her gerçekleştiğinde sanal bir DOM (yani VDOM) kullanır Çeşitlilik Oluşturma işlevi farklı bir öğe ağacı döndürdüğünde, React şu anda döndürülen öğe ağacı ile son oluşturulan öğe ağacı arasındaki farkı tespit edecek ve ardından farkı yerinde güncelleyecek ve son olarak gerçek DOM'a işleyecektir. Bu, tüm Mutabakat sürecidir. ,onun Çekirdek, eski ve yeni DOM ağaçlarını karşılaştırmak için kullanılan fark algoritmasıdır.

Daha iyi performans elde etmek için ilk iş, Farkı azalt Güncellenmesi gereken düğümlerin güncellenebileceği varsayımı altında bu fark süreci nasıl önlenebilir?

Cevap, shouldComponentUpdate yaşam döngüsü işlevini kullanmaktır. Bu işlev ne işe yarar?

Çözümün ikinci kısmı

İlk bölümdeki akış şemasına ve yaşam döngüsü işlevine göre, eğer isterseniz ComponentUpdate İşleme zamanı geldiğinde işle İşlemi sadece burada yapabilirsiniz.

Mesele şudur: özellik (props) ve durum (durum) ne zaman değişir?

1. Sığ karşılaştırma için PureComponent (not) 2. shouldComponentUpdate'te derinlemesine karşılaştırma 3. Değişmez veri yapısı + SCU (not) sığ karşılaştırması

Derinlik karşılaştırması

PureComponent (not) Sığ karşılaştırma . Kaynak kodda bir kod parçası vardır. Özniteliğin değeri bir başvuru türüdür Sığ karşılaştırma başarısız olduğunda. Bu yöntem yalnızca durum bilgisi olmayan bileşenler veya çok basit durum verilerine sahip bileşenler için uygundur.Çok sayıda uygulama tipi bileşen için güçsüzdür.

Yani, shouldComponentUpdate içinde gerçekleştirilirse Derin karşılaştırma Yani tam karşılaştırma, veri miktarı büyükse performans kaybı ciddi olacaktır.

bu problem nasıl çözülür?

function sığEqual (objA: mixed, objB: mixed): boolean { // Aşağıdakiler === işlevine eşdeğerdir, tek fark + 0 ve-0 ile NaN ve NaN durumlarının özel olarak ele alınmasıdır // Birinci seviye: temel veri türleri doğrudan sonuçları karşılaştırır eğer (is (objA, objB)) { doğruya dön; } // İkinci düzey: Bir nesne veri türü olmadığı sürece, yanlış döndür Eğer ( typeof objA! == 'nesne' || objA === boş || typeof objB! == 'nesne' || objB === boş ) { yanlış dönüş; } // Üçüncü seviye: Burada, her ikisinin de nesne veri türü olduğunu garanti edebiliriz, ikisinin öznitelik sayısını karşılaştırabiliriz. const keysA = Nesne.keys (objA); const keysB = Nesne.keys (objB); if (keysA.length! == keysB.length) { yanlış dönüş; } // Dördüncü seviye: ikisinin özniteliklerinin eşit olup olmadığını ve değerlerin eşit olup olmadığını karşılaştırın for (let i = 0; i < keysA.length; i ++) { Eğer ( ! hasOwnProperty.call (objB, anahtarlarA ) || ! is (objA, objB) ) { yanlış dönüş; } } doğruya dön; }

Durum karşılaştırması

Nasıl karşılaştırılacağına ve hangi yöntemin kullanılacağına üçüncü bölümden başlayacağım.

Bölüm III Değişmez Verilerle İlgili

Yukarıdaki sorunlar ışığında, ana veri yapıları aşağıdaki gibi listelenmiştir:

  • Değişmez (Değişmez) veriler
    • Yeni veri yapısı
      • facebook / immutable-js
  • Değişmez Güncelleme (Değiştirilemez Güncelleme) yardımcı programı
    • mweststrate / immer
  • Değişmez / Redux birlikte çalışabilirliği
    • gajus / redux-immutable

immutable-js

Referans kaynağı Değişmez ayrıntılı açıklama ve React uygulaması

Paylaşılan değişken durum, tüm kötülüklerin köküdür (Paylaşılan değiştirilebilir durum, tüm kötülüklerin köküdür) - Pete Hunt

JavaScript'teki nesneler genellikle Değişebilir Referans atamasının kullanılması nedeniyle, yeni nesne yalnızca orijinal nesneye başvurur ve yeni nesnenin değiştirilmesi orijinal nesneyi etkiler. Örneğin, foo = {a: 1}; bar = foo; bar.a = 2 foo.a'nın da 2 olarak değiştirildiğini göreceksiniz.

İşe yarasa da Hafızadan tasarruf edin , Ancak uygulama karmaşık olduğunda bu çok büyük bir gizli tehlikeye neden olur ve Mutable'ın avantajları kayıptan daha fazla olur.

Bu sorunu çözmek için genel yaklaşım, değiştirilmekten kaçınmak için sığ kopya (sığ kopya) veya derin kopya (derin kopya) kullanmaktır, ancak bunu yapmak CPU ve bellek israfına neden olur.

Immutable bu sorunları iyi çözebilir.

Değişmez Veriler

Değişmez Veriler, oluşturulduktan sonra değiştirilemeyen verilerdir. Immutable nesnesinde yapılan herhangi bir değişiklik veya ekleme veya silme, bir Yeni Değişmez nesne .

Değişmez uygulama ilkesi Kalıcı Veri Yapısı'dır, yani yeni veri oluşturmak için eski verileri kullanırken, Eski verilerin aynı anda mevcut ve değiştirilmediğinden emin olun.

Aynı zamanda DeepCopy'den kaçının Tüm düğümlerin çoğaltılmasından kaynaklanan performans kaybı için Immutable, Yapısal Paylaşımı kullanır, yani nesne ağacındaki bir düğüm değişirse, yalnızca bu düğüm ve bundan etkilenen ana düğüm değiştirilir ve diğer düğümler paylaşılır. Lütfen aşağıdaki animasyonu izleyin:

Facebook mühendisi Lee Byron bunu yapmak için 3 yıl harcadı. React ile aynı zamanda ortaya çıktı, ancak varsayılan olarak React araç setine dahil edilmedi (React, basitleştirilmiş bir Yardımcı sağlar). Tam bir set uygular Kalıcı Veri Yapısı , Kullanımı kolay birçok veri türü vardır. Koleksiyon, Liste, Harita, Ayarla, Kayıt, Sıra gibi. Çok kapsamlı harita, filtre, groupBy, azalt, bul işlevsel çalışma yöntemleri vardır. Aynı zamanda API, mümkün olduğu kadar Object veya Array'e benzer olmalıdır.

Bunların arasında açıklanacak en önemli üç veri yapısı vardır: (Java programcıları buna en aşina olmalıdır)

Harita: Nesneye karşılık gelen anahtar-değer çiftlerinden oluşan bir koleksiyon, ES6 ayrıca özel bir Harita nesnesine sahiptir Liste: Array'e karşılık gelen sıralı ve tekrarlanabilir bir liste Set: sırasız ve tekrarlanamayan bir liste // orijinal yazı let foo = {a: {b: 1}}; let bar = foo; bar.a.b = 2; console.log (foo.a.b); // 2 yazdırır console.log (foo === bar); // true yazdırır // immutable.js'yi kullandıktan sonra "değişmez" den Immutable ithal; foo = Immutable.fromJS ({a: {b: 1}}); bar = foo.setIn (, 2); // atamak için setIn kullanın console.log (foo.getIn ()); // Değeri almak ve 1 yazdırmak için getIn kullanın console.log (foo === bar); // yanlış yazdır

Immutable.is

let map1 = Immutable.Map ({a: 1, b: 1, c: 1}); let map2 = Immutable.Map ({a: 1, b: 1, c: 1}); // Bellek adreslerini karşılaştırın map1 === map2; // false // Immutable.is, iki nesnenin hashCode veya valueOf değerini karşılaştırır (JavaScript nesneleri için) Immutable.is (harita1, harita2); // doğru

Lehte ve aleyhte olanlar

  • Immutable, Mutable'ın getirdiği karmaşıklığı azaltır
  • Hafızadan tasarruf edin
  • Geri Al / Yinele, Kopyala / Yapıştır ve hatta zamanda yolculuk işlevleri çocuk oyuncağı
  • Eşzamanlılık güvenliği
  • Yeni API öğrenmeniz gerekiyor
  • Kaynak dosya boyutu artırıldı
  • Yerel nesnelerle karıştırılması kolay
  • ithal {is} 'değişmez'den; shouldComponentUpdate: (nextProps = {}, nextState = {}) = > { const thisProps = this.props || {}, thisState = this.state || {}; eğer (Object.keys (thisProps) .length! == Object.keys (nextProps) .length || Object.keys (thisState) .length! == Object.keys (nextState) .length) { doğruya dön; } for (nextProps içinde const anahtarı) { eğer (! is (thisProps, nextProps)) { doğruya dön; } } for (nextState içinde const anahtar) { eğer (thisState! == nextState! is (thisState, nextState)) { doğruya dön; } } yanlış dönüş; }

    Immerjs

    "Immer.js" kaynak kodunun aşağıdaki alıntı yoğun okuması

    Immer'ın çözmek istediği problem, Immutable'ın karmaşıklığını basitleştirmek için meta-programlamayı kullanmaktır. Immers, yerleşik API'ler yerine yerel veri yapılarını kullanan API'lerdir.

    const üretmek = gerektirir ('immer') const state = { done: false, val: 'dize', } const newState = üretmek (durum, (taslak) = > { draft.done = true }) console.log (state.done) // false console.log (newState.done) // trueproduce (obj, draft = > { draft.count ++ })

    Genel fikir: taslak obj vekil , Değiştirilebilir taslakta yapılan değişiklikler, Özel ayarlayıcı işlevi , Orijinal nesnenin değerini değiştirmez, ancak özyinelemeli üst öğe sürekli olarak Sığ kopya , Ve sonunda yenisine dönün Üst düzey nesne , Üretmek işlevi olarak dönüş değer.

    Temsilci oluştur

    { değiştirildi, // Değiştirildi mi finalized, // Tamamlandı mı (tüm ayarlayıcılar çalıştırıldı ve kopya oluşturuldu) üst, // üst nesne temel, // orijinal nesne (yani, obj) kopya, // temelin sığ kopyası (yani obj), Object.assign (Object.create (null), obj) kullanılarak uygulanmıştır proxy'ler, // Yavaş bir başlatma stratejisi kullanarak her özellik Anahtarının proxy nesnesini depolayın }

    Bu proxy nesnesinde, özel bir alıcı ayarlayıcıyı bağlayın ve ardından doğrudan infaz yapmak .

    alıcı

    Geri çağırma üretme işlevi, kullanıcının değiştirilebilir kodunu içerir. Yani şimdi giriş bir alıcı ve pasör oldu.

    Alıcı, esas olarak proxy nesnesini tembel olarak başlatmak için kullanılır, yani Proxy nesnesi alt özelliğine erişildiğinde Yalnızca proxy nesnesi oluşturulduğunda.

  • Kaynak israfı yok;
  • Alt nesnelere erişilebilir.
  • ayarlayıcı

    Taslak değiştirildiğinde orijinal değer olan baz gerçekleştirilir Sığ kopya , Bunu copy özelliğine kaydedin ve aynı anda değiştirilen özelliği true olarak ayarlayın. Bu, en önemli Değişmez işlemi tamamlar ve yüzeysel kopya çok performans tüketmez, ayrıca isteğe bağlı sığ bir kopyadır, dolayısıyla Immer'in performansı kötü değildir.

    Aynı zamanda, tüm bağlantının nesnelerinin yeni nesneler olmasını sağlamak için, üst öğe özniteliğe dayalı olacak ve yaprak düğümden kök düğüme kadar tüm bağlantı nesnesi yenilenene kadar yüzeysel kopyalara devam edilecektir.

    Değiştirilen nesne değiştirildiğinde, yeni değer kopyalanan nesneye kaydedilir.

    Değişmez nesneler oluşturun

    ne zaman Üretimi gerçekleştirdikten sonra Bundan sonra, tüm kullanıcı değişiklikleri tamamlanmıştır (bu nedenle Immer eşzamansız özelliğini desteklemez), eğer değiştirilmiş Öznitelik yanlışsa, bu, kullanıcının nesneyi hiç değiştirmediği anlamına gelir, bu nedenle yalnızca orijinal temel niteliği doğrudan geri döndürün.

    Değiştirilen öznitelik ise doğru , Nesnenin değiştirildiğini belirten özelliği kopyala Bu kadar. Ancak ayarlayıcı süreci yinelemelidir ve taslağın alt nesnesi de taslaktır (değiştirilen temel kopya gibi ek niteliklerin vekili dahil), gerçek değeri elde etmek için katman katman yinelemeliyiz.

    Yani bu aşamada tüm taslaklar kesinleşmiş Herşey yanlış, kopyala İçeride çok sayıda taslak öznitelik olabilir, bu nedenle özyinelemeli taban ve kopyanın alt öznitelikleri aynıysa, doğrudan döndürülürler; farklılarsa, tüm süreç bir kez yinelenir (bu bölümün ilk satırından başlayarak).

    Son olarak döndürülen nesne, temelin bazı öznitelikleri (değiştirilmemiş parça) ve kopyanın bazı öznitelikleri (değiştirilmiş parça) tarafından nihayet birleştirilir. Son olarak, kopya özelliğini dondurmak ve değiştirmek için dondur'u kullanın. kesinleşmiş Öznitelik şu şekilde ayarlandı: doğru.

    Bu noktada dönüş değeri oluşturulur, son değeri copy özelliğine kaydederiz, dondururuz ve Immutable değerini döndürürüz.

    Immer bu nedenle inanılmaz bir işlemi tamamladı: Mevcut olanı değiştirerek bir sonraki değişmez durumu yaratın.

    Kaynak kodunu okuduktan sonra, Immer'in Promise döndürmek için üretmek işlevini desteklediği sürece eşzamansız desteği gerçekten desteklediğini öğrendim. En büyük sorun, ajanın son iptalinin temizlenmesinin, Immer'in asenkron desteğini engelleyen global değişkenlerin kullanımını gerektirmesidir.

    immer resmi web sitesi

    avantaj

    Normal JavaScript nesneleri, dizileri, Setleri ve Haritaları ile değişmezlik. Öğrenilecek yeni API yok! Kesinlikle yazılmış, dizeye dayalı yol seçicileri vs. yok. Kutudan çıkar çıkmaz yapısal paylaşım Kutudan çıkan nesne donuyor Derin güncellemeler çocuk oyuncağı Klişe azaltma Daha az gürültü, daha kısa kod. Yamalar için birinci sınıf destek Küçük: 3KB sıkıştırılmış
    Ali'den yeni bir mikro hizmet ağ geçidi CSB Mikro Ağ Geçidi önerin
    önceki
    Önceki makaleden devam: Kullanıcı arabiriminin görmesi gereken 8 HTML + CSS becerisi (2. bölüm)
    Sonraki
    PhpStorm 2020.1 kararlı sürümü yayınlandı: composer.json kutudan çıktı
    Elektrikçiler için 60 ortak ve hataya açık bilgi noktası, bu elektrikçi araştırması için yeterli!
    Siemens PLC programlama bağlantı şeması ayrıntılı açıklama ve merdiven diyagramı program örneği
    PLC programlama dilleri nelerdir? Fark ne?
    S7-1200 Modbus-TCP haberleşme yapılandırma sihirbazı açıklaması
    30 PLC programlama örneği, sizi çocukluktan gelişmiş elektrik tanrısına götürür!
    Su pompası sabit basınçlı su beslemesini kontrol etmek için frekans dönüştürücü için adımlar ve yöntemler
    İkincil devre şemasını anlıyor musunuz? 3 dakika içinde anlamana yardım et!
    Bir PLC kontrol motor dönüşü tasarlamayı ve anti-kontrol sistemini durdurmayı size adım adım öğretin
    Yaygın olarak kullanılan altı rölenin tanıtımı
    Ön uç ve arka uç ayırma arayüzü özellikleri hakkında konuşun
    Anahtarı belirtmek için anahtar üzerinde neden "|" ve "O" kullanılır?
    To Top