Dynamic Rendering là gì? Hướng dẫn thiết lập Dynamic Rendering cho các trang CSR bằng Nginx

Dynamic Rendering là gì? Hướng dẫn thiết lập Dynamic Rendering cho các trang CSR bằng Nginx

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Một phần mềm giúp chuyển đổi văn bản thành giọng nói do một lập trình viên người Việt làm ra - J2TEAM - Text to Speech (Free). Bạn có thể chuyển đổi hàng chục ngôn ngữ sang hàng chục giọng đọc tự nhiên khác nhau. Điều đặc biệt là nó miễn phí.

    Đánh giá sơ bộ thì chuyển đổi văn bản dài hoặc văn bản bằng tiếng Việt thuần thì rất tốt. Còn dính thêm các từ tiếng Anh thì nó đọc hơi buồn cười 😅

    » Xem thêm
  • Quá ghê ghớm, Codeium - vốn được biết đến như một đối thủ của Github Copilot, khi nó cho người dùng dùng miễn phí không giới hạn. Mới đây họ giới thiệu thêm Windsurf Editor - không chỉ còn là VSCode Extentions nữa mà là một trình Editor luôn - cạnh tranh trực tiếp với Cursor. Và điểm chính là nó... hoàn toàn miễn phí 🫣.

    » Xem thêm
  • Tin vui đầu này, Github Copilot đã chính thức có bản Free cho tất cả mọi người.

    Github Copilot là một trợ lý AI code cùng chúng ta, nó có thể tự động hoàn thành mã, trò chuyện hoặc sửa lỗi. Hiện đang hỗ trợ nhiều trình soạn thảo, IDE phổ biến như VSCode, JetBrains, XCode...

    Phiên bản miễn phí đang bị giới hạn 2000 Suggestions, và khoảng 50 requests đến tính năng Chat hàng tháng. Sau đó bạn có thể nâng cấp lên các phiên bản cao cấp hơn với giá từ 10$.

    Theo đánh giá của mình thì Copilot rất tốt và xứng đáng trong tầm giá, đang dùng hàng ngày 😄

    » Xem thêm

Vấn đề

SSR vs CSR

Những năm gần đây sự bùng nổ của các Framework về UX/UI như Angular hay React đang tạo nên một cuộc cách mạng về việc phát triển một trang web chú trọng vào tương tác người dùng và giao diện được xử lý hoàn toàn phía trình duyệt.

Những trang web như thế người ta gọi là Client Side Rendering (CSR) và thường được triển khai theo cách Single Page Application (SPA). Chúng tận dụng sức mạnh xử lý của thiết bị người dùng để giảm tải cho máy chủ, bên cạnh đó những trang web này thường mang lại trải nghiệm mượt mà bởi vì máy chủ chỉ cần gửi về mã Javascript cho thiết bị và việc lấy dữ liệu từ máy chủ chỉ cần thông qua API với dữ liệu cần thiết thay vì phải tải toàn bộ mã HTML.

CSR đang làm rất tốt nhiệm vụ của mình ở một khía cạnh nào đó, tuy nhiên chắc chắn rằng nó không tốt cho SEO. Cho những ai chưa biết SEO là gì thì nó là thuật ngữ chỉ việc website được tìm thấy trên internet thông qua những trang tìm kiếm như Google, Bing... Các trang tìm kiếm này liên tục "sai khiến" những con "bọ" truy cập vào tất cả các website mà nó biết để đọc nội dung. Những con "bọ" này đọc HTML rất tốt nhưng đối với Javascript thì không. Chính vì thế việc giúp các trang CSR thân thiện với SEO là một điều rất cần thiết.

Để đạt được điều đó có nhiều hơn một cách để thực hiện, ví dụ như sử dụng những thư viện hỗ trợ Server Side Rendering (SSR) hoặc build hoàn toàn website thành HTML static - Server Side Generation (SSG). Mỗi cách đều có ưu nhược điểm và phụ thuộc vào nhu cầu sử dụng, tuy nhiên trong bài viết này mình xin phép không đề cập đến 2 cách trên.

Thay vào đó, Google đã đề cập đến một giải pháp cho các trang web SPA muốn thân thiện với SEO đó chính là Dynamic Rendering. Vậy thì đó là như thế nào?

![Dynamic Rendering](https://img.youtube.com/vi/CrzUP6MmBW4/0.jpg)

Dynamic Rendering là gì?

Dynamic Rendering là thuật ngữ chỉ cách trả về kết quả truy vấn bằng cách phân biệt các User-Agent là người dùng bình thường hay là các con "bọ" từ công cụ tìm kiếm. Nếu là người dùng bình thường thì trả về mã Javascript, còn nếu là "bọ" thì trả về một trang HTML.

Dynamic Rendering

Bởi vì các con "bọ" tập trung quan tâm đến nội dung trang web của bạn thế nên việc trả về kết quả HTML là điều cần thiết để nó có thể thu thập thông tin. Còn về phía những người dùng, bên cạnh nội dung ra còn có UI/UX bởi họ thực sự tương tác với những thứ đang hiển thị trên trang web.

Để làm được điều đó chúng ta sẽ dựa vào chuỗi User-Agent của người dùng duyệt web. Vì User-Agent của người dùng và "bọ" tìm kiếm là có thể phân biệt được nên dựa vào đó ta sẽ trả được về kết quả mong muốn. Việc phân biệt phân biệt người dùng và "bọ" chúng ta có thể thực hiện ở máy chủ HTTP như Nginx hoặc nếu các bạn đang dùng Framework như Nuxt, Next... thì chúng có sẵn cấu hình để chúng ta có thể dễ dàng thiết lập.

Hiện tại có nhiều cách để có thể triển khai Dynamic Rendering. Chúng ta có thể tìm đến một dịch vụ của bên thứ 3 như là Prerender.io hoặc là tự triển khai một service tạo mã HTML bằng thư viện Rendertron của Google Chrome.

Cách tự triển khai service hỗ trợ rendering

Rendertron là một headless Chrome (Chrome nhưng không có giao diện :D) được thiết kế để render và tái tạo lại trang web một cách nhanh chóng.

Nghe thật thú vị phải không, trình duyệt nhưng lại không có giao diện thì sao mà duyệt web??? Bởi vì nó được thiết kế ra không phải cho duyệt web thông thường, việc loại bỏ các thành phần hiển thị giúp trình duyệt trở nên nhẹ và linh hoạt hơn trong môi trường máy chủ.

Rendertron có chỉ dẫn nhiều cách để tạo một máy chủ render. Ở đây giả sử tôi chạy một máy chủ Rendertron bằng module Express.js của Node:

const express = require('express');
const rendertron = require('rendertron-middleware');

const app = express();

app.use(
  rendertron.makeMiddleware({
    proxyUrl: 'http://my-rendertron-instance/render',
  })
);

app.use(express.static('files'));
app.listen(8080);

Với http://my-rendertron-instance là địa chỉ máy chủ của bạn. Để xem chi tiết cấu hình bạn có thể bấm vào Google Chrome Middleware.

Sau đó hãy thử truy cập vào địa chỉ http://my-rendertron-instance/render/your-spa-url với your-spa-url là địa chỉ trang CSR của bạn sẽ thấy kết quả trả về là mã HTML đã render của trang web.

Cấu hình Dynamic Rendering cho các trang CSR bằng Nginx

Nếu bạn đang triển khai một trang web CSR thông qua Nginx thì đây là hướng dẫn dành cho bạn.

Đầu tiên chúng ta cần xác định danh sách cách User-Agent của "bọ":

map $http_user_agent $is_bot {
        default                                     0;
        "~*Prerender"                               0;
        "~*googlebot"                               1;
        "~*yahoo!\ slurp"                           1;
        "~*bingbot"                                 1;
        "~*yandex"                                  1;
        "~*baiduspider"                             1;
        "~*facebookexternalhit"                     1;
        "~*twitterbot"                              1;
        "~*rogerbot"                                1;
        "~*linkedinbot"                             1;
        "~*embedly"                                 1;
        "~*quora\ link\ preview"                    1;
        "~*showyoubot"                              1;
        "~*outbrain"                                1;
        "~*pinterest\/0\."                          1;
        "~*developers.google.com\/\+\/web\/snippet" 1;
        "~*slackbot"                                1;
        "~*vkshare"                                 1;
        "~*w3c_validator"                           1;
        "~*redditbot"                               1;
        "~*applebot"                                1;
        "~*whatsapp"                                1;
        "~*flipboard"                               1;
        "~*tumblr"                                  1;
        "~*bitlybot"                                1;
        "~*skypeuripreview"                         1;
        "~*nuzzel"                                  1;
        "~*discordbot"                              1;
        "~*google\ page\ speed"                     1;
        "~*qwantify"                                1;
        "~*pinterestbot"                            1;
        "~*bitrix\ link\ preview"                   1;
        "~*xing-contenttabreceiver"                 1;
        "~*chrome-lighthouse"                       1;
        "~*telegrambot"                             1;
}

Sau đó cấu hình cho cách User-Agent này chuyển qua máy chủ Rendertron mà chúng ta đã tạo ở bên trên.

server {
    listen 80;
    server_name example.com;
    ...

    if ($is_bot = 1) {
        rewrite ^(.*)$ /rendertron/$1;
    }

    location /rendertron/ {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_pass http://my-rendertron-instance/render/$scheme://$host:$server_port$request_uri;   
    }
}

Hãy restart lại nginx và thử dùng trình duyệt với dùng Postman sử dụng User-Agent của "bọ" xem trang web của bạn đã trả về mã HTML chưa nhé!

Dưới đây là chuỗi User-Agent của Google.

Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

Tổng kết

Single Page App đang là xu hướng phát triển web hiện nay bởi những lợi ích mà nó mang lại. Tuy nhiên SPA không thân thiện với SEO, chính vì thế Dynamic Rendering là một trong những giải pháp để đưa SPA đến gần hơn với những công cụ tìm kiếm.

Cao cấp
Hello

5 bài học sâu sắc

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (1)

Nội dung bình luận...
Avatar
Văn Mạnh2 năm trước
Cách này tôi thấy tốc độ chậm đi đáng kể, nhưng ko sao bởi vì chỉ dành cho bot thôi mà :D
Trả lời
Avatar
Xuân Hoài Tống2 năm trước
Đúng rồi bạn nhưng nếu chậm quá thì cũng không tốt đâu vì mình được biết thuật toán của GG có tính cả điểm page speed nữa nên cần lưu ý