Pendekatan yang tidak responsif untuk membuat aplikasi web lintas perangkat

Kueri media memang bagus, tapi...

Kueri media luar biasa, sebuah berkat bagi developer situs yang ingin melakukan sedikit penyesuaian pada stylesheet mereka untuk memberikan pengalaman yang lebih baik bagi pengguna di berbagai ukuran perangkat. Kueri media pada dasarnya memungkinkan Anda menyesuaikan CSS situs, bergantung pada ukuran layar. Sebelum mempelajari artikel ini lebih lanjut, pelajari desain responsif lebih lanjut dan baca beberapa contoh penggunaan kueri media di sini: mediaqueri.es.

Seperti yang disebutkan Brad Frost dalam artikel sebelumnya, mengubah tampilan hanyalah salah satu dari banyak hal yang perlu dipertimbangkan saat membuat web seluler. Jika satu-satunya hal yang Anda lakukan saat membuat situs seluler adalah menyesuaikan tata letak dengan kueri media, situasi berikut akan terjadi:

  • Semua perangkat mendapatkan JavaScript, CSS, dan aset (gambar, video) yang sama, sehingga waktu pemuatan menjadi lebih lama dari yang diperlukan.
  • Semua perangkat mendapatkan DOM awal yang sama, yang berpotensi memaksa developer untuk menulis CSS yang terlalu rumit.
  • Sedikit fleksibilitas untuk menentukan interaksi kustom yang disesuaikan dengan setiap perangkat.

Aplikasi web membutuhkan lebih dari sekadar kueri media

Jangan salah paham. Saya tidak menyukai desain responsif melalui kueri media, dan benar-benar berpikir bahwa desain responsif memiliki peranan Selain itu, beberapa masalah yang disebutkan di atas dapat diselesaikan dengan pendekatan seperti gambar responsif, pemuatan skrip dinamis, dll. Namun, pada titik tertentu, Anda mungkin akan melakukan terlalu banyak perubahan inkremental, dan mungkin akan lebih baik jika menyajikan versi yang berbeda.

Karena UI yang Anda build semakin kompleks, dan Anda cenderung menggunakan aplikasi web satu halaman, Anda pasti ingin melakukan lebih banyak hal untuk menyesuaikan UI untuk setiap jenis perangkat. Artikel ini akan menunjukkan cara melakukan penyesuaian tersebut dengan mudah. Pendekatan umum ini melibatkan klasifikasi perangkat pengunjung Anda ke dalam class perangkat yang tepat, dan menayangkan versi yang sesuai ke perangkat tersebut, sekaligus memaksimalkan penggunaan ulang kode antar-versi.

Kelas perangkat apa yang Anda targetkan?

Ada banyak perangkat yang terhubung ke internet, dan hampir semuanya memiliki browser. Detailnya terletak pada keberagamannya: laptop Mac, workstation Windows, iPhone, iPad, ponsel Android dengan input sentuh, roda scroll, keyboard, input suara, perangkat dengan sensitivitas tekanan, smartwatch, pemanggang roti dan lemari es, dan banyak lagi. Beberapa perangkat ini ada di mana-mana, sementara perangkat lainnya sangat langka.

Berbagai perangkat.
Berbagai perangkat (sumber).

Untuk menciptakan pengalaman pengguna yang baik, Anda perlu mengetahui siapa pengguna Anda dan perangkat apa yang mereka gunakan. Jika Anda mem-build antarmuka pengguna untuk pengguna desktop dengan mouse dan keyboard lalu memberikannya kepada pengguna smartphone, antarmuka tersebut akan menjengkelkan karena dirancang untuk ukuran layar lain, dan modalitas input lainnya.

Ada dua ujung ekstrem dalam spektrum pendekatan:

  1. Buat satu versi yang berfungsi di semua perangkat. UX akan mengalami akibatnya, karena perangkat yang berbeda memiliki pertimbangan desain yang berbeda pula.

  2. Buat versi untuk setiap perangkat yang ingin Anda dukung. Proses ini memerlukan waktu lama, karena Anda akan mem-build terlalu banyak versi aplikasi. Selain itu, saat smartphone baru berikutnya tiba (yang terjadi kira-kira setiap minggu), Anda akan dipaksa untuk membuat versi lain.

Ada konsekuensi mendasar di sini: semakin banyak kategori perangkat yang Anda miliki, semakin baik pengalaman pengguna yang dapat Anda berikan, tetapi semakin banyak pekerjaan yang diperlukan untuk merancang, menerapkan, dan memelihara.

Membuat versi terpisah untuk setiap class perangkat yang Anda tentukan mungkin merupakan ide yang bagus untuk alasan performa, atau jika versi yang ingin Anda tayangkan ke class perangkat yang berbeda sangat bervariasi. Jika tidak, desain web responsif adalah pendekatan yang sangat wajar.

Solusi potensial

Inilah komprominya: klasifikasikan perangkat ke dalam kategori, dan rancang pengalaman terbaik untuk setiap kategori. Kategori yang Anda pilih tergantung pada produk dan target pengguna Anda. Berikut adalah contoh klasifikasi yang mencakup perangkat populer yang ada saat ini.

  1. layar kecil + sentuh (sebagian besar ponsel)
  2. perangkat layar besar + sentuh (kebanyakan tablet)
  3. perangkat layar besar + keyboard/mouse (sebagian besar desktop/laptop)

Ini hanyalah salah satu dari banyak kemungkinan pengelompokan, tetapi yang paling masuk akal pada saat penulisan ini. Yang tidak ada dalam daftar di atas adalah perangkat seluler tanpa layar sentuh (misalnya, ponsel menengah, beberapa pembaca eBook khusus). Namun, sebagian besar software tersebut diinstal dengan software navigasi keyboard atau pembaca layar, yang akan berfungsi dengan baik jika Anda membuat situs dengan mempertimbangkan aksesibilitas.

Contoh aplikasi web khusus faktor bentuk

Ada banyak contoh properti web yang menyajikan versi yang benar-benar berbeda untuk berbagai faktor bentuk. Pencarian Google melakukan hal ini, begitu pula Facebook. Pertimbangan untuk hal ini mencakup performa (pengambilan aset, halaman rendering) dan pengalaman pengguna yang lebih umum.

Dalam dunia aplikasi native, banyak developer memilih untuk menyesuaikan pengalaman mereka dengan class perangkat. Misalnya, Flipboard untuk iPad memiliki UI yang sangat berbeda dibandingkan dengan Flipboard di iPhone. Versi tablet dioptimalkan untuk penggunaan dua tangan dan membalik horizontal, sedangkan versi ponsel ditujukan untuk interaksi satu tangan dan balik vertikal. Banyak aplikasi iOS lainnya juga menyediakan versi ponsel dan tablet yang sangat berbeda, seperti Things (daftar tugas), dan Showyou (video sosial), yang ditampilkan di bawah ini:

Penyesuaian UI yang signifikan untuk ponsel dan tablet.
Penyesuaian UI yang signifikan untuk ponsel dan tablet.

Pendekatan #1: Deteksi sisi server

Di server, kita memiliki pemahaman yang jauh lebih terbatas tentang perangkat yang sedang kita tangani. Mungkin petunjuk paling berguna yang tersedia adalah string agen pengguna, yang disediakan melalui header Agen Pengguna pada setiap permintaan. Oleh karena itu, pendekatan sniffing UA yang sama akan berfungsi di sini. Faktanya, project DeviceAtlas dan WURFL sudah melakukannya (dan memberikan banyak informasi tambahan tentang perangkat).

Sayangnya, masing-masing hal tersebut memiliki tantangan tersendiri. WURFL sangat besar, berisi XML 20 MB, yang berpotensi menimbulkan overhead sisi server yang signifikan untuk setiap permintaan. Ada project yang memisahkan XML karena alasan performa. DeviceAtlas bukan open source, dan memerlukan lisensi berbayar untuk digunakan.

Ada juga alternatif yang lebih sederhana dan gratis, seperti project Deteksi Browser Seluler. Kelemahannya, tentu saja, deteksi perangkat pasti akan kurang komprehensif. Selain itu, kode ini hanya membedakan antara perangkat seluler dan non-seluler, sehingga memberikan dukungan tablet terbatas hanya melalui serangkaian penyesuaian ad-hoc.

Pendekatan #2: Deteksi sisi klien

Kita bisa mempelajari banyak hal tentang browser dan perangkat pengguna dengan menggunakan deteksi fitur. Hal utama yang perlu kami tentukan adalah apakah perangkat memiliki kemampuan sentuh, dan apakah menggunakan layar berukuran besar atau kecil.

Kita perlu menggambar garis di suatu tempat untuk membedakan perangkat sentuh kecil dan besar. Bagaimana dengan casing tepi seperti Galaxy Note 5"? Gambar berikut menunjukkan sejumlah perangkat Android dan iOS populer yang di-overlay (dengan resolusi layar yang sesuai). Tanda bintang menunjukkan bahwa perangkat memiliki kepadatan dua kali lipat atau dapat muncul dua kali lipat. Meskipun kepadatan piksel dapat ditingkatkan dua kali lipat, CSS tetap melaporkan ukuran yang sama.

Pengesampingan singkat tentang piksel di CSS: piksel CSS di web seluler tidak sama dengan piksel layar. Perangkat retina iOS memperkenalkan praktik menggandakan kepadatan piksel (misalnya, iPhone 3GS vs 4, iPad 2 vs 3). UA Safari Seluler retina masih melaporkan lebar perangkat yang sama agar web tidak rusak. Seperti perangkat lain (mis., Android) mendapatkan tampilan beresolusi lebih tinggi, sedangkan trik lebar perangkat yang sama.

Resolusi perangkat (dalam piksel).
Resolusi perangkat (dalam piksel).

Namun, mempersulit keputusan ini adalah pentingnya mempertimbangkan mode potret dan lanskap. Kita tidak ingin memuat ulang halaman atau memuat skrip tambahan setiap kali kita mengubah orientasi perangkat, meskipun kita mungkin ingin merender halaman dengan cara yang berbeda.

Dalam diagram berikut, persegi mewakili dimensi maksimum setiap perangkat, sebagai hasil dari overlay garis luar potret dan lanskap (dan melengkapi persegi):

Resolusi potret + lanskap (dalam piksel)
Potret + resolusi lanskap (dalam piksel)

Dengan menyetel ambang batas ke 650px, kami mengklasifikasikan iPhone, Galaxy Nexus sebagai smalltouch, dan iPad, Galaxy Tab sebagai "tablet". Dalam hal ini, Catatan Galaxy androgini diklasifikasikan sebagai "ponsel", dan akan mendapatkan tata letak ponsel.

Jadi, strategi yang wajar mungkin terlihat seperti ini:

if (hasTouch) {
  if (isSmall) {
    device = PHONE;
  } else {
    device = TABLET;
  }
} else {
  device = DESKTOP;
}

Lihat contoh minimal cara kerja pendekatan deteksi fitur.

Pendekatan alternatifnya adalah menggunakan sniffing UA untuk mendeteksi jenis perangkat. Pada dasarnya, Anda membuat kumpulan heuristik dan mencocokkannya dengan navigator.userAgent pengguna. Kode semu terlihat seperti ini:

var ua = navigator.userAgent;
for (var re in RULES) {
  if (ua.match(re)) {
    device = RULES[re];
    return;
  }
}

Lihat contoh cara kerja pendekatan deteksi UA.

Catatan tentang pemuatan sisi klien

Jika melakukan deteksi UA di server, Anda dapat menentukan CSS, JavaScript, dan DOM yang akan ditayangkan saat mendapatkan permintaan baru. Namun, jika Anda melakukan deteksi sisi klien, situasinya lebih kompleks. Anda memiliki beberapa opsi:

  1. Alihkan ke URL khusus jenis perangkat yang berisi versi untuk jenis perangkat ini.
  2. Memuat aset khusus jenis perangkat secara dinamis.

Pendekatan pertama mudah dilakukan, sehingga memerlukan pengalihan seperti window.location.href = '/tablet'. Namun, lokasi kini akan memiliki informasi jenis perangkat ini yang ditambahkan, jadi sebaiknya Anda menggunakan History API untuk membersihkan URL Anda. Sayangnya, pendekatan ini melibatkan pengalihan, yang dapat berjalan lambat, terutama pada perangkat seluler.

Pendekatan kedua sedikit lebih rumit untuk diterapkan. Anda memerlukan mekanisme untuk memuat CSS dan JS secara dinamis, dan (bergantung pada browser), Anda mungkin tidak dapat melakukan hal-hal seperti menyesuaikan <meta viewport>. Juga, karena tidak ada pengalihan, Anda akan terjebak dengan HTML asli yang ditayangkan. Tentu saja, Anda dapat memanipulasinya dengan JavaScript, tetapi ini mungkin lambat dan/atau tidak elegan, bergantung pada aplikasi Anda.

Menentukan klien atau server

Berikut adalah konsekuensi di antara pendekatan tersebut:

Klien Pro:

  • Lebih siap untuk masa depan karena didasarkan pada ukuran/kemampuan layar daripada UA.
  • Tidak perlu terus-menerus memperbarui daftar UA.

Server pro:

  • Kontrol penuh atas versi yang akan ditayangkan ke perangkat.
  • Performa yang lebih baik: tidak perlu pengalihan klien atau pemuatan dinamis.

Preferensi pribadi saya adalah memulai dengan device.js dan deteksi sisi klien. Seiring berkembangnya aplikasi Anda, jika Anda menganggap pengalihan sisi klien sebagai kelemahan performa yang signifikan, Anda dapat dengan mudah menghapus skrip device.js, dan menerapkan deteksi UA di server.

Memperkenalkan device.js

Device.js adalah titik awal untuk melakukan deteksi perangkat semantik berbasis kueri media tanpa memerlukan konfigurasi sisi server khusus, sehingga menghemat waktu dan tenaga yang diperlukan untuk melakukan penguraian string agen pengguna.

Intinya adalah Anda menyediakan markup yang mudah digunakan mesin telusur (link rel=alternate) di bagian atas <head> yang menunjukkan versi situs yang ingin Anda berikan.

<link rel="alternate" href="http://foo.com" id="desktop"
    media="only screen and (touch-enabled: 0)">

Selanjutnya, Anda dapat melakukan deteksi UA sisi server dan menangani pengalihan versi sendiri, atau menggunakan skrip device.js untuk melakukan pengalihan sisi klien berbasis fitur.

Untuk informasi selengkapnya, lihat halaman project device.js, dan juga aplikasi palsu yang menggunakan device.js untuk pengalihan sisi klien.

Rekomendasi: MVC dengan tampilan khusus faktor bentuk

Sekarang Anda mungkin berpikir bahwa saya akan memberi tahu Anda untuk mem-build tiga aplikasi yang benar-benar terpisah, satu untuk setiap jenis perangkat. Tidak! Berbagi kode adalah kuncinya.

Semoga Anda telah menggunakan framework mirip MVC, seperti Backbone, Ember, dll. Jika sudah pernah, Anda sudah memahami prinsip pemisahan fokus, khususnya bahwa UI (lapisan tampilan) harus dipisahkan dari logika Anda (lapisan model). Jika ini baru bagi Anda, mulailah dengan beberapa resource di MVC dan MVC di JavaScript ini.

Cerita lintas perangkat sangat cocok dengan framework MVC Anda yang ada. Anda dapat dengan mudah memindahkan tampilan ke beberapa file terpisah, yang menghasilkan tampilan kustom untuk setiap jenis perangkat. Kemudian, Anda dapat menyajikan kode yang sama ke semua perangkat, kecuali lapisan tampilan.

MVC lintas perangkat.
MVC lintas perangkat.

Project Anda mungkin memiliki struktur berikut (tentu saja, Anda bebas memilih struktur yang paling masuk akal, bergantung pada aplikasi Anda):

model/ (model bersama) item.js item-collection.js

controller/ (pengontrol bersama) item-controller.js

version/ (perangkat khusus perangkat) tablet/ desktop/ phone/ (kode khusus ponsel) style.css index.html views/ item.js item-list.js

Dengan struktur semacam ini, Anda dapat mengontrol sepenuhnya aset yang dimuat oleh setiap versi, karena Anda memiliki HTML, CSS, dan JavaScript kustom untuk setiap perangkat. Cara ini sangat efektif, dan dapat menghasilkan cara pengembangan yang paling ramping dan berperforma terbaik untuk web lintas perangkat, tanpa mengandalkan trik seperti gambar adaptif.

Setelah menjalankan alat build favorit, Anda akan menyambungkan dan meminifikasi semua JavaScript dan CSS menjadi satu file agar pemuatan lebih cepat, dengan HTML produksi yang terlihat seperti berikut (untuk ponsel, menggunakan device.js):

<!doctype html>
<head>
  <title>Mobile Web Rocks! (Phone Edition)</title>

  <!-- Every version of your webapp should include a list of all
        versions. -->
  <link rel="alternate" href="http://foo.com" id="desktop"
      media="only screen and (touch-enabled: 0)">
  <link rel="alternate" href="http://m.foo.com" id="phone"
      media="only screen and (max-device-width: 650px)">
  <link rel="alternate" href="http://tablet.foo.com" id="tablet"
      media="only screen and (min-device-width: 650px)">

  <!-- Viewport is very important, since it affects results of media
        query matching. -->
  <meta name="viewport" content="width=device-width">

  <!-- Include device.js in each version for redirection. -->
  <script src="device.js"></script>

  <link rel="style" href="phone.min.css">
</head>
<body>
  <script src="phone.min.js"></script>
</body>

Perhatikan bahwa kueri media (touch-enabled: 0) tidak standar (hanya diterapkan di Firefox di belakang awalan vendor moz), tetapi ditangani dengan benar (berkat Modernizr.touch) oleh device.js.

Penggantian versi

Deteksi perangkat terkadang dapat salah, dan dalam beberapa kasus, pengguna mungkin lebih suka melihat tata letak tablet di ponsel mereka (mungkin mereka menggunakan Galaxy Note). Oleh karena itu, penting untuk memberi pengguna pilihan versi situs yang akan digunakan jika mereka ingin menggantinya secara manual.

Pendekatan biasanya adalah memberikan link ke versi desktop dari versi seluler Anda. Ini cukup mudah untuk diterapkan, tetapi device.js mendukung fungsi ini dengan parameter GET device.

Penutup

Singkatnya, saat mem-build UI satu halaman lintas perangkat, yang tidak cocok dengan dunia desain responsif, lakukan ini:

  1. Memilih serangkaian class perangkat yang akan didukung, dan kriteria untuk mengklasifikasikan perangkat ke dalam class.
  2. Bangun aplikasi MVC Anda dengan pemisahan fokus yang kuat, yang memisahkan tampilan dari codebase lainnya.
  3. Gunakan device.js untuk melakukan deteksi class perangkat sisi klien.
  4. Jika sudah siap, kemas skrip dan stylesheet Anda ke dalam salah satu masing-masing per class perangkat.
  5. Jika performa pengalihan sisi klien menjadi masalah, tinggalkan device.js dan beralihlah ke deteksi UA sisi server.