Rendering client-side so với server-side

Rendering client-side so với server-side

Web cache – những khái niệm cơ bản
AWS Reserved Instance: tiết kiệm 3/4 chi phí cho AWS EC2/RDS
Thử dùng Envoy của Laravel để viết script deploy cho ứng dụng web

Kể từ thời khai thiên lập địa, các phương pháp thông thường để nhận HTML của trình duyệt là bằng cách sử dụng server-side rendering. Đó là cách duy nhất. Client tải các trang .html trên máy chủ bằng cách gửi yêu cầu lên máy chủ, sau đó máy chủ sẽ xử lý các yêu cầu của client biến nó thành những tài liệu hữu ích trên các trình duyệt của người dùng.

Server-side

Ngày đó, server-side đảm nhiệm hầu như mọi công việc to nhỏ, nặng nhọc. Nhưng mà thời kỳ đó hầu hết các trang web đều chủ yếu chỉ để hiển thị hình ảnh tĩnh và văn bản, với rất ít các tương tác với người dùng.

Sau một thời gian dài  thấy việc để server-side đảm nhiệm quá nhiều nhiệm vụ dẫn đến nhiều  khi server bị downtime ảnh hưởng nhiều đến các website. Không những thế các ứng dụng website hiện nay có vô vàn các chức năng tương tác với người dùng khác ngoài chức năng chỉ dùng để chia sẽ tại liệu như ngày xưa. Ví dụ như bạn có thể gửi tin nhắn, tương tác với những người khác, bán hàng với nhiều chức năng xem sản phẩm ….

Client-side

Vì vậy, nó đang cho chúng ta thấy rằng việc rendering từ phía máy chủ đang từ từ giảm dần và phương pháp rendering các trang trên phía client trở lên phát triển khi các thư viện JavaScript client-side bắt đầu có những đột phá mới.

Vậy nên, nhiều người tự hỏi rằng: “phương pháp nào là lựa chọn tốt nhất?”. Nhưng với hầu hết mọi thứ khi phát triển , nó sẽ phụ thuộc vào những gì bạn muốn làm với trang web của bạn. Bạn cần phải hiểu những ưu và nhược điểm của từng phương pháp rồi sau đó mới đưa ra quyết định chọn cách nào là tốt nhất cho dự án của mình. 

Cách hoạt động của server-side rendering

Server-side rendering là phương pháp phổ biến nhất để hiển thị thông tin lên màn hình cho người dùng. Nó hoạt động bằng cách chuyển đổi dữ liệu, thông tin trên máy chủ thành các tệp HTML cho trình duyệt có thể hiểu và sử dụng được.

Bất cứ khi nào bạn truy cập vào trang website, trình duyệt sẽ gửi yêu cầu lên máy chủ chứa nội dung của trang web. Thông thường mỗi yêu cầu thường chỉ mất vài mili giây, nhưng thực tế nó lại phụ thuộc khá nhiều vào các yếu tố sau đây:

  • Tốc độ đường truyền internet của bạn.
  • Vị trí máy chủ của trang website
  • Có bao nhiêu người cũng đang truy cập tại thời điểm bạn gửi yêu cầu.
  • Cách tối  ưu trang của website đó như thế nào.

Khi yêu cầu được hoàn tất, HTML sẽ được trả về cho trình duyệt để hiển thị lên màn hình của người dùng. Và cứ như thế, nếu bạn muốn chuyển sang một link khác thì trình duyệt của bạn sẽ lại tiếp tục gửi một yêu cầu mới đến  server. Điều này sẽ xảy ra mỗi lần vào trang mà phiên bản trình duyệt của bạn không có bộ nhớ cache.

Vấn đề là nếu trang mới chỉ có một vài mục khác với trang hiện tại, nhưng trình duyệt vẫn sẽ làm mới lại toàn bộ trang đó. Ví dụ một trang HTML này được đặt trên server và có địa chỉ website là: example.com

<! DOCTYPE html> 
 <html> 
  <head> 
  <meta charset="utf-8"> 
  <title> Website </title> 
  </head> 
  <body> 
  <h1> Website của tôi </h1> 
  <p> Một ví dụ về trang web của tôi </p> 
  <a href="http://example.com/other.html."> Trang khác </a> 
  </body> 
 </html>

Nếu bạn truy cập vào địa chỉ trên trình duyệt sẽ gửi yêu cầu đến máy chủ và đợi máy chủ phản hổi. Sau đó trình duyệt sẽ hiển thị nội dung của trang gồm tiêu đề , nội dung và một liên kết trên màn hình của bạn. Bây giờ, giả sử rằng bạn bạn muốn nhấp vào liên kết của trang vừa hiển thị có chứa nội dung như sau:

<! DOCTYPE html> 
<html> 
  <head> 
    <meta charset="utf-8"> 
    <title> Website </title> 
  </head> 
  <body> 
    <h1> Website của tôi </h1> 
    <p> Một ví dụ về trang web của tôi </p> 
    <p> Nội dung khác từ trang other.html </p> 
  </body> 
</html>

Sự khác biệt duy nhất giữa hai trang này là không có liên kết mà thay liên kết đó bằng một nội dung khác. Với logic bình thường thì sẽ làm như sau:

Thay thế:

<a href="http://example.com/other.html."> Trang khác </a> 


Thành:

<p> Nội dung khác từ trang other.html </p>


Nhưng than ôi! Server chưa đủ thông minh để hiểu và làm được như trên. Điều này có nghĩa là tất cả nội dung của toàn bộ trang sẽ được làm mới chứ không phải riêng phần nội dung bị thay đổi làm mới. Dẫn đến tình trạng chậm chạp trong việc phải rendering lại các thành phần không thay đổi . Mặc dù ví dụ trên hầu như mọi thứ không có vấn đề gì lớn lao nhưng một website thực tế thì nó không chỉ đơn giản như vậy. Các website thực tế nó có hàng nghìn dòng code và độ phức tạp của nó gấp nhiều lần ví dụ trên. Bây giờ, bạn hãy tưởng tượng mỗi khi vào website hay điều hướng sang một trang khác mà bạn phải chờ đợi sự chậm chạp của nó thì bạn sẽ có khuynh hướng tắt ngay tab của website đó trên trình duyệt và không muốn vào nó lần thứ hai. Và dĩ nhiên kết quả thật đáng buồn  là bạn đã mất đi người dùng.

Vế mặt tích cực, thì việc rendering ở server là rất tốt cho SEO. Nội dung của bạn có mặt trước khi bạn nhìn thấy nó, vì vậy các công cụ tìm kiếm dễ dàng có thể đánh index và thu thập thông tin cho từng page website của các bạn. Một điều có thể là khó khăn khi dùng hình thức client-side rendering mà tôi sẽ nói ngay sau đây.

Cách hoạt động của client-side rendering.

Khi các developer nói đến việc client-side redering thì có nghĩa là họ đang nói về việc hiển thị nội dung trong trình duyệt bằng cách sử dụng JavaScript. Vì vậy, thay vì nhận được tất cả nội dung chính từ HTML, bạn sẽ nhận được tài liệu HTML là khung của website kèm theo một tệp JavaScript sẽ dựng phần nội dung còn lại trang. Một ví dụ điển hình đó là trang instagram.com của Facebook xây dựng dựa trên ReactJS của chính họ tạo ra.

Đây là một cách tiếp cận tương đối mới về việc hiển thị trang web và nó không thực sự phổ biến cho đến khi các thư viện JavaScript bắt đầu kết hợp vào để phát triển các website. Bạn có thể tham khảo một số ví dụ của các thư viện JavaScript ở hình trên.

Quay lại ví dụ ở trên example.com, giả sử rằng bây giờ bạn có file index.html (ở đây tôi sử dụng một thư viện JavaScriptReactJS của Facebook)như sau:

<! DOCTYPE html> 
<html> 
<head> 
  <meta charset = "utf-8"> 
  <title> Website </ title> 
</ head> 
<body>
<div id="app"></ div>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></ script>
<script src="/app.js"></ script>
</ body>
</ html>

Bạn sẽ thấy ngay rằng có một số thay đổi trong file index.html khi nội dung trang không hề có trong file HTML khi render bằng client-side. Thay vì có có nội dung trong file HTML thì bạn có một vùng chứa nội dung có idapp . Và bạn cũng có thêm hai file JavaScript ,một là thư viện ReactJS, một là app.js sẽ chứa code để hiển thị nội dung cho trang.

Điều này hoàn toàn khác so với việc render từ phía server bởi vì server bây giờ chỉ chịu trách nhiệm tải dữ liệu về client. Mọi thứ khác đều được xử lý bên phía client bới thư viện của JavaScript. 

Nếu bạn gửi yêu cầu với đoạn mã trên bạn sẽ nhận được một màn hình trống. Không có gì để hiển thị vì toàn bộ nội dung của trang được hiển thị bằng JavaScript . Để khắc phục điều này bạn đặt đoạn mã dưới đây vào file app.js.

class OtherPage extends React.Component {
 constructor(props) {
 super(props);
 this.handleOtherClick = this.handleOtherClick.bind(this);
 this.state = {isOther: false};
 }

 handleOtherClick() {
 this.setState({isOther: true});
 }

 render() {
 const isOther = this.state.isOther;
 
 if (isOther) {
 return <ContentOtherPage />;
 } else {
 return <Link onClick={this.handleOtherClick} />;
 }
 }
}
var H1 = React.createClass({
 render: function() {
 return <h1>Website của tôi< /h1>;
 }
});
var Content = React.createClass({
 render: function() {
 return <p>Một ví dụ về trang web của tôi< /p>;
 }
});
var Link = React.createClass({
 render: function() {
 return <a href='#' onClick={this.props.onClick}>Trang khác< /a>;
 }
});

var ContentOtherPage = React.createClass({
 render: function() {
 return <p>Nội dung khác từ trang other.html< /p>;
 }
});
var Body = React.createClass({
 render: function() {
 return <div>
 <H1 />
 <Content />
 <OtherPage />
 < /div>;
 }
});

ReactDOM.render(
 <Body />,
 document.getElementById('app')
);

Nếu muốn xem nhanh ví dụ trên bạn có thể vào link jsfiddle này để chạy thử. Bây giờ nếu bạn truy cập vào thì bạn sẽ thấy  nội dung như bạn đã làm ví dụ trên server-side. Sự khác biệt chính đó là nếu bạn nhấp vào liên kết “Trang khác” để lấy nội dung trang đó thì trình duyệt sẽ không thực hiện yêu cầu mới cho máy chủ. Trình duyệt sẽ tải những nội dung mới dựa vào JavaScript và ReactJS sẽ đảm bảo rằng chỉ nội dung mới được hiển thị. Mọi thứ khác trên trang nếu không thay đổi sẽ vẫn giữ nguyên. Điều này nhanh hơn nhiều vì bạn chỉ cần tìm và thay đổi một phần nhỏ của trang thay vì tải toàn bộ trang như server-side.

Có một số vấn đề với việc sử dụng client-side, ví nội dung không được hiển thị ngay khi trang được tải trên trình duyệt nên việc SEO cho trang sẽ có một số vấn đề.  Có nhiều cách để giải quyết vấn đề này nhưng việc giải quyết không dễ dàng như bên server-side.

Một điều nữa cần lưu ý là trang website của bạn sẽ không được hiển thị cho đến khi tất cả JavaScript được tải xuống trình duyệt. Bởi vì tất cả nội dung của trang đều được chứa trong file JavaScript.Nếu người dùng của bạn đang sửu dụng kết nối internet chậm, có thể nó làm cho thời gian tải ban đầu của họ bị chậm một chút.

Những ưu nhược điểm của mỗi cách tiếp cận

Những gì tôi chỉ ra ở trên là những khác biệt chính giữa rendering phía server-side và client-side. Và còn tùy thuộc vào từng dự án mà các nhà phát triển sẽ quyết định lựa chọn phương án nào là thích hợp rendering phía server-side hay client-side hoặc kết hợp chúng lại với website hay ứng dụng của bạn.

Dưới đây tôi sẽ tổng hợp nhanh lại một số ưu và nhược điểm của từng phương pháp:

Server-side

Ưu điểm

  1. Các công cụ tìm kiếm có thể thu thập dữ liệu một cách dễ dàng để SEO tốt hơn.
  2. Tải trang ban đầu nhanh hơn.
  3. Là sự lựa chọn tuyệt vời cho các website tĩnh.

Nhược điểm

  1. Thường xuyên phải gửi yêu cầu lên máy chủ .
  2. Hiển thị trang chậm.
  3. Tải lại toàn bộ trang.
  4. Tương tác với người dùng không tốt.

Client-Side

Ưu điểm

  1. Tương tác người dùng tốt.
  2. Hiển thị trang nhanh sau khi tải ban đầu.
  3. Là sự lựa chọn tuyệt vời cho các ứng dụng website.
  4. Nhiều thư viện JavaScript mạnh mẽ hỗ trợ.

Nhược điểm

  1. Điểm SEO thấp nếu không thực hiện customize.
  2. Tải ban đầu cần nhiều thời gian.
  3. Hầu hết thường phải sử dụng các thư viện bên thứ 3.

 

COMMENTS