Nuxt.js
(一)
基於 Vue 的 Server side render framework
unversinal
目錄
-
什麼是 SSR?
-
為什麼選擇使用 Nuxt?
-
Nuxt 如何讓一切變方便?
-
Nuxt 的近況
-
Q&A
什麼是 Server Side Render?
簡稱 SSR
早期
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>EJS template</title>
</head>
<body>
<h1><%= title %></h1>
<%- category %>
<ul>
<% for(var i=0; i < characters.length; i++) { %>
<li><%= characters[i] %></li>
<% } %>
</ul>
</body>
</html>
ejs pug erb thymeleaf ...
傳統 SSR
or PHP, Java ...
傳統 SSR
請求
後端
資料庫
拿資料
吐資料
HTML
傳統 SSR
每次點擊換頁時,都需要重新拿重新執行 HTML, JavaScript, CSS (沒快取)
模板語言限制了靈活性
前端越來越複雜、互動越來越多需要 Reactive 機制,也會希望互動跟 View 綁在一起
SPA
請求
後端
JavaScript
解析
請求
吐資料
API
SPA
First Content Paint 比較慢 (aka. FCP, 首次渲染內容, 首屏渲染)
不好的 SEO,因為 JavaScript 產生 HTML
白畫面易閃爍
SPA
puppeteer
prerender-spa-plugin
簡化版
寫死
所以 SSR 誕生了
請求
Node.js
Nuxt
API
請求
吐資料
HTML JavaScript
Hydration
吐資料
請求
SSR
Hydration
幫 HTML 加上 Event Listener (SSR 省略) 跟 執行生命週期 (useEffect ...)
Server render 好了,Client 不需要在 Render 一次
同時也會檢查 Server 跟 Client render 的結果是不是一樣,否則噴 Mismatch 警告
SSR
你可以自己來 SSR
import express from "express";
import React from "react";
import { renderToString } from "react-dom/server";
import App from "./client/App";
const app = express();
app.use(express.static("public"));
app.get("/", (req, res) => {
const content = renderToString(<App />);
const html = `
<html>
<head></head>
<body>
<div id="root">${content}</div>
<script src="bundle.js"></script>
</body>
</html>
`;
res.send(html);
});
app.listen(3000, () => {
console.log("listening on port 3000");
});
const path = require("path");
const webpackNodeExternals = require("webpack-node-externals");
module.exports = {
target: "node",
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
},
],
},
externals: [webpackNodeExternals()]
};
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.hydrate(<App />, document.getElementById("root"));
const path = require("path");
module.exports = {
target: "node",
entry: "./src/client/client.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "public"),
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
},
],
},
};
Next.js 或 Nuxt.js 都幫你做好了
除了做好 SSR 之外 還有 ...
為什麼會選擇使用 Nuxt ?
快速搭建
學習曲線
大量動態頁面的 SEO 問題
想讓一切變得方便
就是懶
Nuxt 如何讓一切變方便?
Cli & DOcument
該裝的都裝好,也能自己設定
Vue-router
Vue-meta
(next-head, react-helmet)
Vuex
(Redux)
Vue 本身內建 Transition
(React-transition-group)
Babel
Webpack 最佳化設定
HMR, bundle analyzer...
Loaders
ES Lint
PostCSS
沒有你要的還有 PLUGINS 跟 MODULES,或是你自己包
Page transition
Loading indicator
...
你的資料夾結構就是你的
Route(NEXT.JS) and Store and more ...
/
/about
/contact
/:id/profile
/:id/setting
form store
user/... store
Components and Plugins
SSR 與 效能
Modern mode (ESModule)
Smart prefetching
http2 push, Gzip (or use nginx)
Code splitting
Critical CSS per route
SEO
First Content Paint
(FCP, 首次繪製內容, 首屏渲染)
較少的閃爍
(Middleware, 和不用等待 Js)
有 SSR 可以做很多後端在做的事
(Image compressor, base auth, error page, or 再包一層 API, Proxy)
SSR 第一次只需要一次請求
就算你不要 SSR 也可以關掉當 SPA 來用
或是 Build Static 的頁面
講這麼多好像很多優點
那缺點呢?
缺點
如果是 SSR 的話你的 Server 當然要一直開著
很大的機率會遇到 Memory Leaks 的問題
有些套件、Plugins 不支援 SSR (好解決)
不習慣 SSR 的你會一直炸
Dev or Build 會有點慢 (包兩份或三份 modern ...)
Library 和 Framework
Nuxt 的近況
Nuxt 的近況
Nuxt 3.0 準備出了 (with Vue 3.0)
有 Composition API plugin
Service worker rendering with SSR
Q & A
Nuxt.js
By Steven Ho
Nuxt.js
- 432