Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Svelte - 如何在前端框架中脫穎而出 | ModernWeb'21

Kalan
September 25, 2021
80

Svelte - 如何在前端框架中脫穎而出 | ModernWeb'21

## 內容

- Svelte 簡介
- 探索前端框架的本質
- 介紹一些 Svelte 特有的語法與功能
- 實際使用後的心得分享

This slide is powered by slidev.

https://sli.dev/

Kalan

September 25, 2021
Tweet

Transcript

  1. Svelte - 如何在前端框架中脫穎而出
    Kalan                  ModernWeb’21
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  2. About Me
    Kalan (愷開)
    Frontend Engineer
    blog.kalan.dev
    @kjj6198
    @kalanyei
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  3. Agenda
    Svelte 簡介
    前端框架的本質
    Svelte 語法
    實際使用心得分享
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  4. Svelte 是什麼
    前端框架(50.5k stars)
    以 write less code 為哲學
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  5. 為什麼「又」一個前端框架?
    對現況的不滿
    人們對於最佳實踐的探索
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  6. 在 2020 年大放異彩
    State of JS 2020 的調查獲得滿意度第一名
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  7. Stack Overflow Survey 2021 最受喜愛的網頁框架
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  8. Svelte 解決了哪些問題?
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  9. 前端框架的基本元素
    元件化的中心思想
    響應機制(Reactivity)
    生命週期(Life Cycle)
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  10. 其他特色
    hooks
    context
    狀態管理
    路由
    開發環境、生態圈
    信仰
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  11. 元件化的中心思想
    響應機制(Reactivity)
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  12. 什麼是 Reactivity
    狀態改變時,畫面或整個應用也會同時更新
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  13. 為什麼我們需要 Reactivity?
    盡可能減少開發者的認知負擔
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  14. CodeSandbox
    pure-js
    kjj6198
    1.2k 0 0
    Edit Sandbox
    Files
    .codesandbox
    src
    index.js
    styles.css
    index.html
    package.json
    Dependencies
    9
    Console 0 Problems 0
    Open Sandbox
    function render(countdown) {

    document.getElementById("app").innerHTML = `

    ${countdown}

    `;

    }

    let countdown = 10;

    function start() {

    let timer = setInterval(() => {

    countdown -= 1;

    if (countdown === 0) {

    clearInterval(timer);

    }

    render(countdown);

    }, 1000);

    }

    render(10);

    start();
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  15. 其他前端框架如何達成 reactive
    如何通知應用狀態已經更新?
    const Countdown = () => {

    const [countdown, setCountdown] = useState(10);

    useEffect(() => {

    setInterval(() => {

    setCountdown(c => c -= 1);
    }, 1000)

    }, [])

    return {countdown}

    }
    <br/><br/>import { ref, onMounted } from 'vue';<br/><br/>const countdown = ref(10);<br/><br/>onMounted(() => {<br/><br/>setInterval(() => countdown.value -= 1, 1000);<br/><br/>})<br/><br/>



    {{countdown}}


    Svelte - 如何在前端框架中脫穎而出

    View Slide

  16. 問題點
    必須配合 JavaScript 機制
    diff 機制為 runtime 帶來負擔
    開發者需自行優化效能
    useMemo
    useCallback
    React.memo

    如果我們可以在其他地方處理變
    數追蹤呢?
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  17. Svelte 如何達到 reactivity
    Svelte 元件
    React
    CodeSandbox
    svelte-countdown
    kjj6198
    4.6k 0 0
    Edit Sandbox
    Files
    .codesandbox
    public
    App.svelte
    index.js
    Console 2 Problems 0
    Open Sandbox
    事先在編譯並生成 JavaScript 程式碼
    <br/><br/>let countdown = 10;<br/><br/>onMount(() => {<br/><br/>setInterval(() => countdown -= 1, 1000);<br/><br/>})<br/><br/>

    {countdown}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  18. Adam Rackis
    @AdamRackis
    omfg
    4:23 AM · Sep 16, 2021
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  19. 編譯帶來的好處是什麼
    可以預先檢查潛在的錯誤
    讓編譯器盡可能地優化壓榨效能
    減少 runtime 時期的程式碼體積
    compilers are the new frameworks
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  20. 特色
    寫更少的程式碼
    沒有虛擬 DOM 機制
    響應機制
    語法與 HTML JavaScript CSS 完全相容
    事先編譯元件並產生程式碼
    簡化後的語法與靜態分析讓程式碼更簡潔
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  21. 但…這看起來很 magic
    CPU 製程算不算 magic?
    作業系統算不算 magic?
    瀏覽器算不算 magic?
    JSX/babel/webpack 算不算 magic?
    Vue 的 template syntax 算不算 magic?
    只要是抽象化,或多或少都具備了「magic」的要素
    定義 magic:實作背後有一連串開發者不清楚的運作機制
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  22. 換個角度思考
    是否從本質上帶來了新的想法
    是否減輕了開發者的認知負擔
    是否能加速開發效率
    是否改善了產品品質
    讓世界變得更好一些
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  23. 探索 Svelte 的迷人之處
    變數宣告
    響應式語法
    跨元件狀態管理機制
    樣板語法
    transition 與 animate 機制
    綁定機制
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  24. 變數宣告與 prop
    <br/><br/>import Profile from './Profile.svelte';<br/>引入其他 Svelte<br/>元件<br/><br/>let state = false;<br/><br/>export let prop = 'hello'; //<br/>加上 export<br/>就變成 prop<br/>了<br/><br/><br/><br/>state = true; //<br/>任何 assignment<br/>都會觸發更新<br/><br/>


    Svelte - 如何在前端框架中脫穎而出

    View Slide

  25. 響應式語法
    在 countdown 有變化時重新呼叫 format
    函數
    約等於 react 當中的 useEffect
    約等於 vue 當中的 computed
    當某變數改變時做出反應
    <br/><br/>import { onMount } from 'svelte';<br/><br/>let countdown = 80;<br/><br/>$: formatted = `${format(countdown, 'xx:xx')}`;<br/><br/>onMount(() => {<br/><br/>setInterval(() => countdown -= 1, 1000)<br/><br/>});<br/><br/>

    {formatted}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  26. $:
    這個語法好奇怪
    標籤陳述式(label statement)
    很少人在用的 JavaScript
    語法
    Svelte
    會追蹤此區塊內的變數
    Vue
    的 ref 語法糖提案當中也參考了此功能
    <br/><br/>let a = 10;<br/><br/>$: {<br/><br/>console.log(a); //<br/>每次變數 a<br/>更新時呼叫 console.log(a)<br/><br/>}<br/><br/>

    {a}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  27. Svelte - 如何在前端框架中脫穎而出

    View Slide

  28. 跨元件狀態管理機制
    Svelte
    中內建 store 可直接使用
    .subscribe
    .set
    .update
    透過 $
    前綴減少開發者的認知負擔
    可在外部 JS 檔案宣告
    import { writable } from 'svelte/store';

    export const store = writable(

    { conference: 'modernweb2021' }

    )
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  29. $
    可幫助節省程式碼
    在元件掛載時自動訂閱 store
    在元件銷毀時解除訂閱 store
    效果大約等於:
    <br/><br/>import { store } from './store';<br/><br/>$: console.log($store.conference);<br/><br/>

    Conference: {$store.conference}
    <br/><br/>import store from './store';<br/><br/>let conference;<br/><br/>onMount(() => {<br/><br/>const unsubscribe = store.subscribe(store => {<br/><br/>conference = store.conference<br/><br/>})<br/><br/>return () => unsubscribe()<br/><br/>})<br/><br/>

    {conference}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  30. 樣板語法
    具備響應式特性
    容易理解
    CodeSandbox
    age-example
    kjj6198
    582 0 0
    Edit Sandbox
    Files
    .codesandbox
    public
    目前年齡:16 歲
    長一歲
    未成年
    Console 2 Problems 0
    Open Sandbox
    具有響應式特性的樣板語法










    {#if age >= 18}


    已成年

    {:else}


    未成年

    {/if}
    <br/>export let age = 16;<br/>const handleClick = () => age++;<br/>

    長一歲
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  31. 又要再多記一個語法…
    重點不是學習新語法
    是否能幫助降低認知負擔才是重點
    {#if}

    {:else}

    {/if}

    {#await promise}

    {:then data}

    {:catch error}

    {/await}

    {#each}

    {/each}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  32. transition 機制
    可和 if
    語法搭配
    不需要額外撰寫 CSS class
    動態產生 CSS Animation(而非直接操作
    style

    CodeSandbox
    transition-example
    kjj6198
    653 0 0
    Edit Sandbox
    Console 2 Problems 0
    Open Sandbox
    可透過宣告式的語法建立進出場動畫
    <br/><br/>import { fade } from 'svelte/transition';<br/><br/>let go;<br/><br/>setInterval(() => {<br/><br/>go = !go;<br/><br/>}, 1000);<br/><br/>

    {#if go}


    in:fade="{ duration: 100 }"

    out:fade="{ duration: 200 }"

    >Hello world

    {/if}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  33. crossfade + animate
    CodeSandbox
    svelte-animate-example
    kjj6198
    125 0 0
    Edit Sandbox
    Files
    .codesandbox
    public
    App.svelte
    Button.svelte
    index.js
    package.json
    JavaScript React Vue Angular Svelte
    Selected
    Console 2 Problems 0
    Open Sandbox
    計算節點位置並觸發動畫
    <br/><br/>import { crossfade } from 'svelte/transition';<br/><br/>const [send, receive] = crossfade({<br/><br/>duration: d => Math.sqrt(d * 350),<br/><br/>easing: cubicOut,<br/><br/>fallback: fade,<br/><br/>})<br/><br/>

    {#each tags as tag (tag.id)}


    animate:flip

    in:receive={{key: tag.id}}

    out:send={{key: tag.id}}

    >

    {tag.text}



    {/each}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  34. 綁定機制
    雙向綁定讓程式碼更加簡潔
    <br/><br/>let value;<br/><br/>let node;<br/><br/>let clientWidth;<br/><br/>





    {clientWidth}
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  35. Svelte - 如何在前端框架中脫穎而出

    View Slide

  36. 也可以綁定

    不需要額外撰寫監聽事件的邏輯
    (timeupdate volumechange
    等)
    改變變數值可以更新 DOM 屬性(部分唯讀屬
    性無法)
    <br/><br/>let duration;<br/><br/>let muted = false;<br/><br/>let currentTime = 0;<br/><br/>let paused = true;<br/><br/>let volume = 0.5;<br/><br/>if (previousPlayedTime) {<br/><br/>currentTime = previousPlayedTime<br/><br/>}<br/><br/>


    bind:duration

    bind:currentTime

    bind:muted

    bind:paused

    bind:volume

    ...

    />
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  37. 回頭探討:Svelte 解決了哪些問題
    用更簡化的語法達到響應式效果
    → 減少認知負擔
    能在編譯時期做的事情就不在 runtime 做
    → 減少 bundle size
    透過描述符(directive)提高程式碼的靈活度
    → 減少程式碼撰寫量
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  38. 專案分享
    動物森友會情報表
    JS bundle size: 10.6KB (gzip)
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  39. 專案分享
    台灣性侵害事件統計
    JS bundle size: 49.6KB (gzip)
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  40. 專案分享
    日語八百屋
    JS bundle size: 20.2KB (gzip)
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  41. 我該使用 Svelte 嗎?
    可接受 Svelte 特化的語法
    覺得 React 的程式碼過於冗長
    想要少寫一些程式碼
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  42. 需要考慮的事
    國內使用程度仍然偏少
    學習資源與生態圈較其他前端框架少
    必須事先編譯
    Svelte - 如何在前端框架中脫穎而出

    View Slide

  43. 一起來用 Svelte 吧!
    Facebook 社團:svelte.js Taiwan
    Svelte - 如何在前端框架中脫穎而出

    View Slide