CSS-in-JS'nin takasları

Fotoğrafı çeken Artem Bali

Son zamanlarda, JS’deki CSS’ye genel bir bakış yazdım, çoğunlukla bu yaklaşımın çözmeye çalıştığı sorunlar hakkında konuşuyorum. Kütüphane yazarları, çözümlerinin değişmezliğini tanımlamak için nadiren zaman harcıyorlar. Bazen çok taraflı oldukları ve bazen kullanıcıların aracı nasıl uyguladıklarını bilmiyorlar. İşte bu, şu ana kadar gördüğüm haksızlıkları tarif etme girişimi. JSS'nin yazarı olduğumu söylemenin önemli olduğunu düşünüyorum, bu yüzden önyargılı olarak değerlendirilmeliyim.

Sosyal etki

Web platformunda çalışan ve herhangi bir JavaScript bilmeyen bir insan katmanı var. Bu insanlara HTML ve CSS yazmak için para alıyorlar. CSS-in-JS, geliştiricilerin iş akışı üzerinde büyük bir etki yarattı. Gerçekten dönüştürücü bir değişim, bazı insanlar geride bırakılmadan asla yapılamaz. JS'nin CSS'nin tek yol olması gerekip gerekmediğini bilmiyorum, ancak kitlesel evlat edinme, modern uygulamalarda CSS kullanımıyla ilgili sorunların açık bir işaretidir.

Sorunun büyük bir kısmı, CSS-in-JS'nin parladığı kullanım durumlarını doğru bir şekilde iletemememiz ve bunu bir görev için nasıl doğru kullanmamız gerektiğidir. Pek çok CSS in JS meraklısı, teknolojiyi teşvik etmede başarılı olmuştur, ancak pek çok eleştirmen araçlarda ucuz salıncaklar almadan yapıcı bir şekilde yapıtlardan bahsetmemiştir. Sonuç olarak, pek çok takas gizlemiş olduk ve açıklama ve geçici çözümler sağlamak için güçlü bir çaba göstermedik.

CSS-in-JS, karmaşık kullanım durumlarının kullanımını kolaylaştıracak bir girişimdir, bu yüzden gerekmediği yere itmeyin!

Çalışma zamanı maliyeti

Çalışma zamanında JavaScript'ten CSS oluşturulduğunda, tarayıcıda, genel bir ek yük vardır. Çalışma zamanı ek yükü, kütüphaneden kütüphaneye değişir. Bu iyi bir genel kriterdir, ancak kendi testlerinizi yaptığınızdan emin olun. Çalışma zamanındaki ana farklar, tam bir CSS şablon dizeleri ayrıştırma ihtiyacına, optimizasyon miktarına, dinamik stil uygulama detaylarına, karma algoritmaya ve çerçeve entegrasyon maliyetine bağlı olarak belirir. *

Potansiyel çalışma süresi ek yükünün yanı sıra, 4 farklı paketleme stratejisini de göz önünde bulundurmanız gerekir, çünkü bazı CSS-in-JS kütüphaneleri çoklu stratejileri destekler ve bunları uygulamak kullanıcıya bağlıdır. *

Strateji 1: Yalnızca çalışma zamanı üretimi

Çalışma zamanı CSS oluşturma, JavaScript'te bir CSS dizesi üreten bir tekniktir ve daha sonra bu dizeyi belgeye stil etiketi kullanarak enjekte eder. Bu teknik, satır içi stilleri değil, Stil Sayfası üretir.

Çalışma zamanı oluşturma işleminin değişmesi, belgenin yüklenmeye başlamasıyla tarzın ilk aşamasında stil içeriği sağlama yetersizliğidir. Bu yaklaşım genellikle hemen yararlı olabilecek içeriği olmayan uygulamalar için uygundur. Genellikle, bu tür uygulamalar, bir kullanıcı için gerçekten kullanışlı hale gelmeden önce kullanıcı etkileşimlerini gerektirir. Genellikle bu tür uygulamalar o kadar dinamik bir içerikle çalışır, yüklenir yüklenmez eskimiş olur, bu nedenle Twitter'ın başında bir güncelleme hattı kurmanız gerekir. Ek olarak, bir kullanıcı oturum açtığında, SEO için HTML sağlamaya gerek yoktur.

Etkileşim JavaScript gerektiriyorsa, uygulamanın hazır olması için paketin yüklenmesi gerekir. Örneğin, belgeye Slack yüklerken varsayılan bir kanalın içeriğini gösterebilirsiniz, ancak kullanıcının bundan hemen sonra kanalı değiştirmek istemesi muhtemeldir. Öyleyse ilk içeriği sadece hemen atmak için yüklediyseniz.

Bu tür uygulamaların algılanan performansı, uygulamanın gerçekte olduğundan daha anında hissetmesini sağlamak için yer tutucular ve diğer püf noktaları ile geliştirilebilir. Bu tür uygulamalar genellikle her zaman veri bakımından ağırdır, bu nedenle bir makale kadar hızlı bir şekilde kullanılamazlar.

Strateji 2: Kritik CSS ile Çalışma Zamanı Üretimi

Kritik CSS, sayfayı başlangıç ​​durumunda stillendirmek için gereken minimum CSS miktarıdır. Belgenin başındaki stil etiketi kullanılarak oluşturulur. Bu teknik, CSS-in-JS'de ve onsuzda yaygın olarak kullanılır. Her iki durumda da, bir kez Kritik CSS'nin bir parçası ve bir kez JavaScript veya CSS paketinin bir parçası olarak CSS kurallarını iki kez yüklemeniz muhtemeldir. Kritik CSS'nin boyutu, içeriğin miktarına bağlı olarak oldukça büyük olabilir. Genellikle, belge önbelleğe alınmaz.

Kritik CSS olmadan, çalışma zamanı CSS-in-JS ile statik içerik ağırlıklı tek sayfa uygulamasının içerik yerine yer tutucuları göstermesi gerekir. Bu kötü bir durumdur, çünkü bir kullanıcı için çok daha önce faydalı olmuş, düşük uçlu cihazlarda ve düşük bant genişlikli bağlantılarda erişilebilirliği arttırmıştır.

Kritik CSS ile çalışma zamanı CSS üretimi, daha sonraki bir aşamada, UI'yi ilk aşamada engellemeden yapılabilir. Yine de, yaklaşık 5+ yıllık düşük seviye mobil cihazlarda, JavaScript'ten CSS oluşturma performansı olumsuz etkileyebilir. Bu, üretilen CSS'nin miktarına ve kullanılan kütüphaneye bağlıdır, bu nedenle genelleştirilemez.

Bu stratejinin aşılması, Kritik CSS çıkarma işleminin maliyeti ve çalışma zamanı CSS oluşturma maliyetidir.

Strateji 3: Yalnızca oluşturma zamanı çıkarımı

Bu strateji, web üzerinde CSS-in-JS olmadan kullanılan varsayılan stratejidir. Bazı CSS in JS kitaplıkları, derleme sırasında statik CSS'yi ayıklamanıza izin verir. * Bu durumda, çalışma zamanı ek yükü söz konusu olmaz, bir bağlantı etiketi kullanılarak sayfada CSS oluşturulur. CSS üretiminin maliyeti önceden bir kez ödenir.

Burada 2 büyük hadiseler var:

  1. CSS-in-JS’nin çalışma zamanında sunduğu bazı dinamik API’leri kullanamazsınız, çünkü duruma erişemezsiniz. Çoğu zaman hala CSS özel özelliklerini kullanamazsınız, çünkü her tarayıcıda desteklenmezler ve yapı sırasında doğada çoklu dolgular yapılamazlar. Bu durumda, dinamik tema ve duruma göre stil oluşturma için geçici çözümler yapmanız gerekecektir. *
  2. Kritik CSS ve boş bir önbellek olmadan, ilk boyanın CSS paketiniz yüklenene kadar engellenir. Belgenin başındaki link öğesi, HTML'nin oluşturulmasını engeller.
  3. Tek sayfa uygulamalarında sayfa tabanlı paket bölme işlemiyle deterministik özellik

Strateji 4: Kritik CSS ile derleme zamanı çıkarma

Bu strateji aynı zamanda JS'de CSS'ye özgü değildir. Kritik CSS ile tam statik ekstraksiyon daha statik bir uygulamayla çalışırken en iyi performansı sunar. Bu yaklaşım, hala durdurulan bağlantı etiketinin belgenin altına taşınabilmesi haricinde, statik bir CSS'nin yukarıda belirtilen tradeoffetlerine sahiptir.

4 ana CSS oluşturma stratejisi vardır. Bunlardan sadece 2'si JS-in-JS'ye özgüdür ve hiçbiri tüm kütüphanelere uygulanmaz.

Ulaşılabilirlik

CSS-in-JS yanlış şekilde kullanıldığında erişilebilirliği azaltabilir. Bu, Critical CSS çıkartma işlemine gerek kalmadan büyük ölçüde statik bir içerik sitesi oluşturulduğunda gerçekleşir, böylece HTML, JavaScript paketi yüklenmeden ve değerlendirilmeden önce boyanamaz. Bu, belgenin başındaki engelleyici bir bağlantı etiketi kullanılarak çok büyük bir CSS dosyası oluşturulduğunda da olabilir; bu, geleneksel gömme ile ilgili en popüler sorun olan ve CSS-JS'ye özgü değildir.

Geliştiricilerin erişilebilirlik için sorumluluk almaları gerekir. Kararsız bir internet bağlantısının ekonomik açıdan zayıf ülkelerin sorunu olduğu konusunda hala yanlış yönlendirilmiş bir fikir var. Her gün bir yeraltı demiryolu sistemine ya da büyük bir binaya girdiğimizde bağlantı sorunlarımız olduğunu unutmaya meyilliyiz. Sabit bir kablosuz mobil bağlantı efsanedir. Sabit bir WiFi bağlantısına sahip olmak bile kolay değil, örneğin, 2,4 GHz bir WI-FI ağı mikrodalga fırından parazit alabilir!

Sunucu Tarafındaki İşleme ile Kritik CSS'nin Maliyeti

JS-in-JS için Kritik CSS çıkarma elde etmek için, SSR'ye ihtiyacımız var. SSR, sunucudaki bir uygulamanın belirli bir durumu için son HTML'yi oluşturma işlemidir. Aslında, oldukça karmaşık ve pahalı bir işlem olabilir. Her HTTP isteği için sunucuda belirli miktarda CPU çevrimi gerektirir.

CSS-in-JS genellikle HTML oluşturma boru hattına bağlı olduğu gerçeğinden yararlanır. * Hangi HTML'nin oluşturulduğunu ve hangi CSS'ye ihtiyaç duyduğunu bilir, böylece mutlak minimum miktarını üretebilir. Kritik CSS, sunucudaki HTML oluşturma işlemine ek yük ekler çünkü CSS'nin de son bir CSS dizesinde derlenmesi gerekir. Bazı senaryolarda, sunucuda önbelleğe almak zor veya hatta imkansızdır.

Kara kutu oluşturma

Kullanmakta olduğunuz bir CSS-in-JS kütüphanesinin CSS'inizi nasıl oluşturduğunu bilmeniz gerekir. Örneğin, insanlar Stilli Bileşenler ve Duygu'nun dinamik stilleri nasıl uyguladığının farkında değillerdir. Dinamik stiller, stiller bildiriminizin içinde JavaScript işlevlerinin kullanılmasına izin veren bir sözdizimidir. Bu işlevler sahne alanlarını kabul eder ve bir CSS bloğu döndürür.

Kaynak siparişin özgüllüğünü tutarlı tutmak için, yukarıda belirtilen kitaplıkların ikisi de, dinamik bir bildirim içeriyorsa ve bileşen yeni aksesuarlar ile güncellenirse, yeni bir CSS kuralı oluşturur. Ne demek istediğimi göstermek için, bu sanal alanı oluşturdum. JSS'de, yeni CSS kuralları oluşturmadan dinamik özellikleri güncellememize izin veren farklı bir tradeoff almaya karar verdik. *

Dik öğrenme eğrisi

CSS'ye aşina olan ancak JavaScript'te yeni olan insanlar için, CSS-in-JS ile hız kazanmaya başlamak için yapılan ilk çalışma miktarı oldukça büyük olabilir.

Karmaşık bir mantığın dahil olduğu noktaya kadar CSS-in-JS yazmak için profesyonel bir JavaScript geliştiricisi olmanıza gerek yok. Stilin karmaşıklığını genelleştiremeyiz, çünkü kullanım durumuna bağlı olarak. JS'de CSS'nin karmaşıklaştığı durumlarda, vanilya CSS ile uygulamanın daha da karmaşık olması muhtemeldir.

Temel CSS in JS stilleri için değişkenlerin nasıl bildirileceğini, şablon dizelerinin nasıl kullanılacağını ve JavaScript değerlerinin enterpolasyonunu bilmek gerekir. Nesne gösterimi kullanılıyorsa, JavaScript nesneleri ve kütüphaneye özgü nesne tabanlı sözdizimi ile nasıl çalışılacağını bilmek gerekir. Dinamik stillendirme söz konusuysa, JavaScript işlevlerini ve koşullarını nasıl kullanacağınızı bilmek gerekir.

Genel olarak bir öğrenme eğrisi var, inkar edemeyiz. Bu öğrenme eğrisi genellikle Sass öğrenmekten çok daha büyük değildir. Aslında, bunu göstermek için bu hakaretli kursu yarattım.

Birlikte çalışabilirlik yok

JS in CSS'lerinin çoğu bir arada çalışamaz. Bu, bir kütüphane kullanarak yazılmış stillerin farklı bir kütüphane kullanarak oluşturulamayacağı anlamına gelir. Pratik olarak, tüm uygulamanızı bir uygulamadan diğerine kolayca geçiremezsiniz. Ayrıca, CSS'niz için yerleşik bir statik özütleme işlemi yapmadığınız sürece, UI'nızı NPM üzerinde kolayca seçemeyeceğiniz anlamına gelir.

Bu sorunu çözmesi beklenen ISTF formatı üzerinde çalışmaya başladık ancak maalesef üretime hazır bir duruma getirmek için henüz zamanımız olmadı. *

Kamusal alanda yeniden kullanılabilir çerçeve agnostik UI bileşenlerinin paylaşılmasının hala genel olarak çözülmesi zor bir sorun olduğunu düşünüyorum.

Güvenlik riskleri

CSS-in-JS ile güvenlik sızıntıları ortaya çıkabilir. Herhangi bir istemci tarafı uygulamada olduğu gibi, her zaman oluşturmadan önce kullanıcı girdisinden kaçmanız gerekir.

Bu makale size daha fazla içgörü ve bazı tahrif edici örnekler sunacaktır.

Okunamayan sınıf isimleri

Bazı insanlar hala web üzerinde anlamlı okunabilir sınıf isimleri bulundurmamızın önemli olduğunu düşünüyor. Şu anda, birçok CSS-in-JS kütüphanesi geliştirme modundaki bildirim adına veya bileşen adına bağlı olarak anlamlı sınıf adları sağlar. Hatta bazıları sınıf ismi üreteci işlevini kişiselleştirmenize izin veriyor.

Yine de üretim modunda, çoğu daha küçük bir taşıma yükü için daha kısa isimler üretir. Bu, kütüphane kullanıcısının gerektiğinde kütüphaneyi yapması ve özelleştirmesi gereken bir tradeoffdur.

Sonuç

Tradeoffs var ve muhtemelen hepsinden bahsetmedim bile. Ancak çoğu, evrensel olarak tüm JS'deki CSS'lere uygulanmaz. Hangi kütüphaneyi kullandığınıza ve nasıl kullandığınıza bağlı.

* Bu cümleyi açıklamak için özel bir yazı alacak. Hangisini daha fazla okumak istediğinizi Twitter'da (@ oleg008) bana bildirin.