Svelten logo tyylitellyllä taustalla.

Svelte - uhka vai mahdollisuus?


Svelte on vuonna 2016 julkaistu avoimen lähdekoodin käyttöliittymien kehittämiseen tarkoitettu ohjelmistokehys. Selvitin, että mihin se taipuu ja mitä hyötyä siitä on liiketoiminnan sekä ohjelmistokehittäjän näkökulmasta.

Vuoden 2021 kehittäjätutkimuksessa rakastetuimmaksi web-frameworkiksi äänestetty Svelte on tullut tunnetuksi koodin luettavuudesta ja siitä, että se ei käytä dokumenttipuun rinnalla “virtuaalista” DOM:a (kuten Reactissa tai Vuessa), vaan muutokset tehdään suoraan dokumenttipuussa.

Käytin Svelten testaamisessa TypeScript -ohjelmointikieltä sekä perus CSS:iä ilman SvelteKitiä. Svelte antaa lähes vapaat kädet määrittää projektin kansiorakenteen, kun taas kokonaisvaltaisemmassa SvelteKitissä myös kansiorakenne sekä tiedostonimet ovat osa kehyksen rakennetta.

Mikä on ohjelmistokehys eli framework?

Ohjelmistokehityksessä käytetään paljon englanninkielisiä termejä. Yksi näistä avainsanoista on framework eli ohjelmistokehys. Ne ovat runkoja, joiden ympärille ohjelma kehitetään. Teknisesti ohjelmistokehykset ovat kirjastojen tavoin uudelleen käytettävää koodia esimerkiksi funktioiden tai luokkien muodossa.

Ero ohjelmistokehyksen ja kirjaston välillä on tyypillisesti se, että kirjaston tarjoamia funktioita kutsutaan omassa koodissa siten, että ohjelmoija itse päättää funktioiden suoritusjärjestyksen. Ohjelmistokehyksessä suoritettava koodi annetaan sille suoritettavaksi, jolloin ohjelmistokehys päättää itse, milloin käyttäjän funktiot suoritetaan. Ohjelmistokehyksen voidaan katsoa toteuttavan käänteisen kontrollin suunnittelumallin (inversion of control).

JavaScript-ohjelmointikielen ympärillä useasti frameworkeista puhuttaessa tarkoitetaan juurikin front end -ohjelmistokehyksiä. Näitä ovat Svelten lisäksi esimerkiksi React, Vue, Angular ja Ember. Niiden keskeisimpiä ominaisuuksia ovat koosteisten käyttöliittymäkomponenttien luonti ja reaktiivisuus, sekä visuaalisten komponenttien päivittyminen arvojen muuttuessa.

JavaScript kirjoitettuna Bananagrams paloilla.

Voiko liiketoimintasi hyötyä Svelten käytöstä?

Koska Svelte on helppolukuisempaa kuin muut front end -puolen ohjelmistokehykset, nopeutuvat sen ympärillä tehtävät toimenpiteet verrattuna syntaksiltaan vaikeaselkoisempiin ohjelmistokehyksiin, ja näin voi säästyä aikaa ja rahaa.

Sveltestä on hyötyä myös loppukäyttäjälle. Selaimen lataama osuus (bundle) on Sveltellä tehtynä huomattavasti paljon pienempi kuin esimerkiksi Reactia käytettäessä. Siten kehitetty verkkosovellus voi latautua nopeammin loppukäyttäjän laitteella sekä toimia sujuvammin. Koska kaikki muutokset tehdään suoraan dokumenttipuuhun rinnakkaisen “virtuaalisen” DOM:n sijaan, voidaan Svelte komponenttien olettaa olevan kevyempiä ja suorituskykyisempiä.

Pieni varoituksen sanakin on paikallaan. Svelte ei ole vielä niin käytetty kuin muut, jolloin komponenttikirjastoja saattaa olla vähemmän tarjolla. Ohjelmoija saattaa lisäksi kohdata virheen tai muun haasteen, johon ei vielä esimerkiksi ohjelmistokehittäjien Stack Overflow -verkkoyhteisössä ole vastattu. Tästä huolimatta Svelte on lukeutunut kehittäjien suosikkikehysten joukkoon esimerkiksi State of JavaScript 2020 -tutkimuksen mukaan. Sveltellä tehtyjä sovelluksia voit katsella Made With Svelte sivustolla.


Apua ohjelmistokehitykseen

JavaScript-maailman front end -kehyksillä on eroja käytettävyyden kannalta. Esimerkiksi Reactissa käyttöliittymäkomponentit esitetään JSX-syntaksilaajennuksella, jota voi käyttää suoraan JavaScript-koodissa. Svelte ja Vue taas käyttävät .vue ja .svelte -päätteisiä tiedostomuotoja, jotka muistuttavat syntaksiltaan XML-merkintäkieltä. Niissä JavaScript kirjoitetaan HTML-dokumenttien tapaan script tagin sisälle ja tyylit sekä komponentin rakenne omille alueilleen dokumentissa.

Kirjoitetut komponentit saadaan helposti luettaviksi erilaisilla conditional rendering -ominaisuuksilla, jotka ovat suoraan osana Svelten omaa syntaksia. Svelte on mielestäni selvästi intuitiivisempi kuin React tai Vue. Koen, että käyttöliittymien frameworkeilla tulee reaktiivisuuden kanssa yllätyksiä. Silloin tällöin useStatella arvoja päivitettäessä voidaan päätyä tilanteeseen, jossa arvon päivittyminen tulee jatkuvasti asteen myöhässä. Myös useEffect Hookia käyttäessä voi tapahtua yllättäviä asioita, jos sille annetaan seurattavat muuttujat virheellisesti.


Svelten perusasioita ohjelmointinäkökulmasta

Svelte hoitaa reaktiivisuuden kehittäjän puolesta. Kun komponentissa määritetään muuttuja, jonka tila on muunneltavissa, voi tämän upottaa elementtien sekaan. Muuttujan tilaa muunneltaessa ei tarvitse kutsua funktioita, vaan niitä voi käyttää normaalimuuttujien tapaan.

<!-- Counter.svelte -->

<script>
    let count = 0;
    const increment = () => count++;
</script>

<button on:click={increment}>
    count is {count}
</button>
Täysin toimiva reaktiivinen Svelte-komponentti. Komponentin nimi tulee sen tiedostonimestä.

Jos halutaan luoda reaktiivisia uudelleen käytettäviä arvoja, joissa käytetään reaktiivisia muuttujia, voidaan niitä luoda "$:" -merkkiä käyttämällä.

<!-- DoubleCounter.svelte -->

<script>
    let countA = 0;
    let countB = 0;

    const incrementCountA = () => countA++;
    const incrementCountB = () => countB++;

    const round = (value) => value.toFixed(2)

    $: sum = round(countA + countB);
    $: sub = round(countA - countB);
    $: mul = round(countA * countB);
    $: div = round(countA / countB);
</script>

<p>Sum: {sum}</p>
<p>Sub: {sub}</p>
<p>Mul: {mul}</p>
<p>Div: {div}</p>

<button on:click={incrementCountA}>A</button>
<button on:click={incrementCountB}>B</button>
Tämän pystyy saavuttamaan lisäämällä reaktiivisia muuttujia sisältävät lausekkeet suoraan elementtien sekaan, mutta ylläkuvatulla tavalla reaktiiviset arvot ovat paremmin uudelleen käytettävissä.

Iteroitavan ja asynkronisen datan näyttäminen sekä ehdollinen näyttäminen toteutetaan Svelten omalla syntaksilla. Kaikki käyttävät samaa syntaksia eri avainsanoilla omalla asianmukaisella logiikallaan. Ohjelmointimukavuuden näkökulmasta toiminta muistuttaa läheisesti Vue:n direktiivejä v-for ja v-if.

<!-- Enemy.svelte -->

<script>
    let health = 120;
    let hit = 0;

    function attack() {
        hit = Math.floor(Math.random() * 15);
        health -= hit;
    }
</script>

{#if health > 0}
    <p>Enemy</p>
    <p>Health: <b>{health}</b></p>

    <i>Your last hit was: <b>{hit}</b></i>
    <button on:click={attack}>
        Attack
    </button>
{:else}
    <p>You win!</p>
{/if} 

Huomioitavaa Svelten käytössä

Mielestäni kannattaa odottaa vielä muutama vuosi, ennen kuin Svelteä käyttävä tiimi alkaa ratkomaan jotain bugia, joka voi johtua pelkästään virheellisistä ilmoituksista. Huomasin, että Svelten käyttäminen saattoi aiheuttaa outoja virheitä editorissa (VS Code), jotka lähtivät vain editorin uudelleen lataamalla, vaikka käytin virallisia Svelten liitännäisiä.

Vaikka jokin ominaisuus olisi samanniminen ja jakaa sinällään saman tehtävän kuin toisessa ohjelmistokehyksessä, kannattaa aina varmistaa ominaisuuden toiminnallisuus uutta kehystä käytettäessä. Opin, että Svelten konteksti ei itsessään ole reaktiivinen, vaan vasta Svelten storen kanssa yhdistelemällä se toimii lähes samoin kuin Reactilla.

Huomasin myös, että tyyliosion sisuksia ei voi muokata samalla tavoin kuin HTML-elementtejä, mikä saattaisi intuitiivisesti käydä mielessä. Dynaamiset tyylit pitää antaa joko tyyli-direktiiveinä (tehokkain) tai inline-tyyleinä HTML-elementteihin (vähemmän tehokas). Svelte osaa tehdä niistä optimoituja ratkaisuja. Jos päädytään kirjoittamaan funktio, joka palauttaa käsitellyn stringin attribuuttiin, ei Svelte osaa optimoida sitä, vaan käännöksen jälkeen sitä käsitellään edelleen merkkijonona. Samoin käy, jos tyyli-merkkijonon yrittää säilöä dynaamiseen arvoon.

Kehitys kokeilemalla tutuksi

Olen käyttänyt paljon JavaScript-pohjaisia ohjelmistokehyksiä frontissa sekä back endin puolella. Käyttöliittymäpuolen ohjelmistokehityksessä frameworkit ovat perinteisesti lisänneet taustalle pyörimään raskasta tavaraa esimerkiksi virtuaalisen DOM:n muodossa. Nähtyäni Fireshipin YouTube-kanavalla tiivistelmävideoita Sveltestä, innostuin yksinkertaisemmalta ja kevyemmältä vaikuttavasta kehyksestä.

Svelte sopii hyvin junioreille, koska oppimiskaari ei ole niin jyrkkä kuin esimerkiksi Reactissa. Olen React-taustainen ja opin mieluummin tekemällä kuin pelkästään dokumentaatiota lukemalla, joten Svelten matala kynnys oppia ilahdutti. Svelten selkeää dokumentaatiota ei tarvitse niin kamalasti tankata heti alussa. Tutoriaalin avulla voi kehittäjä heti päästä kokeilemaan Svelteä interaktiivisessa ikkunassa. Svelten virallinen tutoriaali

Rakensin Sveltellä pelin

Halusin testata Svelteä harjoiteprojektin kautta. Wordle-puhelinpeli vaikutti siltä, että se olisi helppo tehdä käyttöliittymäkomponenteilla. Lapsuudessani tutuksi tulleet Miniclip-verkkosivun selainpelit, kuten Crypt Raider tai Aqua Energizer olivat mahdollisesti toteutettavissa. Pyöriteltyäni ajatusta päätin perustaa pikselitaide-tyyppisen pelin ruudukossa näytettäviin käyttöliittymäkomponentteihin ottaen lisäksi vaikutteita Wonderland Secret Worldsista, eräästä lapsuusajan lempipelistäni.

Testatakseni, onko rakenne mahdollista toteuttaa, tein ensin ruudukkoon päällekkäisiä kerroksia HTML-elementeillä. Jatkoin saman rakenteen kehittämistä “huijaamalla” syvyyden liikuttelemalla päällekkäisiä komponentteja ylöspäin toisiaan nähden, ja lisäsin box shadow -ominaisuuden web-version komponentteihin. Testasin Svelten taipuisuutta ja piirsin 256 Svelte-komponenttia näyttöön, ja ne päivittyvät aktiivisesti. Päädyin rakentamaan pelin näytön ympärille, joka näkyy pelikoodin rakenteessa. Pelin käännetyksi kooksi tuli 189 kilotavua.

Pelikokeilunsa jälkeen tuntui, että voisin luoda jatkossa kaikki verkkopohjaiset harrasteprojektinsa Sveltellä. Vaikuttaa siltä, että saisin sen avulla harrasteprojektit nopeiten esille. Minulla on meneillään paljon harrasteprojekteja ja Sveltellä tehty peli on niistä ensimmäisenä nähnyt päivänvalon. Julkaisin 16-tasoisen pelin Google Cloud Runin avulla. Sokoban-tyyliseen tietokonepeliini pääset suoraan tästä linkistä tai alla olevalla QR-koodilla.

QR-koodi peliin.
QR-koodi peliin.

Tarkemmin Sveltestä

Svelte on Rich Harrisin vuonna 2016 kehittämä framework. Harris kiinnostui koodaamisesta työskenneltyään medioille kuten BBC, The Guardian ja The New York Times, jossa koodia käytettiin interaktiivisen kokemuksen tuottamiseksi lukijoille. Kun hän aloitteli visuaalisen journalismin tekemistä, ei ollut niin hyviä työkaluja saatavilla kuin nykyään ja se loi haasteita tuottaa monipuolisia interaktiivisia applikaatioita.

Harris halusi yrittää ratkaista ongelman. Hän loi ensin kehyksen nimeltä Ractive. Kun mobiiliympäristö alkoi olla yhä enemmän ihmisten päivittäisenä käyttöympäristönä, vaadittiin työkaluiltakin jälleen jotain uutta. Svelte syntyi ideasta kääntää koodi sekä tehdä työ helpommalla kuin aiemmin, ja saada kevyen kehyksen avulla parempia käyttäjäkokemuksia.

Sveltessä komponentti koostuu logiikkaosiosta, malliosiosta ja tyyliosiosta Vuesta tuttuun tapaan. Komponentin nimi tulee suoraan tiedostosta. Svelten käännöstä testatessa Lighthousen avulla oli se vertailussa Vueen ja Reactiin nopein, vaikka kaikki olivat tosi nopeita. Testiprojektina olivat Viten “Hello world” -projektit. Paketin koko oli kaikista pienin, vaikka se ei niin yksinkertaista olekaan. Vuen ja Viten alkuperäisen kehittäjän Evan Youn tekemän kokoanalyysin mukaan Vue on loppujen lopuksi pienempi isommassa projektissa.

On kuitenkin katsottava mihin painopisteisiin eri kehykset nojaavat, koska ne ovat hyviä eri asioihin. Svelte on tällä hetkellä mainio yksittäisiin komponentteihin tai pieniin projekteihin, mutta koko tulee vastaan mediumia isommissa hankkeissa Evanin mukaan. Harrisin mukaan taas koon ei pitäisi kuitenkaan olla ongelma, kunhan ensimmäinen lataus on pieni. Rich Harris suosittelee, että ohjelmistokehityksessä käytettäisiin Svelten ympärille rakennettua projektirakennetta SvelteKitiä. Vuonna 2021 Vercel otti Harrisin tiimiinsä kehittämään Svelteä kokopäiväisesti, joten ohjelmistokehyksellä on täydet mahdollisuudet tulla entistäkin nopeammaksi ja paremmaksi.

Svelte vs Vite vs React Viten boilerplate Chromen Lighthouse benchmarkissa.
Lighthouse-testi Viten alustusprojektista Sveltelle, Reactille, sekä Vuelle.
Svelte vs Vite vs React Viten bundle koko.
Bundle-koot.

Loppusanat

Svelteä on mielestäni siistimpi käyttää. Pohdin sitä, että onko paketin koon kasvu isommassakaan projektissa kovin merkityksellinen, jos sen komponentit tekevät kuitenkin muutokset suoraan dokumenttipuuhun? Mielestäni kaikkein tärkein asia on kuitenkin se, miten kirjoitetaan ylläpidettävää koodia ja siinä Svelte vaikuttaa olevan kärjessä, kun huomioidaan sen tuore ikä ja jotkut keskeneräisyydet työkalujen toimivuudessa. Muutaman vuoden sisällä se voisi olla hyvinkin suositeltava esimerkiksi Reactin ja Vuen tilalla uusiin projekteihin.

Ota yhteyttä!

Tarvitseeko liiketoimintasi enemmän kuin mitä verkkopalvelusi pystyy tarjoamaan? Tarjoamme konsultaatiota kaikissa tähän blogikirjoitukseen liittyvissä asioissa, kuten käyttöliittymäkehityksessä. Ota yhteyttä ja kartoita kanssamme kaikki päivitystarpeet kerralla kuntoon: