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
  • Hẳn là nhiều người ở đây đã nghe đến kiểu tấn công bảo mật Clickjacking rồi nhỉ. Kẻ tấn công thường nhúng một website (thường là mục tiêu) vào trong một iframe trên website của chúng, sau đó làm mờ hoặc ẩn nó đi rồi đặt vào vị trí các nút bấm trên web, ví dụ "Bấm vào để nhận quà". Đâu ai ngờ rằng phía trên nút bấm đó là một nút bấm khác trong iframe. Khá nguy hiểm!

    Nhưng trình duyệt đã có cách ngăn chặn kiểu tấn công này bằng các quy tắc như tiêu đề X-Frame-Options, frame-ancestors của CSP và SameSite: Lax/Strict của Cookies...

    Mới đây, đã xuất hiện thêm kiểu tấn công mới - "DoubleClickjacking" 😨. Đại ý là "hắn" lợi dụng hành động double click để lừa người dùng bấm vào một nút mà hắn muốn. Chi tiết hơn trong bài viết này: DoubleClickjacking: A New Era of UI Redressing.

    » Xem thêm
  • Mọi người đã nghe nói đến Jujutsu - jj - một dạng quản lý phiên bản cho mã nguồn (version control system) chưa? Có vẻ như nó đang nhận được nhiều sự quan tâm.

    Chờ xíu! Chẳng phải git đã quá tốt rồi sao? Thế thì chế ra thằng jj để làm gì nữa? Cũng hơi khó trả lời nhỉ? Mỗi công cụ sinh ra chắc chắn phải cải thiện hoặc khắc phục được nhược điểm của cái trước. Cho nên jj ắt hẳn phải làm được điều gì đó mà git chưa làm được nên mới nổi lên như vậy.

    Thật ra mình đã nghe nói đến jj từ vài tháng trước rồi, nhưng vào đọc thì toàn kiến thức cao siêu. Hoặc là đang mang nặng cái lối suy nghĩ của git vào trong đầu rồi nên chưa lĩnh hội ra được điều gì cả.

    Mình hay có kiểu cái gì đọc lần 1 mà không hiểu thì đọc tiếp lần 2, lần 2 không hiểu thì đọc tiếp lần 3... đến lần thứ n mà vẫn không hiểu thì bỏ. Cơ mà không phải là từ bỏ mà một thời gian sau đó quay lại đọc tiếp. Đến một lúc nào đó khả năng mình sẽ hiểu ra một ít vấn đề, thế mới tài 😆.

    Thì cái jj này có vẻ như nó đang mở ra được tính linh hoạt trong việc "cam kết" mã. Tưởng tượng bạn đang làm việc trên một dự án, đang ở nhánh này, muốn sang nhánh khác để sửa, nhưng mà lại đang viết dở ở nhánh này, thế là phải stash, rồi checkout, rồi commit, rồi merge hoặc rebase lại vào nhánh cũ... nhìn chung quá trình làm việc với git nghiêm ngặt đến mức cứng nhắc, cần nhiều thao tác để giải quyết một vấn đề, chưa kể cái cây commit (commit-tree) nữa thì ôi thôi, khỏi xem cho đỡ nhức mắt. Thế nên ông jj này đang làm cách nào đó để bạn khỏi cần phải quan tâm đến các nhánh luôn, sửa trực tiếp vào commit. Nghe ảo nhỉ 😂.

    Đấy mới lĩnh hội được đến đấy, hy vọng sau n lần đọc lại nữa mình sẽ viết được một bài chi tiết hơn về công cụ này.

    » Xem thêm
  • Gòi gòi tới công chiện gòi 🤤🤤🤤

    » 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

Tôi & khao khát "chơi chữ"

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên 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.

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 ý
Bấm hoặc cuộn mạnh để sang bài mới