- vừa được xem lúc

Biến website SSR bất kỳ thành SPA chỉ với vài dòng code

0 0 3

Người đăng: AlexX

Theo Viblo Asia

Trước khi đi vào bài viết, mình xin kính chúc mọi người một năm mới tràn đầy hạnh phúc, an khang, thịnh vượng ♥️♥️♥️

Với sự phát triển của công nghệ thì việc xây dựng một website vừa SEO tốt (SSR) vừa mượt mà (SPA) đã rất đơn giản với sự hổ trợ tận răng của các super framework như Next.js hay Nuxt.js. Tuy nhiên trong bài này chúng ta sẽ làm cho một website SSR truyền thống trở nên mượt mà hơn mà không sử dụng Next hay Nuxt.

Một số khái niệm (ngắn gọn)

SSR

SSR (Server-Side Rendering) là server sẽ tạo các nội dung của trang (HTML, CSS, JS) và gửi chúng đến trình duyệt để hiển thị. Điều này giúp tải trang nhanh, SEO tốt, tuy nhiên lúc chuyển trang sẽ "khựng" một chút do lại phải request đến server để render (tải lại trang).

CSR

CSR (Client-Side Rendering) ngược lại sẽ render nội dung ở phía client (trình duyệt), server chỉ cần gửi html chứa các tài nguyên CSS, JS cần thiết, sau đó trình duyệt sẽ sử dụng javascript để tải dữ liệu và render các nội dung của trang. Việc này sẽ khiến SEO không tốt do html ban đầu chưa có nội dung gì.

SPA

SPA (Single Page Application) là một loại ứng dụng web mà tất cả các trang và nội dung của ứng dụng được tải một lần duy nhất trong quá trình tải trang ban đầu. Thay vì tải lại trang khi người dùng điều hướng hoặc thực hiện hành động, SPA chỉ cần thay đổi nội dung trang bằng cách thực thi mã JavaScript, mà không cần tải lại toàn bộ trang tạo ra trải nghiệm tương tác mượt mà.

Kết hợp SSR và CSR trong SPA

Kết hợp SSR và CSR là kết hợp ưu điểm của cả hai, giúp SPA của bạn vừa SEO tốt hơn, vừa có trả nghiệm mượt mà. Các framework như Next.js, Nuxt.js đều mặc định hỗ trợ việc này với các tên gọi khác nhau như SSR, Dynamic Rendering (Next.js) hoặc Universal Rendering (Nuxt.js). Tuy nhiên như đã đề cập ở trên, chúng ta sẽ không dùng các framework trên mà chỉ sử dụng Vanilla JS (Javascript thuần).

Trước tiên chúng ta sẽ cần một trang web SSR truyền thống, tạo bới Laravel, RoR hay Nestjs chẳng hạn. Tạo một file js và bắt đầu coding thôi

Lắng nghe sự kiện khi click vào nội dung trên trang

Khi click vào các internal link trong trang thì preventDefault để trang web không load lại mà chúng ta sẽ tự xử lý.

 function getLinkTarget(target) { while (target && target.nodeName != 'A') { target = target.parentNode; } return target; } function click(e) { // Lấy phần tử A từ phần tử được click var a = getLinkTarget(e.target); // Nếu không phải phần tử A thì không làm gì, nên kiểm tra thêm các // điều kiện khác như là external link, link có attribute download... if (!a) { return; } // mở link trong tab mới thì không làm gì if (e.which > 1 || e.metaKey || e.ctrlKey) { return; } // event thỏa mản điều kiện thì preventDefault để trình duyệt không load lại trang // và thực hiện display trang mới e.preventDefault(); loadPage(a.href); } // Lắng nghe sự kiện click trên toàn bộ trang document.body.addEventListener('click', click, true);

Get nội dung của link được click bằng XMLHttpRequest

Dùng xhr(hoặc fetch) để get nội dung của của page mới

var $xhr = new XMLHttpRequest(); function loadPage(url) { // Dùng XMLHttpRequest để get nội dung trang web $xhr.open("GET", url); $xhr.send(); // Nếu trang web trả về HTML, lấy title và body của trang web 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; // Hiển thị page đã get displayPage(title, body, url) }
}

Hiển thị page đã get

Sau khi đã get được nội dung của page mới, dùng javascript để thay đổi nội dung, title của page hiện tại bằng data mới.

function displayPage(title, body, newUrl) { // Thay thế body bằng body mới đã get được bằng xhr document.documentElement.replaceChild(body, document.body); // Sử dụng History API để thay đổi url trên thanh địa chỉ history.pushState(null, null, newUrl); // Scroll về đầu trang khi chuyển sang trang mới scrollTo({ left: 0, top: offset, behavior: 'instant', }); // Thay đổi title thành title mới document.title = title;
}

Thực hiện chạy các file script trên trang mới

Cuối cùng, khi thay đổi nội dung trang web bằng hàm replaceChild() ở bước bên trên thì các script trên trang mới không được tự động thực thi, nên ta cần bắt nó phải chạy. Bạn có thể thêm logic để chỉ định những script chỉ cần chạy 1 lần và không cần chạy lại khi chuyển trang.

var scripts = document.body.getElementsByTagName("script"), script, copy, parentNode, nextSibling; for (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);
}

Như vậy là chúng ta đã hoàn thành việc biến một website SSR trở thành một SPA, giúp trang web của bạn mượt mà hơn. Trên đây chỉ là các bước cơ bản, để hoàn thiện hơn thì bạn sẽ cần code nhiều hơn, như thêm progress bar chẳng hạn...

Lưu ý: giữa các page cần dùng chung css, nếu mỗi page dùng css riêng thì bạn cần code thêm để load css mới nhé. Lưu ý 2:

Demo

Do chủ yếu chỉ có HTML và một ít js (do không dùng các framework nặng) và nội dung cũng không có gì 🤣 nên được chấm full điểm PageSpeed.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Single Page Application Concept

Bạn đã từng nghe về một trang wed Single page hay chưa? Dạo gần đây Single page application là một cái tên đang nổi trong xu hướng phát triển web. Mặc dù concept này đã ra đời hơn chục năm nay.

0 0 35

- vừa được xem lúc

Xây dựng một Single-page Application cơ bản với React Router DOM như thế nào ?

Mở đầu. Trong những website thông thường khi điều hướng từ page này sang page khác, chúng ta sẽ sử dụng thẻ <a> để làm điều đó, nhưng trong React JS thường được sử dụng để xây dựng nhữmg Single Page A

0 0 215

- vừa được xem lúc

Đây là 6 lý do mà mình sử dụng công nghệ Single Page App (SPA) cho Website

Vâng, bài viết đầu tay của mình là những chia sẻ về ý tưởng, cảm nhận của mình khi bắt tay vào làm với SPA (Single Page App). Tại sao mình lại chọn SPA cho những ứng dụng Webstie của mình thì mời các

0 0 8

- vừa được xem lúc

Cẩn thận với Server-Side Plugins trong Nuxt.js

Nếu bạn build một ứng dụng server-side rendering (SSR) với Nuxt.js, bạn hoàn toàn có thể tạo ra một ứng dụng với độ linh hoạt cao cùng với trải nghiệm hiệu suất tuyệt vời.

0 0 91

- vừa được xem lúc

Tạo website kiết xuất phía máy chủ ( server side rendering ) với Angular Universal

Giới thiệu. Kiết xuất phía máy khách (CSR) là gì. . Đây là một phương pháp kết xuất hiện đại vì không có nhận toàn bộ trang HTML.

0 0 52

- vừa được xem lúc

Tạo Web CURD đơn giản với Nodejs + Mysql + EJS

Mở đầu. Trong bài viết này mình sẽ tạo web CRUD đơn giản bằng Nodejs sử dụng Mysql , Express, Ejs.

0 0 24