Hiện nay SSR đối với các Frontend Framework rất nổi tiếng điển hình là NextJS, Remix, Gastby, … của nhà React; NuxtJs của nhà Vue, SvelteKit của nhà Svelte, … Qua bài viết này chúng ta sẽ tìm hiểu cơ chế và làm thế nào để thực hiện SSR biểu diễn bằng ReactJS
Client Side Rendering được diễn ra khi chúng ta nhận được từ request là 1 file HTML trống (như file index.html trong React App) và sau đó quá trình thêm JS vào để render ra toàn bộ content được diễn ra ở phía Browser(Client)
Nhờ vậy điểm mạnh của CSR sẽ giúp:
Nhưng thực tế 1 ứng dụng xịn xò người ta sẽ kết hợp rất nhiều phương pháp như SSR, CSR, SSG, ISR, … chứ không đơn thuần là CSR
Ở đây ta chỉ so sánh CSR và SSR còn SSG và ISR tương lai mình sẽ làm sau
Server Side Rendering được diễn ra khi ta nhận về file HTML được render đầy đủ từ bên Server và sau đó dùng JS để hydrate nên ta sẽ có được giao diện animation, chức năng.
Khác biệt lớn nhất với CSR thay vì Server trả ra file HTML trống và dùng JS render ra ở Browser thì SSR Server trả ra file HTML đã được render đầy đủ element sau đó mới dùng JS hydrate(như kiểu nhúng) ở Browser. Chính vì thế SSR rất được ưa chuộng cho việc SEO
Nhờ vậy điểm mạnh của SSR sẽ giúp:
Được trả về đầy đủ content HTML content mà không cần JS ở Browser render ra nên ta nếu ta tắt JS ở Browser SSR sẽ hiển thị đc HTML còn CSR thì bắt buộc yêu cầu mở JS
Ở trên mình đã nêu ưu điểm riêng của mỗi phương pháp rồi, section này mình sẽ làm rõ cách hoạt động khác biệt của 2 cách
Đầu tiên là CSR:
Tiếp theo là SSR:
Các bạn lưu ý, điều này không có nghĩa là toàn bộ ReactJS được thực thi ở SSR đâu nha. SSR có nhiệm vụ là khởi tạo lần đầu ra toàn bộ content được render trả ra cho Browser, các việc như useState, useEffect, … đều được diễn ra toàn bộ ở Browser hết. Rất nhiều bạn hiểu lầm về vấn đề này.
Để hiểu rõ hơn về SSR mình cùng code thôi. Ví dụ lần này rất cơ bản nên sẽ dễ hiểu
Ở đây mình sẽ xài template của Vite và Server sẽ là ExpressJS
Đầu tiên tạo project ReactJS bằng Vite như bình thường
yarn create vite
Vào file index.js
đổi từ render()
sang hydrate()
ReactDOM.createRoot(document.getElementById('root')).hydrate(
<React.StrictMode>
<App />
</React.StrictMode>,
)
Sau khi tạo project thành công, tạo file server.js
import express from "express";
import fs from "fs";
import path from "path";
import React from "react";
import ReactDOMServer from "react-dom/server";
import App from "./src/App.jsx";
const PORT = 3030;
const app = express();
app.get("/", (req, res, next) => {
fs.readFile(path.resolve("./dist/index.html"), "utf-8", (err, data) => {
if (err) {
res.status(500).send(err.message);
}
const reactDOM = ReactDOMServer.renderToString(<App />);
return res.send(
data.replace('<div id="root"></div>', `<div id="root">${reactDOM}</div>`)
);
});
});
app.use(express.static(path.resolve(__dirname, ".", "dist")));
app.listen(PORT, () => {
console.log(`running at port: ${PORT}`);
});
Ở phía Server mình cần React để render html rồi sau đó gửi về cho Browser
Nhưng vấn đề là trong server.js
vẫn chưa chạy được vì nó không hiểu được JSX, vì vậy ta cần cài thêm plugin
yarn add babel/preset-env @babel/preset-react @babel/register ignore-styles
Sau khi cài xong ta tạo thêm file index.js
để config
require("ignore-styles");
require("@babel/register")({
ignore: [/(node_modules)/],
presets: ["@babel/preset-env", "@babel/preset-react"],
});
require("./server.js");
Nhiêu đó là đủ, cùng chạy thôi, chứ là chạy file index.js nha, không phải server.js
node index.js
Và đây là kết quả, ta có thể tương tác thêm State như bình thường
Đặc biệt khi bạn tắt JS ở Browser, nó vẫn show ra được HTML đã được render từ Server trước đó trả về mà không cần JS, nhưng ta sẽ không tương tác được chẳng hạn như setCount
. Vì các hành động đó cần có JS và được diễn ra ở Browser
Qua bài viết này chúng ta có thể hiểu được phần nào về SSR trong Frontend nói chung và React nói riêng bằng ví dụ. Tuy nhiên đây chỉ là ví dụ cơ bản để hiện thực cách SSR hoạt động thôi, thực tế bao nhiêu đó vẫn chưa đủ ví dụ đoạn code không xài được multiple route
Thực tế ta nên sử dụng các Framework được hỗ trợ rất mạnh mẽ và có cộng đồng ví dụ như Nextjs. Nếu có thời gian bạn nên dành vài phút sẽ hiểu được SSR của Nextjs
Hi vọng bài chia sẻ này hữu ích với mọi người!
Mở rộng thêm bạn có thể tham khảo:
Cheers 🍺
-
a year ago
xịn z
-
a year ago
hay quá
-
a year ago
Cảm ơn mn đã đọc qua 🥳🥳