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

Threads
  • Hôm trước mình thấy repository này dùng TauriSvelte để viết lại ứng dụng kiểu như là Task Manager trên Window hay Monitor trên Mac á. Tò mò tải về xem thử thì bất ngờ thứ nhất là dung lượng rất nhỏ, chỉ vài MB. Tiếp theo là tốc độ khởi động cũng rất nhanh mà ứng dụng cũng rất mượt nữa chứ 🫣

    Abdenasser/neohtop

    » Xem thêm
  • Tuôi" để ý là cứ đợt nào ham đọc cái là lại lười viết, tuần nay tuôi đang đọc một lúc 3 cuốn, à phải là đọc 2 và nghe 1.

    Cuốn sách ám ảnh nhất đến thời điểm hiện tại: Đại dương đen - thuật lại 12 câu chuyện của 12 người mắc bệnh trầm cảm. Thần kinh vững, nhưng mới đọc 2 câu truyện đầu thôi mà cảm giác ngộp thở, bứt rứt thật khó tả 😰

    Câu chuyện tiếp theo đó thì mang lại cảm giác dễ thở hơn vì họ kiểm soát được bản thân. Nhưng sang tiếp câu chuyện thứ 4, thứ 5 thì lại như một có một bàn tay siết họng mình lại. Không thể nhắm mắt mà nghe được á, có gì đó rất đáng sợ.

    Một câu mà mình cảm thấy ám ảnh nhất là khi ba mẹ của người mắc trầm cảm luôn miệng hỏi tại sao con lại như thế mỗi khi sắp lên cơn và gào thét. Họ chỉ đành bất lực trả lời là "Làm sao mà con biết! Cũng giống như hỏi một người bị ốm là tại sao lại ốm? Làm sao mà biết được chứ! Có ai muốn đâu!".

    » Xem thêm
  • Mistral.ai là một công ty AI có trụ sở tại Pháp, được biết đến với nhiều mô hình ngôn ngữ lớn Mistral. Mới đây họ vừa ra mắt thêm một số mô hình có kích thước siêu lớn, siêu mạnh... Nhưng tạm khoan nói đến vì Mistral Chat cũng vừa được ra mắt với nhiều tính năng hay ho tương tự như Chat GPT mà lại miễn phí 😇

    » 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.

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 ý