Develoka

Baca Artikel

  •     Lihat Daftar Artikel
  • Menjajal Imba yang mengklaim lebih cepat 20x lipat dari Vue dan React

    Sebuah ulasan ringan dari sudut pandang teknis

    by rmdwirizki — Posted on May 15, 2018

    Imba adalah sebuah "bahasa baru" untuk pengembangan aplikasi web. Begitu deskripsi yang tertera di halaman github-nya. Maksudnya bahasa baru seperti Web Assembly? bukan, bahasa untuk browser ya apalagi kalo bukan javascript. Kalo saya liat mirip-mirip dengan coffescript, yaitu sebuah precompiler yang mengkonversi kode .imba menjadi .js. Tapi karena imba meng-cover masalah penggunaan data binding, manipulasi DOM dan routing, maka Imba dapat bekerja tak ubahnya seperti frontend framework lain (sebut saja React, Angular, Vue).

    Lalu apa yang menarik dari Imba? selain dari nama uniknya yang terkesan angkuh karena mengaku sebagai "dewa" (istilah hiperbola para gamer), ada dua hal yang membuat Imba menarik untuk dicoba, yaitu syntax dan mekanisme atau cara kerjanya.

    Syntax

    Terinspirasi dari React dan Ruby, Imba menggunakan markup berbasis indentasi seperti kebanyakan bahasa pemrograman fungsional (Off-side rule) yang dikombinasikan dengan .jsx milik React.

    # Classes
    class Todo
        # automatic getter/setter declaration
        prop title
    
        def initialize title
            # instance variables
            @title = title
            @completed = no
    
        def complete
            @completed = yes
    
    # Tags
    var item =  "This is a div"
    var list =  for item in ["one","two","three"]
        
  • item
  • Hasil compile-nya juga masih terbaca. Contoh kode imba:

    tag Component
        def render
            
                 "Welcome"
                 "I am a component"
    

    Di-compile menjadi javascript:

    var Component = Imba.defineTag('Component', function(tag){
        tag.prototype.render = function (){
            var $ = this.$;
            return this.setChildren($.$ = $.$ || [
                createElement('h1',$,0,this).flag('title').setText("Welcome"),
                createElement('p',$,1,this).flag('desc').setText("I am a component")
            ]).synced();
        };
    });
    

    Abaikan simbol dollar-nya, itu hanya nama variabel reference sebagai representasi DOM node. Tapi sisanya masih kebacalah ya?, Imba hanya mengandalkan API DOM sederhana dari browser, tidak ada yang baru disini. Setiap elemen HTML yang ditulis diubah menjadi method berantai dalam javascript untuk memanipulasi DOM, seperti createElement, setText, setContent dan sebagainya. Semua query selector tidak diperlukan karena sudah disimpan dalam memori melalui variabel reference tadi, terutama untuk elemen yang bersifat statis, ini yang menyebabkan performanya cepat (kita akan bahas di bab berikutnya).

    Lihat dokumentasinya disini, syntax-nya deklaratif dan cukup semantic jadi gampang adaptasinya. Saya udah coba bikin aplikasi sederhana tentang tes mengetik cepat pake Imba (liat di github), jujur pengerjaannya sangat cepat, karena tidak begitu banyak fitur atau siklus khusus yang kompleks. Jika sudah familiar dengan javascript, tidak butuh waktu lama untuk bisa beradaptasi.

    Mekanisme dan Performa

    Oke kita langsung aja masuk ke pembahasan utamanya. Jadi pada tahun 2015, Imba sempat menuai pertikaian dari berbagai developer karena klaim mereka yang mengatakan lebih cepat dari React 35 kali lipat di HN (Hacker News). Lihat benchmark-nya disini.

    Screenshot

    Banyak yang menganggap bahwa perbandingannya tidak fair dan terlalu berlebihan, kalau kalian ikutin diskusinya lumayan panas haha. Sebagian besar frontend developer sepertinya sudah mengalami fenomena yang bernama framework fatigue, tapi menurut saya itu bukan alasan yang baik untuk menolak hal baru. Seru sih ngeliat developer fanatik membela karyanya masing-masing, kita jadi tau banyak hal soal perspektif framework dari sudut pandang yang beragam.

    Itu kasus tahun 2015, saat ini Imba sudah banyak mengalami perkembangan dari segi dokumentasi dan telah memperbarui benchmark-nya (lihat disini).

    Benchmark Imba terbaru

    Kenapa performanya bisa secepat itu? author imba menjelaskannya dalam screencast berikut: https://scrimba.com/p/c6B9rAM.

    Saya akan coba menguraikan penjalasan screencast tadi berdasarkan pemahaman saya sendiri (CMIIW). Jadi perbedaan utama antara mekanisme Imba dengan framework lain (sebut saja React) adalah pada proses DOM Diffing atau DOM Reconciler. Jika Polymer memanfaatkan Shadow DOM dan React atau Vue menggunakan Virtual DOM, Imba menggunakan Inline Cached DOM. Seperti yang kita ketahui bahwa masalah utama yang berusaha dipecahkan oleh berbagai frontend framework modern (khususnya dalam membuat SPA) adalah masalah repaint dan reflow pada web browser yang menjadi terasa berat tergantung dari banyaknya perubahan konten DOM.

    Virtual DOM pada React, umumnya memiliki alur sebagai berikut:

    1. Dirty checking, ketika ada component yang diduga akan melakukan peubahan konten (misal: ada kode this.setState() di salah satu fungsinya), maka komponen tersebut akan ditandai sebagai dirty component
    2. Batch Update, yang dilakukan React dalam beberapa interval waktu tertentu
    3. Pemeriksaan beberapa component yang harus di-update, seperti dirty component, pending component dan forced component
    4. Dan beberapa pemeriksaan lainnya sampai pada fungsi render

    Pada fungsi render terdapat tiga fungsi utama, yaitu:

    1. Rebuild Virtual DOM, yaitu memperbarui konten virtual dom berdasarkan dirty component atau component lain yang akan di-update. Jadi component yang kontennnya tidak ada perubahan tidak perlu di overwrite ke dalam virtual dom. Kalo belum kebayang, anggap aja virtual dom sebuah variabel js biasa, tapi isinya adalah replika keseluruhan pohon dom node di halaman web.
    2. DOM Diffing, dengan algoritma khusus, virtual dom akan dibandingkan dengan actual dom (yang bukan replika) untuk mendapat reference dari node pada actual dom yang akan diubah.
    3. DOM Reconciliation, melakukan iterasi berdasarkan banyaknya reference node pada actual dom kemudian update konten node tersebut. Bisa dibayangkan seperti melakukan setText atau setContent kalo jQuery mungkin seperti .html('new content').

    Kurang lebih seperti itu, meskipun proses aslinya lebih kompleks dari yang bisa saya terangkan namun semua itu berjalan lebih cepat dari kelihatannya. Lalu gimana Imba dengan Inline DOM-nya?

    Teknik yang digunakan sebenarnya sangat sederhana. Imba hanya memangkas sebagian besar proses iterasi tersebut. Hapus batch update, hilangkan beberapa pemeriksaan, hapus juga rebuild virtual dom dan dom diffing. Maka proses yang tersisa adalah dirty checking dan dom reconciliation. Misal kita pakai contoh kode ini:

    var state = {status: "ok"}
    
    tag App
        def render
            
          # Contoh elemen statis
                 "Header"
          # Contoh elemen dinamis
                 state:status
    
    Imba.mount 
    

    Div yang pertama (dengan class header) isinya statis dan div yang kedua (dengan class status) isinya dinamis, berdasarkan nilai dari variabel state. Sekarang kode ini akan di-compile oleh imba menjadi:

    var App = Imba.defineTag('App', function(tag){
        tag.prototype.render = function (){
        // Menyimpan node
            var $ = this.$;
            return this.$open(0).setChildren($.$ = $.$ || [
                _1('div',$,0,this).flag('header').setText("Header"),
                _1('div',$,1,this).flag('status')
            ],2).synced((
                $[1].setContent(this.state().status,3)
            ,true));
        };
    });
    

    Masih ingat dengan dollar sign atau simbol $? Variabel tersebut berfungsi menyimpan reference pada actual node. Setiap elemen dengan Tag (kita sebut saja component) memiliki variabel ini. Sekarang perhatikan index di tiap child component dan fungsi di dalam synced.

    Annotated imba compiled code

    Index 1 (warna merah) adalah index untuk elemen div yang kedua, yaitu yang bernilai dinamis. Jadi, setiap node bernilai dinamis secara otomatis akan ditransformasi ke dalam fungsi synced milik Imba, ini adalah bagian dari proses dirty checking. Lalu kapan proses dom reconciler bekerja? saya belum baca source code-nya, jadi saya belum tau apa yang dilakukan Imba pada fungsi synced sebelum baris perubahan dom tersebut dieksekusi.

    Yang pasti dengan mekanisme ini membuat proses lebih cepat dibandingkan dengan virtual dom. Dalam screencast sebelumnya juga diterangkan bahwa garbage collection yang dihasilkan jauh lebih sedikit karena tidak melakukan iterasi panjang tersebut. Coding pun terasa lebih seperti ngoding vanilla javascript, karena kita tau tidak begitu banyak magic dibelakangnya.

    Beberapa kali diterangkan oleh Sindre (author Imba), bahwa pengembangan aplikasi web dengan Imba tidak memerlukan state management sama sekali. Jika kamu punya alasan selain "mengubah view bersamaan dengan data", maka silakan menggunakan state management (mobX, redux, apollo, relay). Beliau sudah mengujinya di scrimba.com, sebuah platform screencast yang notabene harus dirender tiap frame (stream audio), meski tanpa state management namun tetap terasa ringan.

    Tapi metode ini bukan tanpa kekurangan, salah satu masalah yang saya alami saat membuat project imba-typing adalah ketika tampilan tidak ter-update saat saya menggunakan setInterval. Karena sepertinya pemicu fungsi synced tidak bekerja di dalam closure jadi harus pake Imba.commit() (seperti forcUpdate() pada react).

    Kesimpulan

    Mungkin Imba lebih unggul dari segi kemudahan syntax atau kecepatan rendering, tapi bukan itu saja pertimbangan developer untuk memilih sebuah framework. Walaupun Imba ini sudah dikembangkan sejak tahun 2009 (bahkan sebelum React populer), pada akhirnya framework yang menguasai pasar adalah yang ramai komunitasnya, didukung oleh perusahaan besar, dokumentasinya lengkap, memiliki banyak library siap pakai dan menyediakan banyak tools untuk menghadapi berbagai situasi.

    Saya juga belum berani kalau disuruh pake Imba buat production. Coba coba untuk nambah wawasan aja. Mungkin berikutnya saya akan coba komponen Imba.router buat nguji seberapa nyaman Imba buat bikin SPA dan mencoba integrasinya dengan beberapa plugin / library.

    Kalo mau mulai coba Imba, kamu bisa mulai dengan clone repository hello-world-imba. Atau coba langsung lewat code editor-nya https://scrimba.com/c/cWkZRSV. Di scrimba, kamu disediain live code editor yang bisa dipake bukan cuma buat screencast tapi playground juga, pilih template Imba.

    Screenshot

    Sebelum coba buat aplikasi saran saya, baca dokumentasinya dulu sampe tamat (sedikit kok). Karena ada beberapa syntax yang tidak biasa dan component lifecycle yang perlu diperhatikan.

    Oiya, saya mau promosiin sekali lagi scrimba, sebuah platform screencast tanpa video yang dibuat pake Imba oleh author-nya. Karena bukan video, kalian disediain fitur code editor, browser preview, import dari google slide, sama rekaman suara. Kayanya cocok buat audiens orang Indonesia yang cenderung pengen hemat kuota atau punya bandwidth kecil. Waktu saya coba, kira-kira 10 menit screencast bisa cuman 2MB saja. Bisa jadi pilihan juga buat yang pengen bikin screencast.