Next.js: nhiều ưu điểm lớn hay là điều phức tạp khi triển khai cho dự án Front-End của bạn 🤫

Microvn2 tháng 4 • 14 min read • 

Cuối tuần trước, thay vì viết blog như mọi lần, mình đã dành cho bản thân một chuyến picnic cùng mọi người trên công ty khá thú vị. Địa điểm mà bọn mình chọn là khu du lịch Đồng Mô kết hợp với về thăm nhà người em đồng nghiệp đồng thời là dự đám cưới ở trên ấy.

Vì thế nên bài viết này đã chậm hơn mục tiêu đề ra một chút. Để không phải khiến mọi người chờ lâu, mình sẽ tiếp tục với series "Tôi đã tạo ra Blog của mình như thế nào?". Như tuần trước, mình đã có một bài viết "Về nền tảng Back-End phía sau blog của mình" chia sẻ về Ghost cũng như có đánh giá một cách khách quan về nền tảng blog này. Vì vậy tuần này, mình sẽ giới thiệu về công nghệ mà mình đã chọn để xây dựng cho mặt tiền (Front-End) blog mình ra sao, mọi người cùng tìm hiểu nhé.

Mặt tiền trông đơn giản, vậy đã sử dụng gì?

Như bài trước, mình có đề cập tới câu chuyện sử dụng Headless CMS là Ghost để làm nơi quản lý blog, kết hợp với việc sử dụng API để khai thác dữ liệu cho đa nền tảng khác nhau. Đầu tiên, phải kể đến blog này, mình lựa chọn React, một library Front-end đã quá nổi tiếng trong nhiều năm gần đây. Nhưng mình không dùng phiên bản CRA hay là một Boilerplate nào đó trên GitHub mà mình lựa chọn Next.js

The React Framework for Production.
With Next.js, server rendering React applications has never been easier, no matter where your data is coming from.

Nói về công nghệ, ngoài React ra còn rất nhiều các library, framework phải kể đến như Angular, Svelte, Vue.js đang phát triển một cách vượt bậc với khả năng thiết kế các SPA (Single-page application) nhanh chóng, tiện lợi và hiệu quả.

Single-page application - Wikipedia

Như các bạn đã biết, React khá là tù trong khoản SEO (Search Engine Optimization), blog mà SEO dở là hỏng rồi, sẽ không có nhiều cơ hội để xuất hiện trên các cỗ máy tìm kiếm. Mình nói tù chứ không nói không thể nhé, làm được nhưng khá mệt, trong khi đó mình có thể dành thời gian nghiên cứu việc khác. Để nói về sự tù túng đó, mình cùng tìm hiểu về SSR và CSR trước nhé 😋.

SSR, CSR là gì ?

SSR = Server-side Rendering

Cho đến gần đây, đối với hầu hết các trang web được thiết lập nội dung trên máy chủ và được trả về dữ liệu để trình duyệt có thể hiện thị nó trên màn hình của người dùng. Bất cứ khi nào người dùng nhấp chuột vào liên kết trên trang, thì cũng là lúc yêu cầu máy chủ tạo một dữ liệu mới cho để cấu trúc lại trang và hiển thị cho người dùng.  

Người dùng phải chờ một khoảng thời gian nhất định để hoàn thành quá trình từ khi nhận được yêu cầu cho tới thu thập, soạn HTML và cuối cùng là trả về phản hồi. Vì SSR là tải bộ trang nên trình duyệt sẽ phải cố gắng đợi các tài nguyên khác như JavaScript, CSS và các nội dung khác được tải xuống (nếu dùng cache thì có thể không cần tải lại) trước khi để người dùng có thể thao tác trên trang. Đây là một bất tiện cho người dùng, khiến họ cảm thấy mất thời gian cũng như trải nghiệm bị giảm đi đáng kể. Bạn có thể xem mô tả dưới đây:

SSR WorkFlow
  1. Người dùng thông qua trình duyệt gửi yêu cầu xem trang tới máy chủ. Máy chủ đồng ý và đã sẵn sàng gửi trả lại toàn bộ các yêu cầu từ phía trình đã được kết xuất (render) thông qua HTML về cho trình duyệt.
  2. Trình duyệt nhận được thông tin và tiến hành kết xuất (render) trang web từ HTML được trả về từ máy chủ. Ngay trong lúc này, bạn có thể nhìn thấy nội dung cơ bản được trả về từ máy chủ. Song song với quá trình đó, trình duyệt sẽ tải các tài nguyên cần thiết khác như JavaScript, CSS.
  3. Trình duyệt đã tải xong các tài nguyên và tiến hành thực thi các đoạn mã như: JavaScript, CSS.
  4. Cuối cùng, khi hoàn tất quá trình tải xuống và thực thi. Lúc này, người dùng có thể thao tác vào trang web. Mỗi khi người dùng nhấp chuột vào các liên kết trong nội dung trang web, thì quy trình từ 1 tới 4 sẽ được lặp lại.


CSR = Client-side Rendering

Không giống với SSR, các SPA ngày nay đã sử dụng rất nhiều các công nghệ mới giúp cho việc giảm thiểu quá trình xử lý ở phía máy chủ. Hầu hết, các máy chủ sẽ chỉ trả về HTML tối thiểu cho quá trình kết xuất (render) dựa vào JavaScript. Quá trình hiển thị giao diện trang web cho người dùng sẽ cần nhiều thời gian để trình duyệt tải các các mã JavaScript, CSS sau đó chờ các đoạn mã được thực thi, cuối cùng là hiển thị và cho người dùng thao tác trên trang. Mỗi khi, người dùng nhấp vào liên kết trên trang, khác với SSR các đoạn mã JavaScript sẽ chủ động tìm nạp, yêu cầu máy chủ gửi các thông tin còn thiếu và tiến hành kết xuất lại trang web mà không cần tải lại toàn bộ giao diện người dùng. Điều này, sẽ khiến cho kích thước tải nạp trang giảm đi đáng kể và tận dụng được phần cứng của máy khách. Bạn có thể xem mô tả dưới đây:

CSR WorkFlow
  1. Người dùng thông qua trình duyệt gửi yêu cầu xem trang tới máy chủ. Máy chủ đồng ý và đã sẵn sàng gửi trả lại một phần thông tin HTML đủ để các đoạn mã Javascript có thể thực thi mà không gặp lỗi nào trong quá trình kết xuất (render).
  2. Trình duyệt nhận được thông tin và tiến hành kết xuất (render) trang web từ HTML được trả về từ máy chủ. Song song với quá trình đó, trình duyệt sẽ tải các tài nguyên cần thiết khác như JavaScript, CSS.
  3. Sau khi tải xong, các đoạn mã JavaScript sẽ được thực thi để kết xuất ra các HTML đầy đủ (Virtual DOM).
  4. Người dùng sẽ nhìn thấy và có thể thao thác dựa vào việc trình duyệt hiển thị nội dung trang web thông qua HTML đầy đủ ở quá trình trước.

SEO sẽ ảnh hưởng như thế nào khi sử dụng SSR hoặc CSR ?

Như vây, việc kết xuất ở máy chủ hay máy khách có liên quan trực tiếp đến việc thứ hạng trang web của bạn trên các cỗ máy tìm kiếm, chúng ta ai cũng đều mong muốn website của mình có thứ hạng cao.

Nhưng mà ngược lại, các cỗ máy tìm kiếm lại là kẻ tham lam, chỉ mong muốn trang web của bạn hiển thị trong thời gian ngắn điều đó đồng nghĩa với việc sẽ mang lại ít cơ hội cho các ứng dụng CSR.

Các Bot của máy tìm kiếm muốn ứng dụng của bạn có thời gian phản hồi nhanh chóng, các thông tin cơ bản phải sẵn sàng có trong nội dung HTML. Nếu cả 2 điều này đều không được thực hiện, các Bot sẽ luôn thấy một trang trắng.

Đây sẽ là nội dung mà Bot nhìn thấy - Ảnh: Internet

Mình sẽ tổng kết những điểm khác của SSR và CSR để các mọi người dễ hình dung:

SSR CSR
✓ Có thể nhìn thấy HTML ✕ HTML bị ẩn(chỉ nhìn thấy ở DevTool)
✓ Không phụ thuộc vào JavaScript ✓ Có nhiều lựa chọn Lib, Framework
✓ Dễ dàng cho SEO ✕ Bất lợi cho SEO
✓ Khởi tạo nhanh chóng ✓ Nhanh chóng hiển thị sau khi tải trang
✕ Tải lại toàn trang ✓ Giảm thiểu tải lại toàn trang
✕ Hạn chế nếu kết nối mạng chậm ✓ Hỗ trợ dựa vào mạng của người dùng
✕ Không khuyến khích máy chủ yếu ✓ Tận dụng được nguồn lực máy khách

Vậy tại sao lại là Next.js? Có cách nào khi sử dụng CSR cho SEO không?

Sau khi tìm hiểu về SSR và CSR bạn đã hiểu cơ bản về nó, vậy để mình chia sẻ các thêm các thông tin vì sao mình lại chọn Next.js:

  1. Trải nghiệm người dùng phong phú, dễ dàng thực hiện SSR, CSR kể cả SSG. Có nhiều các code mẫu được cập nhật liên tục.
  2. Có nhiều công ty lớn sử dụng, như: Netflix, Uber, Twitch...
  3. Kiến trúc của Next.js giúp gia tăng hiệu quả cho SEO.
  4. Hỗ trợ React cực tốt với hiệu suất vượt trội.
  5. Phát triển tính năng nhanh chóng mà không mất quá nhiều thời gian cho việc cấu hình, như: Static, Webpack, Babel
  6. Hỗ trợ Serverless.
  7. Hỗ trợ CSS tích hợp.
  8. Hỗ trợ chia và hợp code của bạn một cách tối ưu.
  9. Các hỗ trợ khác như TypeScript, Image Optimize, Fast Refresh bạn có thể tìm hiểu thêm tại đây.

Có một lưu ý khi bạn bắt đầu với Next.js là bạn phải chú ý tới 2 thời điểm, chỉ cần nắm bắt được nó, bạn sẽ có thể tùy chỉnh ứng dụng của bạn theo mong muốn.

  1. Thời điểm truy cập trang lần đầu tiên khi khi máy chủ bắt đầu kết xuất HTML, bạn sẽ phải quan tâm đến trạng thái khởi tạo lúc đó để xác định làm gì tiếp theo. Ví dụ: Khi kết xuất ở phía máy chủ, bạn không thể dùng biến window.abxyz giống như ở trình duyệt được, đồng nghĩa bạn sẽ không có localStorage, atob, btoa, etc etc...
  2. Thời điểm khi máy chủ đã hoàn tất quy trình kết xuất HTML cuối cùng và người dùng bắt đầu thao tác trên trang của bạn. Khi này thì bạn sẽ không thể sử dụng các chức năng ở dưới máy chủ như là context, request, request, etc etc...

Như vậy bạn đã biết sơ qua về Next.js, vậy chắc bạn tự hỏi nếu vẫn muốn sử dụng React mà không muốn sử dụng Next thì có cách nào không?

=)) có chứ, chắc chắn có. Tuy nhiên mình chỉ chia sẻ dưới góc độ các phương pháp khả thi mà mình biết ở thời điểm viết bài này, như:

Isomorphic/Universal React

Là ứng dụng cho phép chạy trên cả môi trường máy chủ và máy khách. Tương tự như Next.js như Gastby,... có rất nhiều các dự án như thế này trên Github phải kể đến React Redux Universal, After.js, Goldpage

Prerendering

Với ý tưởng là tách biệt 2 việc truy cập của người dùng và bot của máy tìm kiếm ra thành 2 việc riêng biệt. Khi bot truy cập sẽ được chuyển hướng tới trang đầy đủ để có thể thu thập thông tin, còn người dùng sẽ được sử dụng bình thường. Bạn có thể xem ý tưởng đó thông qua bức ảnh dưới đây.

Nguồn: https://yalantis.com/

Với việc sử dụng Prerendering bạn có thể sử dụng các dịch vụ SaaS hoặc thư viện dưới đây:

Ngoài ra bạn có thể điều hướng bot với nginx với đoạn mã như sau (nhớ thay domain.com bằng domain của bạn)

map $http_user_agent $limit_bots {
     default 0;
     ~*(google|bing|yandex|msnbot) 1;
     ~*(AltaVista|Googlebot|Slurp|BlackWidow|Bot|ChinaClaw|Custo|DISCo|Download|Demon|eCatch|EirGrabber|EmailSiphon|EmailWolf|SuperHTTP|Surfbot|WebWhacker) 1;
     ~*(Express|WebPictures|ExtractorPro|EyeNetIE|FlashGet|GetRight|GetWeb!|Go!Zilla|Go-Ahead-Got-It|GrabNet|Grafula|HMView|Go!Zilla|Go-Ahead-Got-It) 1;
     ~*(rafula|HMView|HTTrack|Stripper|Sucker|Indy|InterGET|Ninja|JetCar|Spider|larbin|LeechFTP|Downloader|tool|Navroad|NearSite|NetAnts|tAkeOut|WWWOFFLE) 1;
     ~*(GrabNet|NetSpider|Vampire|NetZIP|Octopus|Offline|PageGrabber|Foto|pavuk|pcBrowser|RealDownload|ReGet|SiteSnagger|SmartDownload|SuperBot|WebSpider) 1;
     ~*(Teleport|VoidEYE|Collector|WebAuto|WebCopier|WebFetch|WebGo|WebLeacher|WebReaper|WebSauger|eXtractor|Quester|WebStripper|WebZIP|Wget|Widow|Zeus) 1;
     ~*(Twengabot|htmlparser|libwww|Python|perl|urllib|scan|Curl|email|PycURL|Pyth|PyQ|WebCollector|WebCopy|webcraw) 1;
 } 

location / {
  if ($limit_bots = 1) {
    return 301 $scheme://domain.com$request_uri;
  }
}

Dành một chút thời gian cho Next.js

Trong khuôn khổ bài viết này, mình chỉ dành thời gian để cài đặt và thử nghiệm SSR và CSR cho mọi người. Để cho mọi người cảm nhận được sự khác biệt rõ rệt để khi vào dự án thực tế, chúng ta có thể chọn lựa cho mình phương án tốt nhất.

Bắt đầu với việc cài đặt theo hướng dẫn tại đây

npx create-next-app
# or
yarn create next-app

Bạn được kết quả như này, hãy cd vào thư mục chứa code (demo-nextjs) và chạy npm run dev cho môi trường development.

Cài đặt Next.js

HomePage sau khi bạn truy cập

Trang sau khi thiết lập thành công
Sử dụng React như bình thường.
Sửa một chút
Kết quả này

Thử kiểm tra SSR của Next nhé

Meta, Source Code được render phía SSR, nên khi view sẽ thấy HTML đầy đủ

Thử xem CSR xem nào

Chà, khi ở CSR. Title và HTML đã không được render ở phía SSR
Không có mà vẫn hiển thị này, đỉnh không =)). Sau khi render HTML ở server và trả về trình duyệt. Các đoạn mã JavaScript sẽ tìm nạp các phần HTML còn thiếu ở phía CSR để hiển thị. Kết quả như ảnh bên trái
Thay đổi meta một chút để test thử SEO với SSR trên Facebook. Mình cũng đã ghi chú Meta Tags ở dưới cho các bạn
Kiểm tra thử xem nhận meta cho SEO với debug của Facebook thông qua Ngrok
Thử viết bài mới...Nó hoạt động. Amazing!!

Còn rất nhiều các mục quan trọng khác mà bạn có thể tìm hiểu như Data Fetching, Pages, Built-In CSS Support, Environment Variables, Dynamic Component, Advanced. Bạn hãy sắp xếp thời gian trải nghiệm nó nhé. Mình tin rằng nó rất thú vị, tiện ích và nhanh chóng.

Tổng kết lại

Qua bài viết này, mình tin là bạn đã hiểu rõ hơn về SSR và CSR, điều này giúp các bạn định hình được việc phát triển các dự án có lợi cho SEO hay không? Không nhưng thế bài viết còn cung cấp cho bạn các giải pháp thay thế nếu bạn không thể sử dụng SSR.

Ngoài ra, Next.js là một dự án mà mình cho là tuyệt vời với nhiều ưu điểm lớn. Có thể triển khai dự án một cách nhanh chóng với việc thiết lập gần như tối thiểu. Điều đáng giá hơn cả là nó còn có số lượng lớn các nhà phát triển trên khắp thế giới song song là các phiên bản code example mà bạn có thể khai thác tại đây. Trải qua khoảng gần 3 năm làm việc với Next, mình tin và hi vọng nó sẽ còn phát triển vượt bậc trong tương lai.

Và dĩ nhiên là đôi khi bạn không cần phải cầm dao mổ trâu đi giết gà, nếu ngoài mục đích thử nghiệm cơ bản, theo mình bạn có thể sử dụng CRA, còn Next sẽ phù hợp các trang web cần SEO như: ấn phẩm magazine, báo chí, thương mại điện tử, quảng cáo, quảng bá thương hiệu, blog, trang giới thiệu sản phẩm, vân vân.. nó sẽ ít được dùng cho các sản phẩm không quan tâm đến SEO như: trang quản lý (Admin, CMS), các công cụ đặc biệt nào đó...

Một số dự án mình đã sử dụng Next: http://oklabel.vn/, http://microvn.net/ và mình có 1 bộ nextjs-startkit dành cho các bạn mới bắt đầu tìm hiểu về nó nhé.

Cuối cùng, cảm ơn các bạn đã dành thời gian đọc bài viết của mình, nếu có sai sót nào đó bạn có thể nhắn qua Facebook cá nhân hoặc email: microvn.gm@gmail.com cho mình nhé.

Nguồn: Microvn.net

Tham khảo:
Complete List of HTML Meta Tags
Next.js, ShowCase
Awesome Universal Rendering
Prerender.io nginx.conf for nginx
How to Make React SEO-Friendly: an Extensive SEO Guide
Performance Next.js (SSR) vs. Create React App (CSR)