Giriş
Mobil web için geliştirme yapmak günümüzde çok popüler bir konu. Bu yıl, akıllı telefonlar PC'leri ilk kez 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 giderek daha önemli hale geldiği anlamına geliyor.
"Mobil" savaş alanı, çok sayıda geliştirici için hâlâ keşfedilmemiş bir alan. 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 buna 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 geliş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. Buradaki nokta, birçok sitenin aynı durumda olduğudur.
Bu makalede, html5rocks'un Android ve iOS cihazlar için optimize edilmiş mobil sürümünü nasıl oluşturduğumuz incelenmektedir. Farklılığı görmek için bu işletim sistemlerinden birini destekleyen bir cihazda html5rocks.com adresini yüklemeniz yeterlidir. m.html5rocks.com veya bu tür başka bir siteye 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 taşır ve medya sorgularıyla işlevlerini geliş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 sayede, içeriğin kendisini değiştirmek zorunda kalmadan içeriğin sunumunun belirli bir çıkış cihazı aralığına göre özelleştirilmesi sağlanı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 "el cihazı" olarak kabul ettiği cihazlar veya ekran genişliği en fazla 320 piksel olan cihazlar için geçerli olur.
<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şaretlememiz üzerinde önemli değişiklikler yapmak zorunda kalmadan düzeni değiştirmemize olanak tanıdılar. Bu gerçekten hayat kurtarıcıydı. 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 tanımlamıştır 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.
Etki: Mobil cihazlarda daha iyi görünmesi için base.css
'teki stilleri kademeli olarak geçersiz kılıyoruz (yalnızca gerektiğinde).
mobile.css
'ün zorunlu kıldığı stil değişikliklerinden bazıları:
- Sitedeki fazla boşlukları/dolguları azaltır. Küçük ekranlar, alan açısından avantaj sağlar.
:hover
durumunu 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 ÖZELLIK GRUPLARINA GÖRE ÖĞRENİN" bölümünü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) viewport mülkü. Görüntü alanı ayarlamak, tarayıcıya içeriğin cihazın ekranına nasıl sığması gerektiğini bildirir ve sitenin mobil cihazlar için optimize edildiğini belirtir. Ö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 düzeyde 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 belirtmesine olanak tanıyarak viewport 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
'dir.
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 cihazlar, bağlantılar için rel="apple-touch-icon"
(iOS) ve rel="apple-touch-icon-precomposed"
(Android) değerlerini de kabul eder. 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ırma yapmak daha kullanışlıdır. 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. Daha da kötüsü, farklı platformlarda bazen sayfanın yüklenmesi tamamlandıktan sonra bile ekranın üst kısmında büyük bir adres çubuğuyla karşılaşırsınız.
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 azaltma, bant genişliğinden tasarruf etme
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 para kaybettiriyor olabilirsiniz.
Aşağıda, html5rocks'ta ağ isteklerini en aza indirmek ve bant genişliğini azaltmak için uyguladığımız bazı yaklaşımlar 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 nedenle, 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. Çözüm, HTML bölümlerinin koşullu olarak atlanması için Django şablonumuzda bir "is_mobile" boole değişkeni 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ırma: Hem CSS hem de JS'yi işlediği için Closure compiler yerine YUI compressor 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 ek bir istek gönderir.
<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
- Kod güzelleştiricimiz ve Modernizr, hiç kullanılmamış olsalar bile her sayfaya dahil ediliyordu. Modernizr harika bir araçtır ancak her yükleme işleminde 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ı yalnızca gerçekten ihtiyaç duyulan sayfalara ekliyoruz. -2 istek :)
Ek performans düzenlemeleri:
- Tüm JS'ler (mümkün olduğunda) sayfanın en altına taşındı.
- 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 biçimlendirmeler mobil cihazlarda daha da maliyetlidir.
- Verimli olmayan istemci tarafı kodunu sunucuya aktardı. Daha ayrıntılı olarak, mevcut sayfanın gezinme stilini ayarlamak için şunu kontrol edin:
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'un mobil sürümü, ilk yüklemeyi hızlandırmak için uygulama önbelleğini kullanır ve kullanıcıların içeriği çevrimdışı okumasına olanak tanı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 söz konusu önbelleğe almayı önlemek için öncelikle App Engine'i manifest dosyalarını hiçbir zaman önbelleğe almaması için 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.