Chuyển Đổi Website SSR Thành SPA Dễ Dàng
Chúc mọi người một năm mới tràn đầy hạnh phúc và thịnh vượng! ♥️♥️♥️
Với sự phát triển của công nghệ, việc xây dựng một website vừa tối ưu SEO (Server-Side Rendering - SSR) vừa mang lại trải nghiệm người dùng mượt mà (Single Page Application - SPA) trở nên dễ dàng hơn bao giờ hết. Hôm nay, chúng ta sẽ khám phá cách biến một website SSR truyền thống thành một ứng dụng SPA mà không cần sử dụng các framework phổ biến như Next.js hay Nuxt.js.
Khái Niệm Cơ Bản
SSR (Server-Side Rendering)
SSR là phương pháp mà server tạo ra nội dung của trang web (HTML, CSS, JS) và gửi đến trình duyệt. Điều này mang lại lợi ích về tốc độ tải trang và tối ưu cho SEO, tuy nhiên, điểm trừ của SSR là khi chuyển trang, người dùng sẽ trải nghiệm một khoảng dừng do phải yêu cầu server tái tạo nội dung.
CSR (Client-Side Rendering)
Ngược lại, CSR cho phép rendering nội dung tại client (trình duyệt). Server chỉ cần gửi HTML chứa các tài nguyên cần thiết, sau đó JavaScript sẽ tải dữ liệu và render nội dung. Điều này giúp tạo ra trải nghiệm mượt mà nhưng lại ảnh hưởng không tốt đến SEO vì HTML ban đầu không chứa nội dung hữu ích cho crawler.
SPA (Single Page Application)
SPA là ứng dụng web mà toàn bộ nội dung chỉ được tải một lần trong quá trình tải trang đầu tiên. Khi người dùng tương tác, SPA sẽ cập nhật nội dung mà không phải tải lại trang, tạo ra trải nghiệm tương tác mượt mà và liên tục.
Kết Hợp SSR và CSR Trong SPA
Sự kết hợp giữa SSR và CSR mang lại cả hai lợi ích: SEO tốt hơn và trải nghiệm người dùng mượt mà. Hầu hết các framework hiện nay như Next.js hay Nuxt.js đều hỗ trợ tính năng này. Tuy nhiên, trong bài viết này, chúng ta sẽ thực hiện điều đó với Vanilla JS.
Bước 1: Lắng Nghe Sự Kiện Click
Khi người dùng click vào các liên kết nội bộ, ta sẽ ngăn chặn sự kiện mặc định để không tải lại toàn bộ trang.
javascript
function getLinkTarget(target) {
while (target && target.nodeName != 'A') {
target = target.parentNode;
}
return target;
}
function click(e) {
var a = getLinkTarget(e.target);
if (!a) return;
if (e.which > 1 || e.metaKey || e.ctrlKey) return;
e.preventDefault();
loadPage(a.href);
}
document.body.addEventListener('click', click, true);
Bước 2: Lấy Nội Dung Trang Mới
Sử dụng XMLHttpRequest hoặc Fetch API để lấy nội dung từ trang mới.
javascript
var $xhr = new XMLHttpRequest();
function loadPage(url) {
$xhr.open('GET', url);
$xhr.send();
if ($xhr.getResponseHeader('Content-Type').match(/\/(x|ht|xht)ml/)) {
var doc = document.implementation.createHTMLDocument('');
doc.documentElement.innerHTML = $xhr.responseText;
var title = doc.title;
var body = doc.body;
displayPage(title, body, url);
}
}
Bước 3: Hiển Thị Trang Mới
Thay đổi tiêu đề và nội dung của trang hiện tại bằng nội dung mới mà ta đã tải về.
javascript
function displayPage(title, body, newUrl) {
document.documentElement.replaceChild(body, document.body);
history.pushState(null, null, newUrl);
scrollTo({left: 0, top: 0, behavior: 'instant'});
document.title = title;
}
Bước 4: Chạy Các Script Trên Trang Mới
Cuối cùng, nhật thực thi các file script trong nội dung mới để đảm bảo tất cả tính năng hoạt động như mong muốn.
javascript
var scripts = document.body.getElementsByTagName('script'), script, copy, parentNode, nextSibling;
for (var i = 0, j = scripts.length; i < j; i++) {
script = scripts[i];
copy = document.createElement('script');
if (script.src) copy.src = script.src;
if (script.innerHTML) copy.innerHTML = script.innerHTML;
parentNode = script.parentNode;
nextSibling = script.nextSibling;
parentNode.removeChild(script);
parentNode.insertBefore(copy, nextSibling);
}
Và như vậy, bạn đã hoàn thành bước chuyển đổi một website SSR thành SPA để cải thiện trải nghiệm người dùng. Đây là những bước cơ bản, bạn có thể mở rộng thêm bằng cách thêm thanh tiến độ (progress bar) hay các tính năng khác để cải thiện hơn nữa.
Lưu Ý: Hãy chắc chắn rằng các trang đều sử dụng chung CSS để có trải nghiệm mượt mà.
Demo
- Framework: Nest.js (MVC)
- Link: Giarevn.com
Nhờ vào việc chỉ sử dụng HTML và một ít JavaScript đơn giản (không dựa vào các framework nặng), website của bạn có thể đạt điểm số cao trên PageSpeed.
source: viblo