Bir web uygulamasını basit tutmak şaşırtıcı derecede karmaşık olabilir. Bu modülde web API'lerinin iş parçacığıyla nasıl çalıştığını ve bunu durum yönetimi gibi yaygın PWA kalıpları için nasıl kullanabileceğinizi öğreneceksiniz.
Basitlik ve karmaşıklık
Rich Hickey, Simple Made Easy başlıklı konuşmasında basit şeylerin mi karmaşık şeylerin niteliklerini ele alıyor. Basit hususları şu şekilde ifade ediyor:
"Bir rol, bir görev, tek bir kavram veya tek bir boyut."
Ancak sadelik şu konularla ilgili değildir:
"Bir örneğe sahip olma veya bir işlem gerçekleştirme."
Bir şeyin basit olup olmaması onun ne kadar bağlı olduğuyla ilgilidir.
Karmaşıklık, bağlama, dokuma veya Rich'in deyimiyle, nesneleri bir araya getirme işlemlerinden kaynaklanır. Bir şeyin yönettiği rolleri, görevleri, kavramları veya boyutları sayarak karmaşıklığı hesaplayabilirsiniz.
Basit bir kodun anlaşılması ve sürdürülmesi daha kolay olduğundan yazılım geliştirmede basitlik şarttır. Basitlik, uygulamamızı mümkün olan her bağlamda hızlı ve erişilebilir hale getirmeye yardımcı olabileceğinden web uygulamaları için de gereklidir.
PWA karmaşıklığını yönetme
Web için yazdığımız tüm JavaScript bir noktada ana iş parçacığına dokunur. Ancak ana iş parçacığında, bir geliştirici olarak sizin kontrolünüz dışındaki birçok karmaşıklık alışılmışın dışındadır.
Ana ileti dizisi:
- Stilleri hesaplama, katmanları güncelleme ve birleştirme ve ekrana boyamayı içeren karmaşık, çok adımlı bir süreç olan sayfayı çizmekten sorumludur.
- Kaydırma gibi etkinlikler de dahil olmak üzere etkinlikleri dinlemek ve bunlara tepki vermekten sorumludur.
- Sayfanın yüklenmesi ve kaldırılmasından sorumludur.
- Medya, güvenlik ve kimlik yönetimi. Yazdığınız herhangi bir kodun ilgili iş parçacığında yürütülebilmesinden önce aşağıdakiler gibi işlemler gerçekleşir:
- DOM üzerinde işlem yapılıyor.
- Hassas API'lere (ör. cihaz özellikleri veya medya/güvenlik/kimlik) erişme.
Surma'nın 2019 Chrome Geliştirici Zirvesi konuşmasında belirttiği gibi, ana ileti dizisi fazla işlenmiş ve yeterince ücret ödenmemiştir.
Yine de çoğu uygulama kodu ana iş parçacığında da bulunur.
Tüm bu kodlar ana iş parçacığının daha karmaşık hale gelmesini sağlar. Ana ileti dizisi, tarayıcının ekrandaki içeriği düzenlemek ve oluşturmak için kullanabileceği tek ileti dizisidir. Bu nedenle, kodunuzun tamamlanması için daha fazla işlem gücü gerektiğinde, kodu hızlı bir şekilde çalıştırmamız gerekir. Çünkü uygulama mantığını gerçekleştirmek için gereken her saniye, tarayıcının kullanıcı girişine yanıt verememesi veya sayfayı yeniden çizememesi anlamına gelir.
Etkileşimler girişe bağlanmadığında, kareler düştüğünde veya bir siteyi kullanmak çok uzun sürdüğünde kullanıcılar sinirlenir, uygulamanın çalışmadığını düşünürler ve uygulamaya olan güvenleri azalır.
Kötü haber ne mi? Ana ileti dizisine karmaşıklık katmak, bu hedeflere ulaşmayı zorlaştırmanın neredeyse kesin bir yoludur. Ancak güzel bir haberimiz var: Çünkü ana iş parçacığının ne yapması gerektiği açıktır: Uygulamanızın geri kalanında bu işleme bağımlılığı azaltmaya yardımcı olması için bir kılavuz olarak kullanılabilir.
Kaygı ayrımları
Web uygulamalarının yaptığı pek çok farklı iş türü vardır, ancak genel anlamda, bunu doğrudan kullanıcı arayüzüne temas eden ve dokunmayan çalışmalara bölebilirsiniz. Kullanıcı arayüzü çalışmaları şu şekildedir:
- Doğrudan DOM'ye dokunur.
- Bildirimler veya dosya sistemi erişimi gibi cihaz özelliklerine dokunan API'leri kullanmalıdır.
- Kullanıcı çerezleri, yerel depolama veya oturum depolaması gibi kimliklere dokunur.
- Medya öğelerini (ör. resim, ses veya video) yönetir.
- Onay vermek için kullanıcı müdahalesi gerektirecek güvenlik etkileri (ör. web seri API'si) içerir.
Kullanıcı arayüzü dışı çalışmalarda aşağıdakiler yer alabilir:
- Sadece hesaplamalar.
- Veri erişimi (getirme, IndexedDB vb.).
- Kripto.
- Mesajlaşma.
- Blob veya akış oluşturma ya da değiştirme.
Kullanıcı arayüzü olmayan işler genellikle kullanıcı arayüzü çalışmaları tarafından ayrılır: Kullanıcı, bir API için ağ isteğini tetikleyen bir düğmeyi tıklar. Bu işlem, daha sonra DOM'yi güncellemek için kullanılan ayrıştırılmış sonuçlar döndürür. Kod yazarken bu uçtan uca deneyim genellikle göz önünde bulundurulsa da akışın hiçbir bölümü genellikle dikkate alınmaz. Kullanıcı arayüzü işi ile kullanıcı arayüzü dışı çalışmalar arasındaki sınırlar, ana iş parçacığı karmaşıklığını azaltabileceğiniz ilk yer olduğundan, uçtan uca deneyimler kadar dikkate alınması gereken sınırlardır.
Tek bir göreve odaklanın
Kodu basitleştirmenin en basit yollarından biri, işlevleri parçalara ayırarak her birinin tek bir göreve odaklanmasını sağlamaktır. Görevler, uçtan uca deneyimden geçerek belirlenen sınırlara göre belirlenebilir:
- Öncelikle kullanıcı girişine yanıt verin. Bu, kullanıcı arayüzü çalışması.
- Ardından, bir API isteği gönderin. Bu, kullanıcı arayüzü kullanmadan gerçekleştirilir.
- Ardından, API isteğini ayrıştırın. Bu yine kullanıcı arayüzü dışındaki bir işlemdir.
- Ardından, DOM'de yapılan değişiklikleri belirleyin. Bu, kullanıcı arayüzü çalışması olabilir veya sanal DOM uygulaması gibi bir şey kullanıyorsanız kullanıcı arayüzü çalışması olmayabilir.
- Son olarak, DOM'de değişiklik yapın. Bu, kullanıcı arayüzü çalışması.
İlk net sınırlar, kullanıcı arayüzü işi ile kullanıcı arayüzü dışındaki çalışmalar arasındadır. Öyleyse yapılması gereken değerlendirme çağrıları var: Bir API isteğini yerine getirmek ve ayrıştırmak, yalnızca bir görev mi yoksa iki görev mi? DOM değişiklikleri, kullanıcı arayüzüyle ilgili olmayan işlerse API çalışmasıyla birlikte paket hâline getiriliyor mu? Aynı ileti dizisinde mi? Farklı bir ileti dizisinde mi? Burada uygun ayırma düzeyi, hem kod tabanınızı basitleştirmek hem de bunların parçalarını ana iş parçacığının dışına başarıyla taşıyabilmek için çok önemlidir.
Özelleştirilebilirlik
Büyük uçtan uca iş akışlarını daha küçük parçalara bölmek için kod tabanınızın uygunluğu üzerine düşünmeniz gerekir. İşlevsel programlamadan ipuçları almak istiyorsanız şunları yapabilirsiniz:
- Uygulamanızın yaptığı iş türlerini sınıflandırma.
- Bunlar için ortak giriş-çıkış arayüzleri oluşturma.
Örneğin, tüm API alma görevleri API uç noktasını alır ve bir standart nesne dizisi döndürür. Tüm veri işleme işlevleri ise standart nesnelerden oluşan bir diziyi alıp döndürür.
JavaScript'te, karmaşık JavaScript nesnelerini kopyalamak için hazırlanmış bir yapılandırılmış klon algoritması bulunur. Web çalışanları bunu ileti gönderirken, IndexedDB ise nesneleri depolamak için kullanır. Yapılandırılmış klonlama algoritmasıyla kullanabileceğiniz arayüzlerin seçilmesi, söz konusu arayüzlerin çalışmasını daha da esnek hale getirecektir.
Bunu göz önünde bulundurarak, kodunuzu kategorilere ayırarak ve bu kategoriler için ortak G/Ç arayüzleri oluşturarak composable işlevlerinden oluşan bir kitaplık oluşturabilirsiniz. Oluşturulabilir kod, basit kod tabanlarının ayırt edici bir özelliğidir. Birbirine "yan yana" oturup birbirlerinin üzerine inşa edilebilen serbest bir şekilde eşlenmiş, değiştirilebilir parçalardır. Ancak bu, güçlü bir şekilde birbirine bağlı olan ve bu nedenle kolayca ayrılamayan karmaşık kodlardır. Web'de ise composable kod, ana iş parçacığının aşırı çalışması veya olmaması arasındaki farkı ifade edebilir.
Oluşturabileceğiniz kodun bir kısmını ana ileti dizisinden çıkarmanın zamanı gelmiş demektir.
Karmaşıklığı azaltmak için web işçilerini kullanma
Çoğunlukla az kullanılan ancak yaygın olarak bulunan bir web özelliği olan web işçileri, işleri ana iş parçacığının dışına taşımanızı sağlar.
Web çalışanları, PWA'nın (bazı) JavaScript'i ana iş parçacığının dışında çalıştırmasını sağlar.
Üç tür çalışan vardır.
Web çalışanlarını tanımlarken en yaygın olarak düşünülen adanmış çalışanlar, PWA'nın çalışan tek bir örneğindeki tek bir komut dosyası tarafından kullanılabilir. Mümkün olduğunda, doğrudan DOM ile etkileşimde bulunmayan çalışmalar, performansı artırmak için bir web çalışanına taşınmalıdır.
Paylaşılan çalışanlar, özel çalışanlara benzer. Tek fark, birden fazla komut dosyasının bunları birden fazla açık pencerede paylaşabilmesidir. Bu, özel bir çalışanın avantajlarına ek olarak pencereler ile komut dosyaları arasında ortak bir durum ve dahili bağlam sağlar.
Örneğin, paylaşılan bir çalışan, PWA'nın IndexedDB'nin erişimini ve işlemlerini yönetebilir, ayrıca değişikliklere tepki vermesini sağlamak için tüm çağrı komut dosyalarında işlem sonuçlarını yayınlayabilir.
Son web çalışanı bu kursta kapsamlı bir şekilde ele alınmıştır: Ağ istekleri için proxy görevini gören ve tüm PWA örnekleri arasında paylaşılan Service Worker.
Kendiniz deneyin
Kod zamanı! Bu modülde öğrendiğiniz her şeyi temel alarak sıfırdan bir PWA oluşturun.