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

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

9d7732f8bad970e853ce664588b204b0?s=47 Kalan
September 25, 2021
50

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

## 內容

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

This slide is powered by slidev.

https://sli.dev/

9d7732f8bad970e853ce664588b204b0?s=128

Kalan

September 25, 2021
Tweet

Transcript

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

  2. About Me Kalan (愷開) Frontend Engineer blog.kalan.dev @kjj6198 @kalanyei Svelte

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

  4. Svelte 是什麼 前端框架(50.5k stars) 以 write less code 為哲學 Svelte

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

  6. 在 2020 年大放異彩 State of JS 2020 的調查獲得滿意度第一名 Svelte -

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

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

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

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

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

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

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

  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 = ` <span class="number">${countdown}</span> `; } let countdown = 10; function start() { let timer = setInterval(() => { countdown -= 1; if (countdown === 0) { clearInterval(timer); } render(countdown); }, 1000); } render(10); start(); Svelte - 如何在前端框架中脫穎而出
  15. 其他前端框架如何達成 reactive 如何通知應用狀態已經更新? const Countdown = () => { const

    [countdown, setCountdown] = useState(10); useEffect(() => { setInterval(() => { setCountdown(c => c -= 1); }, 1000) }, []) return <span>{countdown}</span> } <script setup> import { ref, onMounted } from 'vue'; const countdown = ref(10); onMounted(() => { setInterval(() => countdown.value -= 1, 1000); }) </script> <template> <span>{{countdown}}</span> </template> Svelte - 如何在前端框架中脫穎而出
  16. 問題點 必須配合 JavaScript 機制 diff 機制為 runtime 帶來負擔 開發者需自行優化效能 useMemo

    useCallback React.memo … 如果我們可以在其他地方處理變 數追蹤呢? Svelte - 如何在前端框架中脫穎而出
  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 程式碼 <script> let countdown = 10; onMount(() => { setInterval(() => countdown -= 1, 1000); }) </script> <span>{countdown}</span> Svelte - 如何在前端框架中脫穎而出
  18. Adam Rackis @AdamRackis omfg 4:23 AM · Sep 16, 2021

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

    frameworks Svelte - 如何在前端框架中脫穎而出
  20. 特色 寫更少的程式碼 沒有虛擬 DOM 機制 響應機制 語法與 HTML JavaScript CSS

    完全相容 事先編譯元件並產生程式碼 簡化後的語法與靜態分析讓程式碼更簡潔 Svelte - 如何在前端框架中脫穎而出
  21. 但…這看起來很 magic CPU 製程算不算 magic? 作業系統算不算 magic? 瀏覽器算不算 magic? JSX/babel/webpack

    算不算 magic? Vue 的 template syntax 算不算 magic? 只要是抽象化,或多或少都具備了「magic」的要素 定義 magic:實作背後有一連串開發者不清楚的運作機制 Svelte - 如何在前端框架中脫穎而出
  22. 換個角度思考 是否從本質上帶來了新的想法 是否減輕了開發者的認知負擔 是否能加速開發效率 是否改善了產品品質 讓世界變得更好一些 Svelte - 如何在前端框架中脫穎而出

  23. 探索 Svelte 的迷人之處 變數宣告 響應式語法 跨元件狀態管理機制 樣板語法 transition 與 animate

    機制 綁定機制 Svelte - 如何在前端框架中脫穎而出
  24. 變數宣告與 prop <script> import Profile from './Profile.svelte'; 引入其他 Svelte 元件

    let state = false; export let prop = 'hello'; // 加上 export 就變成 prop 了 state = true; // 任何 assignment 都會觸發更新 </script> <Profile user={user} /> Svelte - 如何在前端框架中脫穎而出
  25. 響應式語法 在 countdown 有變化時重新呼叫 format 函數 約等於 react 當中的 useEffect

    約等於 vue 當中的 computed 當某變數改變時做出反應 <script> import { onMount } from 'svelte'; let countdown = 80; $: formatted = `${format(countdown, 'xx:xx')}`; onMount(() => { setInterval(() => countdown -= 1, 1000) }); </script> <span>{formatted}</span> Svelte - 如何在前端框架中脫穎而出
  26. $: 這個語法好奇怪 標籤陳述式(label statement) 很少人在用的 JavaScript 語法 Svelte 會追蹤此區塊內的變數 Vue

    的 ref 語法糖提案當中也參考了此功能 <script> let a = 10; $: { console.log(a); // 每次變數 a 更新時呼叫 console.log(a) } </script> <span>{a}</span> Svelte - 如何在前端框架中脫穎而出
  27. Svelte - 如何在前端框架中脫穎而出

  28. 跨元件狀態管理機制 Svelte 中內建 store 可直接使用 .subscribe .set .update 透過 $

    前綴減少開發者的認知負擔 可在外部 JS 檔案宣告 import { writable } from 'svelte/store'; export const store = writable( { conference: 'modernweb2021' } ) Svelte - 如何在前端框架中脫穎而出
  29. $ 可幫助節省程式碼 在元件掛載時自動訂閱 store 在元件銷毀時解除訂閱 store 效果大約等於: <script> import {

    store } from './store'; $: console.log($store.conference); </script> <h1>Conference: {$store.conference}</h1> <script> import store from './store'; let conference; onMount(() => { const unsubscribe = store.subscribe(store => { conference = store.conference }) return () => unsubscribe() }) </script> <h1>{conference}</h1> Svelte - 如何在前端框架中脫穎而出
  30. 樣板語法 具備響應式特性 容易理解 CodeSandbox age-example kjj6198 582 0 0 Edit

    Sandbox Files .codesandbox public 目前年齡:16 歲 長一歲 未成年 Console 2 Problems 0 Open Sandbox 具有響應式特性的樣板語法 {#if age >= 18} <span> 已成年</span> {:else} <span> 未成年</span> {/if} <script> export let age = 16; const handleClick = () => age++; </script> <button on:click={handleClick}> 長一歲</button> Svelte - 如何在前端框架中脫穎而出
  31. 又要再多記一個語法… 重點不是學習新語法 是否能幫助降低認知負擔才是重點 {#if} {:else} {/if} {#await promise} {:then data}

    {:catch error} {/await} {#each} {/each} Svelte - 如何在前端框架中脫穎而出
  32. transition 機制 可和 if 語法搭配 不需要額外撰寫 CSS class 動態產生 CSS

    Animation(而非直接操作 style ) CodeSandbox transition-example kjj6198 653 0 0 Edit Sandbox Console 2 Problems 0 Open Sandbox 可透過宣告式的語法建立進出場動畫 <script> import { fade } from 'svelte/transition'; let go; setInterval(() => { go = !go; }, 1000); </script> {#if go} <p in:fade="{ duration: 100 }" out:fade="{ duration: 200 }" >Hello world</p> {/if} Svelte - 如何在前端框架中脫穎而出
  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 計算節點位置並觸發動畫 <script> import { crossfade } from 'svelte/transition'; const [send, receive] = crossfade({ duration: d => Math.sqrt(d * 350), easing: cubicOut, fallback: fade, }) </script> {#each tags as tag (tag.id)} <button animate:flip in:receive={{key: tag.id}} out:send={{key: tag.id}} > {tag.text} </button> {/each} Svelte - 如何在前端框架中脫穎而出
  34. 綁定機制 雙向綁定讓程式碼更加簡潔 <script> let value; let node; let clientWidth; </script>

    <input type="text" bind:value={value} /> <canvas bind:this={node}></canvas> <div bind:clientWidth>{clientWidth}</div> Svelte - 如何在前端框架中脫穎而出
  35. Svelte - 如何在前端框架中脫穎而出

  36. 也可以綁定 <video> 或 <audio> 不需要額外撰寫監聽事件的邏輯 (timeupdate volumechange 等) 改變變數值可以更新 DOM

    屬性(部分唯讀屬 性無法) <script> let duration; let muted = false; let currentTime = 0; let paused = true; let volume = 0.5; if (previousPlayedTime) { currentTime = previousPlayedTime } </script> <audio bind:duration bind:currentTime bind:muted bind:paused bind:volume ... /> Svelte - 如何在前端框架中脫穎而出
  37. 回頭探討:Svelte 解決了哪些問題 用更簡化的語法達到響應式效果 → 減少認知負擔 能在編譯時期做的事情就不在 runtime 做 → 減少

    bundle size 透過描述符(directive)提高程式碼的靈活度 → 減少程式碼撰寫量 Svelte - 如何在前端框架中脫穎而出
  38. 專案分享 動物森友會情報表 JS bundle size: 10.6KB (gzip) Svelte - 如何在前端框架中脫穎而出

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

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

  41. 我該使用 Svelte 嗎? 可接受 Svelte 特化的語法 覺得 React 的程式碼過於冗長 想要少寫一些程式碼

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

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