# SSR vs Prerendering dochi? ### EK --- ## 名詞定義 ### 渲染 * **SSR**(Server-Side Rendering) * **CSR**(Client-Side Rendering) * **Rehydration** * 透過javascript在client端,產生像SSR產生HTML’s DOM tree和資料。 * **Prerendering** * 在client跑應用前,捕獲所有的狀態產生出靜態HTML ---- ### 效能 * **TTFB**(Time to First Byte) * 造訪網站後,收到伺服器回應第一個位元組的時間。 * **FP**(First Paint)第一次渲染 * 白屏到有畫面。 * **FCP**(First Contentful Paint)首次內容繪製 * 表示瀏覽器抓取到內容顯示的時間 (article body, etc)。 * **TTI**(Time To Interactive)可互動時間 * 表示頁面能提供完整互動功能的時間。 --- ## Server Rendering ![](https://i.imgur.com/SuPno7E.png) ---- * Client端 cpu使用較少。 * 更快的FP和FCP,以致可以達到快速的TTI。 * 產生頁面在主機端需要更長時間,換來更慢的TTFB。 --- ## Static Rendering ![](https://i.imgur.com/pag0kGQ.png) ---- * 更快的FP和FCP,以致可以達到快速的TTI。 * 他還改善了Server Rendering的TTFB * 靜態渲染意味著每個URL對應單獨的HTML檔案,透過cdn做緩存可以達到最好的效果。 * 但如果每個URL的內容無法預測,或是有大量不同頁面,會影響其可行性。 --- ## Server Rendering vs Prerendering * Server Rendering 不是萬用解,他的動態特性可能會造成巨大的與算成本。 * Server Rendering不能提前工作,會造成TTFB的延遲。 * Server rendering 產生靜態HTML是依據URL,但一定比Static Rendering更慢。 * 如果同時使用 **server rendering** + **HTML caching**可以顯著的減少server render時間。 --- ![](https://i.imgur.com/bDBeb0O.png) --- ## SSR(伺服器渲染) * 使用 * Laravel * Vue * [套件](https://github.com/spatie/laravel-server-side-rendering) * 套件包沒有特別說明**vuex**, **vue-router**如何使用在套件的寫法中,可以參考[範例](https://github.com/spatie/laravel-server-side-rendering-examples)。 ---- * 作法 * 透過php v8或是 node原生,在進後端route的時候在server side render,把整個完整的html return回去。 * 前端點選網址,則使用前端router做觸發。 ---- * 優點 * 可以渲染即時的資料,解決SEO。 * 不會有進入時白頁問題,因為不需要在前端渲染。 * 缺點 * 在vue生命週期只有 **beforeCreate**和**created**會被調用到。 * server端沒有**window**、**document**,如果要算頁寬,高度等等都會GG,要做特別處理。 ---- ### [實例](http://ssr.dev.parenting.com.tw) * 使用vue-router,在每一頁看原始碼都是一次SSR,可以看到Vue component產生的內容,會在網頁原始碼內。 --- ## Prerender(預渲染) * 使用 * Koa * Vue * 套件 * [prerender-spa-plugin](https://github.com/chrisvfritz/prerender-spa-plugin) * 核心技術 * [puppeteer](https://github.com/GoogleChrome/puppeteer) * [範例](https://github.com/chrisvfritz/prerender-spa-plugin/tree/master/examples/vue2-webpack-router) * **P.S.** 範例沒有後端router,所以產生靜態後,重整網址後,未預渲染路徑會404,此處使用Node.js架設主機撰寫wildcard。 ---- ### 作法 #### 指定需要做預渲染的Url **webpack.config.js** ```javascript=71 new PrerenderSPAPlugin({ staticDir: path.join(__dirname, 'dist'), routes: [ '/', '/about', '/contact'], ``` ---- #### 用node寫一個server(Koa為例) 安裝koa ```shell= yarn add koa koa-router koa-views koa-static ``` ---- 撰寫koa 引用lib **./server.js** ```javascript= const Koa = require('koa'); const Router = require('koa-router'); const views = require('koa-views'); const serve = require('koa-static'); const app = new Koa(); ``` ---- 指定view的路徑與副檔名 ```javascript=7 app.use(views(__dirname + '/dist', { extension: 'html' })); ``` 寫個router ```javascript=11 const router = Router(); // Router -> / router.get('/(.*)', async(ctx) => { await ctx.render('index') }); ``` ---- 指定static folder ```javascript=17 app.use(serve(__dirname + '/dist')); ``` 最後註冊router和設定port ```javascript=19 app .use(router.routes()) .use(router.allowedMethods()); app.listen(8001); ``` ---- #### SEO META怎麼辦? ---- 裝 [vue-meta-info](https://github.com/muwoo/vue-meta-info) ```shell= yarn add vue-meta-info ``` ---- 以 about頁面為例 **src/components/About.vue** ```javascript=8 export default { metaInfo: { title: "About", meta: [ { name: "About", content: "About Page" } ], link: [ { rel: "asstes", href: "https://assets-cdn.github.com/" } ] } }; ``` ---- **index.html** ```htmlembedded= <head> <meta charset="utf-8"> <title>{{ title }}</title> </head> ``` ---- #### 使用webpack做SSR產生靜態頁面 ```shell= yarn build ``` 會產生到 **./dist** 資料夾 ![](https://i.imgur.com/pG0zKiw.png) ---- #### 執行node ```shell= yarn serve ``` 此時已經將 yarn serve改寫成 node app.js 網址為 http://127.0.0.1:8001 ![](https://i.imgur.com/Zy6fY7h.png) ---- #### 如果Contact Page為動態資料,不能要產生靜態頁面 ---- 修改 **webpack.config.js** ```javascript=71 new PrerenderSPAPlugin({ staticDir: path.join(__dirname, 'dist'), routes: [ '/', '/about'], ``` 重新產生靜態頁面 ```shell= yarn build ``` ---- 或是我們偷懶一點,直接把 **./dist/contact**砍掉就好 ---- 重新跑,點擊contact超連結,之後看原始碼 ![](https://i.imgur.com/dZbAtWd.png) 你會發現它讀取的是Vue進入的那一頁 **./dict/index.html**,表示這頁是CSR。 ---- 這兩種方法可不可以混在一塊寫.......... ---- ![](https://i.imgur.com/nHN5QJP.png) 等你.... --- 會後討論
{"metaMigratedAt":"2023-06-14T22:50:36.653Z","metaMigratedFrom":"Content","title":"SSR vs Prerendering dochi?","breaks":true,"contributors":"[{\"id\":\"8e42ec30-16dd-49e7-9493-42a2633bb31a\",\"add\":5935,\"del\":1437}]"}
    551 views