Giriş
Günümüzde mobil web için geliştirme yapmak çok sıcak bir konu. Bu yıl, ilk kez akıllı telefonlar PC'leri geride bıraktı. Web'de gezinmek için mobil cihaz kullanan kullanıcı sayısı giderek artıyor. Bu da geliştiricilerin sitelerini mobil tarayıcılar için optimize etmesinin kritik hale geldiği anlamına geliyor.
"Mobil" savaş alanı, çok sayıda geliştirici için hâlâ keşfedilmemiş bir yer. Birçok kullanıcının, mobil kullanıcıları tamamen göz ardı eden eski siteleri vardır. Bunun yerine, site öncelikle masaüstü tarayıcılar için tasarlanmış ve mobil tarayıcılarda kötü bir deneyim sunuyor. Bu site (html5rocks.com) de istisna değil. Lansman sırasında sitenin mobil sürümüne çok fazla emek harcamadık.
Mobil uyumlu html5rocks.com oluşturma
Bir alıştırma olarak, html5rocks'ı (mevcut bir HTML5 sitesi) alıp mobil uyumlu bir sürümle zenginleştirmenin ilginç olacağını düşündüm. Özellikle akıllı telefonları hedeflemek için gereken minimum iş miktarıyla ilgili endişelerim vardı. Bu alıştırmanın amacı, tamamen yeni bir mobil site oluşturmak ve iki kod tabanını yönetmek değildi. Bu işlem çok uzun sürer ve çok zaman kaybına neden olurdu. Sitenin yapısını (işaretleme) daha önce tanımlamıştık. Bir göz atıp (CSS) hissettik. Temel işlev (JS) mevcuttu. Birçok sitenin aynı teknede bulunduğunu söyleyebilirsiniz.
Bu makalede, html5rocks'ın Android ve iOS cihazlar için optimize edilmiş bir mobil sürümünü nasıl oluşturduğumuz incelenmektedir. Farkı görmek için, bu işletim sistemlerinden birini destekleyen bir cihaza html5rocks.com'u yüklemeniz yeterlidir. m.html5rocks.com adresine veya bu tür bir yapıya yönlendirme yoktur. html5rocks'u olduğu gibi alırsınız. Ayrıca, mobil cihazlarda harika görünen ve iyi çalışan bir çözümün avantajlarından da yararlanabilirsiniz.
CSS Medya Sorguları
HTML4 ve CSS2, medyaya bağımlı stil sayfalarını bir süredir destekliyor. Örneğin:
<link rel="stylesheet" media="print" href="printer.css">
baskı cihazlarını hedefler ve sayfa içeriği yazdırıldığında belirli bir stil sağlar. CSS3, medya türü fikrini bir adım daha ileri götürür ve medya sorgularıyla işlevlerini iyileştirir. Medya sorguları, stil sayfalarının daha hassas şekilde etiketlenmesine olanak tanıyarak medya türlerinin kullanışlılığını artırır. Bu da içeriğin kendisini değiştirmek zorunda kalmadan belirli bir çıkış cihazı yelpazesine göre özelleştirilmesine olanak tanır. Değiştirilmesi gereken mevcut bir düzen için mükemmel bir çözüm.
Ekran genişliğini, cihaz genişliğini, yönü vb. hedeflemek için harici stil sayfalarınızın media
özelliğinde medya sorgularını kullanabilirsiniz. Tam liste için W3C medya sorgusu spesifikasyonuna bakın.
Ekran boyutlarını hedefleme
Aşağıdaki örnekte phone.css
, tarayıcının "avuç içi" olarak kabul ettiği cihazlar veya ekranı 320 pikselden küçük olan cihazlar için geçerlidir.
<link rel='stylesheet'
media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>
Bir medya sorgusunun önüne "only
" anahtar kelimesinin eklenmesi, CSS3 uyumlu olmayan tarayıcıların kuralı yoksaymasına neden olur.
Aşağıdakiler, 641 piksel ile 800 piksel arasındaki ekran boyutlarını hedefler:
<link rel='stylesheet'
media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>
Medya sorguları, satır içi <style>
etiketlerinde de görünebilir. Aşağıdakiler, dikey yöndeyken all
medya türlerini hedefler:
<style>
@media only all and (orientation: portrait) { ... }
</style>
media="handheld"
Bir dakika durup media="handheld"
hakkında konuşmamız gerekiyor.
Android ve iOS, media="handheld"
değerini yok sayar. Kullanıcıların, media="screen"
hedefleyen stil sayfalarının sağladığı yüksek kaliteli içeriği kaçıracağı ve geliştiricilerin daha düşük kaliteli bir media="handheld"
sürümünü sürdürme olasılığının düşük olduğu iddia ediliyor. Bu nedenle, "tam web" sloganlarının bir parçası olarak çoğu modern akıllı telefon tarayıcısı, el stil sayfalarını yoksayar.
Bu özelliği mobil cihazları hedeflemek için kullanmak ideal olsa da çeşitli tarayıcılar bu özelliği farklı şekillerde uygulamıştır:
- Bazıları yalnızca el stil sayfasını okur.
- Bazıları, varsa yalnızca el stil sayfasını okur, aksi takdirde varsayılan olarak ekran stil sayfasını kullanır.
- Bazıları hem el stil sayfasını hem de ekran stil sayfasını okur.
- Bazıları yalnızca ekran stil sayfasını okur.
Opera Mini, media="handheld"
değerini yoksaymaz. Windows Mobile'un media="handheld"
değerini tanıması için ekran stil sayfasının media özelliği değerini büyük harflerle yazmanız gerekir:
<!-- media="handheld" trick for Windows Mobile -->
<link rel="stylesheet" href="screen.css" media="Screen">
<link rel="stylesheet" href="mobile.css" media="handheld">
html5rocks, medya sorgularını nasıl kullanır?
Medya sorguları, mobil html5rocks'ta yoğun olarak kullanılmaktadır. Django şablon işaretlememizde önemli değişiklikler yapmak zorunda kalmadan düzeni değiştirmemize olanak tanıdılar. Bu gerçekten hayat kurtarıcı bir destek oldu. Ayrıca, çeşitli tarayıcılarda destekleri oldukça iyi.
Her sayfanın <head>
bölümünde aşağıdaki stil sayfalarını görürsünüz:
<link rel='stylesheet'
media='all' href='/static/css/base.min.css' />
<link rel='stylesheet'
media='only screen and (max-width: 800px)' href='/static/css/mobile.min.css' />
base.css
, html5rocks.com'un ana görünümünü ve tarzını her zaman belirlemiştir. Ancak artık 800 piksel altındaki ekran genişlikleri için yeni stiller (mobile.css
) uyguluyoruz. Medya sorgusu, akıllı telefonları (~320 piksel) ve iPad'i (~768 piksel) kapsar.
Sonuç: Mobil cihazlarda daha iyi görünmek için base.css
ürünündeki stilleri (yalnızca gerektiğinde) kademeli olarak geçersiz kılıyoruz.
mobile.css
'ün zorunlu kıldığı stil değişikliklerinden bazıları:
- Site genelinde fazladan boşlukları/dolguyu azaltır. Küçük ekranlar alanın çok değerli olduğunu gösteriyor.
:hover
durumu kaldırır. Bu veriler dokunmatik cihazlarda hiçbir zaman görülmez.- Düzeni tek sütunlu olacak şekilde ayarlar. Bu konuyla ilgili daha fazla bilgiyi aşağıda bulabilirsiniz.
- Sitenin ana kapsayıcı div'i etrafındaki
box-shadow
öğesini kaldırır. Büyük kutu gölgeleri sayfa performansını düşürür. - Ana sayfadaki her bölümün sırasını değiştirmek için CSS esnek kutusu modeli
box-ordinal-group
kullanıldı. "BÜYÜK HTML5 ÖZELLİK GRUPLARINA GÖRE ÖĞRENİN" başlıklı bölümün ana sayfada "EĞİTİMLER" bölümünden önce, mobil sürümde ise bu bölümden sonra geldiğini göreceksiniz. Bu sıralama, mobil cihazlar için daha anlamlıydı ve işaretleme değişiklikleri gerektirmiyordu. CSS flexbox FTW! opacity
değişikliklerini kaldırır. Alfa değerlerini değiştirmek mobil cihazlarda performansı düşürür.
Mobil meta etiketler
Mobil WebKit, kullanıcılara belirli cihazlarda daha iyi bir tarama deneyimi sunan birkaç özelliği destekler.
Görüntü alanı ayarları
İlk meta ayar (ve en sık kullanacağınız ayar) görüntü alanı özelliğidir. Görüntü alanı ayarlamak, tarayıcıya içeriğin cihazın ekranına nasıl sığması gerektiğini söyler ve sitenin mobil cihazlar için optimize edildiğini bildirir. Örneğin:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
tarayıcıya, görüntü alanını 1 başlangıç ölçeğiyle cihazın genişliğine ayarlamasını söyler. Bu örnekte yakınlaştırmaya da izin verilir. Bu, web sitesi için istenebilecek ancak web uygulaması için istenmeyecek bir özelliktir. user-scalable=no
ile yakınlaştırmayı önleyebilir veya ölçeklendirmeyi belirli bir seviyede sınırlayabiliriz:
<meta name=viewport
content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">
Android, geliştiricilerin sitenin hangi ekran çözünürlüğü için geliştirildiğini belirtmelerine olanak tanıyarak görüntü alanı meta etiketini genişletir:
<meta name="viewport" content="target-densitydpi=device-dpi">
target-densitydpi
için olası değerler device-dpi
, high-dpi
,
medium-dpi
, low-dpi
'dır.
Web sayfanızı farklı ekran yoğunluklarına göre değiştirmek istiyorsanız -webkit-device-pixel-ratio
CSS medya sorgusunu ve/veya JavaScript'teki window.devicePixelRatio
mülkünü kullanın, ardından target-densitydpi
meta mülkünü device-dpi
olarak ayarlayın. Bu, Android'in web sayfanızda ölçeklendirme yapmasını engeller ve CSS ile JavaScript aracılığıyla her yoğunluk için gerekli düzenlemeleri yapmanıza olanak tanır.
Cihaz çözünürlüğünü hedefleme hakkında daha fazla bilgi için Android'in WebView belgelerine bakın.
Tam ekranda gezinme
iOS-sfic olan iki meta değer daha vardır. apple-mobile-web-app-capable
ve apple-mobile-web-app-status-bar-style
, sayfa içeriğini uygulama benzeri tam ekran modunda oluşturur ve durum çubuğunu yarı saydam hale getirir:
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
Kullanılabilir tüm meta seçenekleri hakkında daha fazla bilgi için Safari referans dokümanlarına bakın.
Ana ekran simgeleri
iOS ve Android cihazlarda bağlantılar için rel="apple-touch-icon"
(iOS) ve rel="apple-touch-icon-precomposed"
(Android) uygulamaları da kabul edilir. Bu yöntemler, kullanıcı sitenize yer işareti koyduğunda kullanıcının ana ekranında uygulama benzeri gösterişli bir simge oluşturur:
<link rel="apple-touch-icon"
href="/static/images/identity/HTML5_Badge_64.png" />
<link rel="apple-touch-icon-precomposed"
href="/static/images/identity/HTML5_Badge_64.png" />
html5rocks, mobil meta etiketlerini nasıl kullanır?
Tüm bunları bir araya getirerek html5rocks'un <head>
bölümündeki bir snippet'i aşağıda bulabilirsiniz:
<head>
...
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
<link rel="apple-touch-icon"
href="/static/images/identity/HTML5_Badge_64.png" />
<link rel="apple-touch-icon-precomposed"
href="/static/images/identity/HTML5_Badge_64.png" />
...
</head>
Dikey düzen
Küçük ekranlarda yatay kaydırmaktan çok dikey kaydırmanız önerilir. Mobil cihazlarda içeriğin tek sütunlu, dikey bir düzende tutulması tercih edilir. html5rocks için bu tür bir düzen oluşturmak üzere CSS3 medya sorgularını kullandık. Yine de işaretlemeyi değiştirmeden.
Mobil optimizasyonlar
Yaptığımız optimizasyonların çoğu, ilk başta yapılması gereken şeylerdi. Ağ isteklerinin sayısını azaltma, JS/CSS sıkıştırma, gzip sıkıştırma (App Engine'de ücretsizdir) ve DOM işlemlerini en aza indirme gibi işlemler. Bu teknikler yaygın en iyi uygulamalardır ancak siteyi hızlıca kullanıma sunma sürecinde bazen gözden kaçar.
Adres çubuğunu otomatik olarak gizleme
Mobil tarayıcılar, masaüstündeki muadillerinin sahip olduğu ekran alanından yoksundur. En kötü durum ise farklı platformlarda, bazen sayfanın yüklenmesi tamamlandıktan sonra bile ekranın üst kısmında büyük bir eski adres çubuğu belirir.
Bununla başa çıkmanın kolay yollarından biri, JavaScript kullanarak sayfayı kaydırmaktır.
Bir piksel bile kaydırmanız, can sıkıcı adres çubuğunu ortadan kaldırır.
html5rocks'ta adres çubuğunu zorla gizlemek için window
nesnesine bir onload
etkinlik işleyici ekledim ve sayfayı dikey olarak bir piksel kaydırdım:
// Hides mobile browser's address bar when page is done loading.
window.addEventListener('load', function(e) {
setTimeout(function() { window.scrollTo(0, 1); }, 1);
}, false);
Ayrıca bu dinleyiciyi, masaüstünde gerekli olmadığı için is_mobile
şablon değişkenimize sardık.
Ağ isteklerini azaltın, bant genişliğinden tasarruf edin
HTTP isteklerinin sayısını azaltmanın performansı büyük ölçüde artırabileceği bilinen bir gerçektir. Mobil cihazlar, tarayıcının kurabileceği eşzamanlı bağlantı sayısını daha da sınırlandırır. Bu nedenle, mobil siteler bu gereksiz isteklerin azaltılmasından daha da fazla yararlanır. Ayrıca, telefonlarda bant genişliği genellikle sınırlı olduğundan her bayttan tasarruf etmek çok önemlidir. Kullanıcılara masraf yapıyor olabilirsiniz.
Aşağıda ağ isteklerini en aza indirmek ve html5rocks'ta bant genişliğini azaltmak için benimsediğimiz yaklaşımlardan bazıları verilmiştir:
iframe'leri kaldırın - iframe'ler yavaştır! Gecikmemizin büyük bir kısmı, eğitim sayfalarındaki üçüncü taraf paylaşım widget'larından (Buzz, Google Friend Connect, Twitter, Facebook) kaynaklanıyordu. Bu API'ler
<script>
etiketleri aracılığıyla dahil edildi ve sayfanın hızını düşüren iframe'ler oluşturuyor. Widget'lar mobil cihazlarda kaldırıldı.display:none
: Belirli durumlarda, mobil profile uymayan işaretlemeleri gizliyorduk. Ana sayfanın üst kısmındaki dört yuvarlak kutu buna iyi bir örnektir:
Mobil sitede bu öğeler eksik. Kapsayıcıları display:none
ile gizlenmiş olsa bile tarayıcının her simge için istek göndermeye devam ettiğini unutmayın. Bu yüzden de bu düğmeleri
gizlemek yeterli değildi. Bu durum yalnızca bant genişliğini boşa harcamakla kalmaz, kullanıcı bu bant genişliğinin avantajlarından da yararlanamaz. Bu sorunun çözümü, HTML bölümlerini koşullu olarak çıkarmak için Django şablonumuzda bir "is_mobile" boole değeri oluşturmaktı.
Kullanıcı siteyi akıllı cihazda görüntülerken düğmeler gösterilmez.
Uygulama Önbelleği: Bu özellik yalnızca çevrimdışı destek sunmakla kalmaz, aynı zamanda daha hızlı bir başlatma sağlar.
CSS/JS sıkıştırması: Esas olarak hem CSS hem de JS'yi işlediği için Closure derleyici yerine YUI sıkıştırıcısını kullanıyoruz. Karşılaştığımız sorunlardan biri, satır içi medya sorgularının (stil sayfasının içinde görünen medya sorguları) YUI sıkıştırıcı 2.4.2'de çökmesiydi (bu soruna bakın). YUI Compressor 2.4.4 ve sonraki sürümlerin kullanılması sorunu çözdü.
Mümkün olduğunda CSS resim sprite'leri kullanın.
Resim sıkıştırma için pngcrush kullanıldı.
Küçük resimler için dataURI'ler kullanıldı. Base64 kodlama, görüntüye yaklaşık %30'un üzerinde boyut ekler ancak ağ isteğini kaydeder.
Google Özel Arama'yı
google.load()
ile dinamik olarak yüklemek yerine tek bir komut dosyası etiketi kullanarak otomatik olarak yükledi. İkincisi ise ekstra bir istekte bulunur.
<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
- Güzel kod yazıcımız ve Modernizr, hiç kullanılmamış olsalar bile her sayfaya ekleniyordu. Modernizr bir harikadır, ancak her yüklemede bir sürü test yapar. Bu testlerden bazıları DOM'da maliyetli değişiklikler yapar ve sayfa yükleme hızını düşürür. Artık bu kitaplıkları sadece gerçekten gerektiği sayfalara ekliyoruz. -2 istek :)
Ek performans düzenlemeleri:
- Tüm JS'ler sayfanın alt kısmına taşındı (mümkün olduğunda).
- Satır içi
<style>
etiketleri kaldırıldı. - Önbelleğe alınmış DOM aramaları ve en aza indirilmiş DOM işlemleri: DOM'a her dokunduğunuzda tarayıcı yeniden akış gerçekleştirir. Yeniden akışlar mobil cihazlarda daha da maliyetli olur.
- Verimli olmayan istemci tarafı kodunu sunucuya aktardı. Özellikle, geçerli sayfanın gezinme stilini ayarlamayla ilgili kontrol:
js var lis = document.querySelectorAll('header nav li'); var i = lis.length; while (i--) { var a = lis[i].querySelector('a'); var section = a.getAttribute("data-section"); if (new RegExp(section).test(document.location.href)) { a.className = 'current'; } }
- Sabit genişliğe sahip öğeler, değişken
width:100%
veyawidth:auto
ile değiştirildi.
Uygulama Önbelleği
HTML5rocks'ın mobil sürümü, ilk yüklemeyi hızlandırmak ve kullanıcıların içeriği çevrimdışı olarak okumasına olanak tanımak için Uygulama Önbelleği'ni kullanır.
Sitenizde AppCache'i uygularken manifesto dosyanızı önbelleğe almamanız (manifesto dosyasında açıkça veya ağır önbelleğe alma kontrol üstbilgileriyle dolaylı olarak) çok önemlidir. Manifest dosyanız tarayıcı tarafından önbelleğe alınırsa hata ayıklama işlemi bir kabusa dönüşür. iOS ve Android bu dosyayı önbelleğe alma konusunda özellikle iyi bir iş çıkarsa da masaüstü tarayıcılarda olduğu gibi önbelleği temizlemenin uygun bir yolunu sunmaz.
Sitemizde bu önbelleğe almayı önlemek için ilk olarak App Engine'i, manifest dosyalarını hiçbir zaman önbelleğe almayacak şekilde ayarladık:
- url: /(.*\.(appcache|manifest))
static_files: \1
mime_type: text/cache-manifest
upload: (.*\.(appcache|manifest))
expiration: "0s"
İkinci olarak, yeni bir manifest indirildiğinde kullanıcıyı bilgilendirmek için JS API'yi kullandık. Kullanıcılardan sayfayı yenilemeleri istenir:
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
}
}, false);
Ağ trafiğini azaltmak için manifest dosyanızı basit tutun. Yani, sitenizdeki her sayfayı belirtmeyin. Önemli resimleri, CSS ve JavaScript dosyalarını listelemeniz yeterlidir. Mobil tarayıcıyı her uygulama önbelleği güncellemesinde çok sayıda öğe indirmeye zorlamak istemezsiniz. Bunun yerine, kullanıcı bir html sayfasını ziyaret ettiğinde (ve sayfa bir <html manifest="...">
özelliği içeriyorsa) tarayıcının sayfayı dolaylı olarak önbelleğe alacağını unutmayın.