Chào mừng đến với Cafedev! Trong bài viết này, chúng ta sẽ khám phá một chủ đề thú vị: Vuejs with Server-Side Rendering (SSR). Vue.js là một framework mạnh mẽ cho việc xây dựng các ứng dụng phía client. Nhưng bạn đã bao giờ tự hỏi về cách kết hợp Vue với Server-Side Rendering (SSR) chưa? Trải nghiệm này không chỉ giúp cải thiện hiệu suất ứng dụng mà còn tăng cường khả năng tìm kiếm trên web. Hãy cùng khám phá nhé!

1. Tổng quan

1.1 SSR là gì?

Vue.js là một framework để xây dựng ứng dụng dành cho client-side. Theo mặc định, các thành phần Vue tạo ra và thao tác DOM trong trình duyệt để tạo ra đầu ra. Tuy nhiên, cũng có thể render các thành phần tương tự thành chuỗi HTML trên máy chủ, gửi chúng trực tiếp đến trình duyệt, và cuối cùng “hydrate” (thẩm thấu) đánh dấu tĩnh thành một ứng dụng hoàn toàn tương tác trên máy khách.
Một ứng dụng Vue.js được render trên máy chủ cũng có thể được xem xét là “isomorphic” hoặc “universal”, trong ý nghĩa rằng phần lớn mã của ứng dụng của bạn chạy trên cả máy chủ máy khách.

1.2 Tại sao lại sử dụng SSR?

So với ứng dụng Single-Page Application (SPA) dành cho client-side, ưu điểm chính của SSR chủ yếu nằm ở:


Thời gian hiển thị nội dung nhanh hơn: Điều này trở nên đáng chú ý hơn trên internet chậm hoặc thiết bị chậm. Đánh dấu được render trên máy chủ không cần phải chờ đợi cho đến khi tất cả JavaScript đã được tải xuống và thực thi để hiển thị, do đó người dùng sẽ thấy trang đã được render hoàn toàn sớm hơn. Ngoài ra, việc truy xuất dữ liệu được thực hiện ở phía máy chủ cho lần truy cập ban đầu, có thể có kết nối tốc độ nhanh hơn đến cơ sở dữ liệu của bạn so với máy khách. Điều này thường dẫn đến cải thiện Core Web Vitals metrics, trải nghiệm người dùng tốt hơn, và có thể quan trọng đối với các ứng dụng mà thời gian hiển thị nội dung liên quan trực tiếp đến tỷ lệ chuyển đổi.
Mô hình thống nhất: Bạn có thể sử dụng cùng ngôn ngữ và cùng mô hình khai báo, hướng thành phần để phát triển toàn bộ ứng dụng của mình, thay vì phải chuyển đổi giữa hệ thống mẫu backend và framework frontend.
Tối ưu hóa SEO: Các công cụ tìm kiếm sẽ trực tiếp nhìn thấy trang đã được render hoàn toàn.

tip Hiện tại, Google và Bing có thể chỉ mục các ứng dụng JavaScript đồng bộ tốt. Từ “đồng bộ” là từ khóa ở đây. Nếu ứng dụng của bạn bắt đầu bằng một biểu tượng quay vòng, sau đó truy xuất nội dung qua Ajax, công cụ tìm kiếm sẽ không chờ bạn kết thúc. Điều này có nghĩa là nếu bạn có nội dung được truy xuất bất đồng bộ trên các trang mà SEO quan trọng, SSR có thể là cần thiết.

Tuy nhiên, cũng có một số ưu điểm cần cân nhắc khi sử dụng SSR:

  • Ràng buộc trong quá trình phát triển. Mã cụ thể cho trình duyệt chỉ có thể được sử dụng trong một số vòng đời hooks; một số thư viện bên ngoài có thể cần xử lý đặc biệt để có thể chạy trong ứng dụng được render trên máy chủ.
  • Yêu cầu cài đặt và triển khai phức tạp hơn. Không giống như một SPA tĩnh hoàn toàn có thể triển khai trên bất kỳ máy chủ tệp tĩnh nào, một ứng dụng được render trên máy chủ đòi hỏi một môi trường mà máy chủ Node.js có thể chạy.
  • Tải trọng phía máy chủ nhiều hơn. Việc render một ứng dụng đầy đủ trong Node.js sẽ tốn nhiều tài nguyên CPU hơn là chỉ phục vụ các tệp tĩnh, vì vậy nếu bạn mong đợi lưu lượng lớn, hãy chuẩn bị cho tải trọng máy chủ tương ứng và sử dụng một cách thông minh các chiến lược caching.
    Trước khi sử dụng SSR cho ứng dụng của bạn, câu hỏi đầu tiên bạn nên đặt ra là liệu bạn thực sự cần nó không. Điều này chủ yếu phụ thuộc vào thời gian hiển thị nội dung đối với ứng dụng của bạn. Ví dụ, nếu bạn đang xây dựng một bảng điều khiển nội bộ mà thêm một vài trăm mili giây vào lúc tải ban đầu không quan trọng nhiều, thì SSR sẽ là một lựa chọn quá lớn. Tuy nhiên, trong những trường hợp thời gian hiển thị nội dung là hoàn toàn quan trọng, SSR có thể giúp bạn đạt được hiệu suất tải ban đầu tốt nhất có thể.

1.3 SSR so với SSG

Tạo trang tĩnh (SSG), còn được gọi là tạo trước, là một kỹ thuật phổ biến khác để xây dựng các trang web nhanh chóng. Nếu dữ liệu cần thiết để server-render một trang là giống nhau cho mọi người dùng, thì thay vì render trang mỗi khi có yêu cầu, chúng ta chỉ cần render nó một lần, trước thời gian, trong quá trình xây dựng. Các trang được tạo trước được tạo và phục vụ dưới dạng các tệp HTML tĩnh.

SSG giữ lại các đặc điểm hiệu suất giống như ứng dụng SSR: nó cung cấp hiệu suất thời gian hiển thị nội dung tuyệt vời. Đồng thời, nó cũng rẻ hơn và dễ triển khai hơn so với các ứng dụng SSR vì đầu ra là HTML tĩnh và tài nguyên. Từ khóa ở đây là tĩnh: SSG chỉ có thể được áp dụng cho các trang tiêu thụ dữ liệu tĩnh, tức là dữ liệu được biết trước khi xây dựng và không thay đổi giữa các lần triển khai. Mỗi khi dữ liệu thay đổi, cần có một lần triển khai mới.

Nếu bạn chỉ đang nghiên cứu về SSR để cải thiện SEO của một số trang tiếp thị (ví dụ /, /about, /contact, vv.), thì bạn có thể muốn SSG thay vì SSR. SSG cũng tuyệt vời cho các trang web dựa trên nội dung như trang tài liệu hoặc blog. Trong thực tế, trang web bạn đang đọc ngay bây giờ được tạo tĩnh bằng cách sử dụng VitePress, một công cụ tạo trang tĩnh được cung cấp bởi Vue.

2. Hướng dẫn cơ bản

2.1 Render một ứng dụng

Hãy xem xét ví dụ đơn giản nhất về Vue SSR hoạt động.
1. Tạo một thư mục mới và cd vào đó

2. Chạy npm init -y

3. Thêm "type": "module" vào package.json để Node.js chạy ở chế độ module ES.

4. Chạy npm install vue

5. Tạo một tệp example.js:

// this runs in Node.js on the server.
import { createSSRApp } from 'vue'
// Vue's server-rendering API is exposed under `vue/server-renderer`.
import { renderToString } from 'vue/server-renderer'

const app = createSSRApp({
  data: () => ({ count: 1 }),
  template: `<button @click="count++">{{ count }}</button>`
})

renderToString(app).then((html) => {
  console.log(html)
})

Sau đó chạy:

node example.js

Nó sẽ in ra dòng sau trên dòng lệnh:

<button>1</button>


renderToString() lấy một instance ứng dụng Vue và trả về một Promise giải quyết thành HTML đã render của ứng dụng. Cũng có thể stream rendering bằng cách sử dụng API Stream của Node.js hoặc API Web Streams. Kiểm tra Tài liệu Tham chiếu SSR để biết chi tiết đầy đủ.

Tiếp theo, chúng ta có thể chuyển mã Vue SSR vào một trình xử lý yêu cầu máy chủ, làm bao bọc dấu ngoặc của ứng dụng với HTML trang đầy đủ. Chúng ta sẽ sử dụng express cho các bước tiếp theo:

  • Chạy npm install express
  • Tạo tệp server.js sau đây:
import express from 'express'
import { createSSRApp } from 'vue'
import { renderToString } from 'vue/server-renderer'

const server = express()

server.get('/', (req, res) => {
  const app = createSSRApp({
    data: () => ({ count: 1 }),
    template: `<button @click="count++">{{ count }}</button>`
  })

  renderToString(app).then((html) => {
    res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Vue SSR Example</title>
      </head>
      <body>
        <div id="app">${html}</div>
      </body>
    </html>
    `)
  })
})

server.listen(3000, () => {
  console.log('ready')
})

2.2 Hydrat hóa từ phía máy khách

Nếu bạn nhấp vào nút, bạn sẽ nhận thấy số không thay đổi. HTML là hoàn toàn tĩnh trên máy khách vì chúng ta không tải Vue trong trình duyệt.
Để làm cho ứng dụng phía máy khách trở nên tương tác, Vue cần thực hiện bước hydration. Trong quá trình hydration, nó tạo ra cùng một ứng dụng Vue đã chạy trên máy chủ, phù hợp mỗi thành phần với các nút DOM mà nó nên điều khiển, và gắn các trình lắng nghe sự kiện DOM.

Để gắn một ứng dụng ở chế độ hydration, chúng ta cần sử dụng createSSRApp() thay vì createApp():


// this runs in the browser.
import { createSSRApp } from 'vue'

const app = createSSRApp({
  // ...same app as on server
})

// mounting an SSR app on the client assumes
// the HTML was pre-rendered and will perform
// hydration instead of mounting new DOM nodes.
app.mount('#app')

2.3 Cấu trúc mã

Lưu ý cách chúng ta cần phải sử dụng lại cùng một cấu trúc ứng dụng như trên máy chủ. Đây là nơi chúng ta cần bắt đầu suy nghĩ về cấu trúc mã trong một ứng dụng SSR – làm thế nào để chia sẻ cùng một mã ứng dụng giữa máy chủ và máy khách?
Ở đây, chúng tôi sẽ thực hiện một thiết lập cơ bản nhất. Trước hết, hãy chia nhỏ logic tạo ứng dụng thành một tệp riêng biệt, app.js:

// app.js (shared between server and client)
import { createSSRApp } from 'vue'

export function createApp() {
  return createSSRApp({
    data: () => ({ count: 1 }),
    template: `<button @click="count++">{{ count }}</button>`
  })
}

Tệp này và các phụ thuộc của nó được chia sẻ giữa máy chủ và máy khách – chúng tôi gọi chúng là mã đa năng. Có một số điều bạn cần chú ý khi viết mã đa năng, như chúng tôi sẽ thảo luận dưới đây.
Đoạn mã nhập của client sẽ nhập mã đa năng, tạo ứng dụng và thực hiện việc gắn:

// client.js
import { createApp } from './app.js'

createApp().mount('#app')

Và máy chủ sử dụng cùng một logic tạo ứng dụng trong trình xử lý yêu cầu:


// server.js (irrelevant code omitted)
import { createApp } from './app.js'

server.get('/', (req, res) => {
  const app = createApp()
  renderToString(app).then(html => {
    // ...
  })
})

Ngoài ra, để tải các tệp của client trong trình duyệt, chúng ta cũng cần:

  • Phục vụ các tệp khách hàng bằng cách thêm server.use(express.static(‘.’)) vào server.js.
  • Tải tệp nhập của khách hàng bằng cách thêm <script type=”module” src=”/client.js”></script> vào HTML shell.
  • Hỗ trợ việc sử dụng như import * from ‘vue’ trong trình duyệt bằng cách thêm một Import Map vào HTML shell.


Thử ví dụ hoàn chỉnh trên StackBlitz. Nút bây giờ đã tương tác!

3. Các Giải Pháp Cấp Cao Hơn

Di chuyển từ ví dụ đến một ứng dụng SSR sẵn sàng cho sản xuất liên quan đến nhiều hơn. Chúng ta sẽ cần:

  • Hỗ trợ Vue SFCs và các yêu cầu bước xây dựng khác. Trong thực tế, chúng ta sẽ cần phối hợp hai quá trình xây dựng cho cùng một ứng dụng: một cho client và một cho máy chủ.

tip Các thành phần Vue được biên dịch khác nhau khi được sử dụng cho SSR – các mẫu được biên dịch thành chuỗi nối thay vì các hàm render Virtual DOM để tăng hiệu suất render hiệu quả hơn.

  • Trong trình xử lý yêu cầu máy chủ, render HTML với các liên kết tài nguyên phía máy khách chính xác và gợi ý tài nguyên tối ưu. Chúng ta cũng có thể cần chuyển đổi giữa chế độ SSR và chế độ SSG, hoặc thậm chí kết hợp cả hai trong cùng một ứng dụng.
  • Quản lý định tuyến, lấy dữ liệu và các cửa hàng quản lý trạng thái một cách đa năng.
    Một việc triển khai hoàn chỉnh sẽ khá phức tạp và phụ thuộc vào bộ công cụ xây dựng mà bạn đã chọn để làm việc. Do đó, chúng tôi rất khuyến khích sử dụng một giải pháp cấp cao, mang tính chủ quan giải quyết các vấn đề phức tạp cho bạn. Dưới đây, chúng tôi sẽ giới thiệu một số giải pháp SSR được khuyến nghị trong hệ sinh thái Vue.

3.1 Nuxt

Nuxt là một framework cấp cao được xây dựng trên nền tảng của hệ sinh thái Vue, cung cấp trải nghiệm phát triển mượt mà cho việc viết ứng dụng Vue đa năng. Hơn nữa, bạn cũng có thể sử dụng nó như một trình tạo trang tĩnh! Chúng tôi rất khuyến khích bạn thử nghiệm.

3.2 Quasar

Quasar là một giải pháp hoàn chỉnh dựa trên Vue cho phép bạn nhắm mục tiêu đến SPA, SSR, PWA, ứng dụng di động, ứng dụng desktop và tiện ích trình duyệt chỉ bằng một mã nguồn. Nó không chỉ xử lý cài đặt xây dựng, mà còn cung cấp một bộ sưu tập đầy đủ các thành phần UI tuân theo thiết kế Material Design.

3.3 Vite SSR

Vite cung cấp tích hợp hỗ trợ cho việc render SSR của Vue, nhưng nó có ý thức là cấp độ thấp. Nếu bạn muốn tiếp tục với Vite, hãy kiểm tra vite-plugin-ssr, một plugin cộng đồng giải quyết nhiều chi tiết khó khăn cho bạn.

Bạn cũng có thể tìm thấy một dự án mẫu Vue + Vite SSR sử dụng cài đặt thủ công ở đây, có thể được sử dụng như một cơ sở để phát triển tiếp. Lưu ý rằng điều này chỉ được khuyến nghị nếu bạn đã có kinh nghiệm với SSR / các công cụ xây dựng và thực sự muốn có hoàn toàn kiểm soát về kiến ​​trúc cấp cao.

4. Viết Mã Thân Thiện với SSR

Bất kể cài đặt xây dựng hoặc lựa chọn framework cấp cao của bạn là gì, có một số nguyên tắc áp dụng cho tất cả các ứng dụng Vue SSR.

4.1 Tính Phản ứng trên Máy Chủ

Trong quá trình SSR, mỗi URL yêu cầu tương ứng với một trạng thái mong muốn của ứng dụng của chúng ta. Không có tương tác người dùng và không có cập nhật DOM, vì vậy tính phản ứng là không cần thiết trên máy chủ. Theo mặc định, tính phản ứng sẽ bị vô hiệu hóa trong quá trình SSR để tăng hiệu suất.

4.2 Hooks Lifecycle của Component

Vì không có cập nhật động, các hooks lifecycle như mountedonMounted hoặc updatedonUpdated KHÔNG được gọi trong quá trình SSR và chỉ được thực thi trên máy khách. Chỉ có các hooks được gọi trong quá trình SSR là beforeCreatecreated

4.3 Truy cập vào API Cụ thể cho Platform

Mã đa năng không thể cho rằng có quyền truy cập vào các API cụ thể cho nền tảng, vì vậy nếu mã của bạn trực tiếp sử dụng các biến toàn cục chỉ có trên trình duyệt như window hoặc document, chúng sẽ gây ra lỗi khi thực thi trong Node.js, và ngược lại.
Đối với các nhiệm vụ được chia sẻ giữa máy chủ và máy khách nhưng với các API nền tảng khác nhau, nên đề xuất bọc các triển khai cụ thể cho nền tảng bên trong một API đa năng, hoặc sử dụng thư viện làm điều này cho bạn. Ví dụ, bạn có thể sử dụng node-fetch để sử dụng cùng một API fetch trên cả máy chủ và máy khách.

Đối với các API chỉ có trên trình duyệt, cách tiếp cận phổ biến là truy cập chúng theo cách lười biếng bên trong các hooks lifecycle chỉ có trên máy khách như mountedonMounted.

Lưu ý rằng nếu một thư viện bên thứ ba không được viết với mục đích sử dụng đa nền tảng trong tâm trí, việc tích hợp nó vào một ứng dụng được render trên máy chủ có thể gặp khó khăn. Bạn có thể có thể làm cho nó hoạt động bằng cách giả mạo một số biến toàn cục, nhưng điều này sẽ là một phương pháp hacky và có thể gây xung đột với mã phát hiện môi trường của các thư viện khác.

4.4 Ô nhiễm Trạng thái qua Các Yêu cầu

Trong chương Quản lý Trạng thái, chúng tôi giới thiệu một mô hình quản lý trạng thái đơn giản sử dụng các API Phản ứng. Trong ngữ cảnh SSR, mô hình này yêu cầu một số điều chỉnh bổ sung.

Mô hình khai báo trạng thái chia sẻ trong phạm vi gốc của một mô-đun JavaScript. Điều này làm cho chúng trở thành đơn vị duy nhất – nghĩa là chỉ có một phiên bản của đối tượng phản ứng trong suốt vòng đời của ứng dụng của chúng ta. Điều này hoạt động như mong đợi trong một ứng dụng Vue chỉ có trên máy khách, vì các mô-đun trong ứng dụng của chúng ta được khởi tạo mới cho mỗi lần truy cập trang của trình duyệt.

Tuy nhiên, trong ngữ cảnh SSR, các mô-đun ứng dụng thường chỉ được khởi tạo một lần trên máy chủ, khi máy chủ khởi động. Các phiên bản mô-đun giống nhau sẽ được sử dụng lại qua nhiều yêu cầu máy chủ, và cũng như các đối tượng trạng thái đơn vị của chúng ta. Nếu chúng ta thay đổi trạng thái đơn vị chia sẻ với dữ liệu cụ thể cho một người dùng, nó có thể bị rò rỉ ngẫu nhiên sang một yêu cầu từ một người dùng khác. Chúng ta gọi điều này là ô nhiễm trạng thái qua các yêu cầu.

Lý thuyết, chúng ta có thể khởi tạo lại tất cả các mô-đun JavaScript trên mỗi yêu cầu, giống như chúng ta làm trong trình duyệt. Tuy nhiên, việc khởi tạo các mô-đun JavaScript có thể tốn kém, vì vậy điều này sẽ ảnh hưởng đáng kể đến hiệu suất máy chủ.

Giải pháp được khuyến nghị là tạo một phiên bản mới của toàn bộ ứng dụng – bao gồm cả bộ định tuyến và trạng thái toàn cầu – trên mỗi yêu cầu. Sau đó, thay vì nhập trực tiếp vào các thành phần của chúng ta, chúng ta cung cấp trạng thái chia sẻ bằng cách sử dụng cung cấp cấp ứng dụng và tiêm vào các thành phần cần nó:

// app.js (shared between server and client)
import { createSSRApp } from 'vue'
import { createStore } from './store.js'

// called on each request
export function createApp() {
  const app = createSSRApp(/* ... */)
  // create new instance of store per request
  const store = createStore(/* ... */)
  // provide store at the app level
  app.provide('store', store)
  // also expose store for hydration purposes
  return { app, store }
}

Các thư viện Quản lý Trạng thái như Pinia được thiết kế với điều này trong tâm trí. Tìm kiếm hướng dẫn SSR của Pinia để biết thêm chi tiết.

4.5 Sự không phù hợp khi Hydration

Nếu cấu trúc DOM của HTML được render trước không khớp với kết quả dự kiến của ứng dụng ở phía máy khách, sẽ xảy ra lỗi không phù hợp khi hydration. Sự không phù hợp khi hydration thường được gây ra bởi các nguyên nhân sau:
1. Template chứa cấu trúc lồng HTML không hợp lệ, và HTML được render đã bị “sửa” bởi hành vi phân tích HTML tự nhiên của trình duyệt. Ví dụ, một lỗi phổ biến là  <div> cannot be placed inside <p> :

<p><div>hi</div></p>

Nếu chúng ta tạo ra điều này trong HTML được phục vụ bởi máy chủ, trình duyệt sẽ chấm dứt thẻ <p> đầu tiên khi gặp phải <div> và phân tích nó thành cấu trúc DOM sau:

   <p></p>
   <div>hi</div>
   <p></p>

2. Dữ liệu được sử dụng trong quá trình render chứa các giá trị được tạo ngẫu nhiên. Vì cùng một ứng dụng sẽ chạy hai lần – một lần trên máy chủ và một lần trên máy khách – các giá trị ngẫu nhiên không được đảm bảo sẽ giống nhau giữa hai lần chạy này. Có hai cách để tránh sự không phù hợp do giá trị ngẫu nhiên gây ra:
2.1. Sử dụng v-if + onMounted để render phần phụ thuộc vào các giá trị ngẫu nhiên chỉ trên máy khách. Framework của bạn cũng có thể có các tính năng tích hợp để làm cho việc này dễ dàng hơn, ví dụ như thành phần trong VitePress.
2.2 Sử dụng một thư viện tạo số ngẫu nhiên hỗ trợ tạo với hạt giống và đảm bảo rằng chạy trên máy chủ và chạy trên máy khách đang sử dụng cùng một hạt giống (ví dụ: bằng cách bao gồm hạt giống trong trạng thái được serialize và lấy nó trên máy khách).

3.Máy chủ và máy khách ở các múi giờ khác nhau. Đôi khi, chúng ta có thể muốn chuyển đổi một dấu thời gian thành thời gian địa phương của người dùng. Tuy nhiên, múi giờ trong quá trình chạy trên máy chủ và múi giờ trong quá trình chạy trên máy khách không phải lúc nào cũng giống nhau, và chúng ta có thể không biết được múi giờ của người dùng một cách đáng tin cậy trong quá trình chạy trên máy chủ. Trong những trường hợp như vậy, việc chuyển đổi thời gian địa phương cũng nên được thực hiện như một hoạt động chỉ trên máy khách.

Khi Vue gặp sự không phù hợp khi hydration, nó sẽ cố gắng tự động phục hồi và điều chỉnh DOM được render trước để khớp với trạng thái ở phía máy khách. Điều này sẽ dẫn đến mất hiệu suất rendering do các nút không chính xác bị loại bỏ và các nút mới được mount, nhưng trong hầu hết các trường hợp, ứng dụng vẫn nên tiếp tục hoạt động như dự kiến. Tuy nhiên, vẫn tốt nhất là loại bỏ sự không phù hợp khi hydration trong quá trình phát triển.

4.6 Hướng dẫn Tùy chỉnh

Vì hầu hết các hướng dẫn tùy chỉnh liên quan đến việc thao tác DOM trực tiếp, chúng sẽ bị bỏ qua trong quá trình SSR. Tuy nhiên, nếu bạn muốn chỉ định cách một hướng dẫn tùy chỉnh sẽ được render (tức là những thuộc tính nào nó nên thêm vào phần tử được render), bạn có thể sử dụng hook getSSRProps:

const myDirective = {
  mounted(el, binding) {
    // client-side implementation:
    // directly update the DOM
    el.id = binding.value
  },
  getSSRProps(binding) {
    // server-side implementation:
    // return the props to be rendered.
    // getSSRProps only receives the directive binding.
    return {
      id: binding.value
    }
  }
}

4.7 Teleports

Teleports yêu cầu xử lý đặc biệt trong quá trình SSR. Nếu ứng dụng được render chứa Teleports, nội dung được teleport sẽ không phải là một phần của chuỗi được render. Một giải pháp dễ dàng hơn là điều kiện render Teleport khi mount.
Nếu bạn thực sự cần hydrate nội dung được teleport, chúng được hiển thị dưới thuộc tính teleports của đối tượng context SSR:

const ctx = {}
const html = await renderToString(app, ctx)

console.log(ctx.teleports) // { '#teleported': 'teleported content' }

Bạn cần inject markup của teleport vào vị trí đúng trong HTML trang cuối cùng của bạn tương tự như cách bạn cần inject markup của ứng dụng chính.

tip Tránh chỉ định body khi sử dụng Teleports và SSR cùng nhau – thường, sẽ chứa nội dung được render từ máy chủ khác, điều này làm cho Teleports không thể xác định vị trí bắt đầu đúng cho việc hydration.

Thay vào đó, ưu tiên sử dụng một container riêng, ví dụ như <div id=”teleported”></div>, chứa chỉ nội dung được teleport.

Trên Cafedev, chúng ta đã khám phá cách kết hợp Vuejs với Server-Side Rendering (SSR). Việc này không chỉ giúp tăng cường hiệu suất của ứng dụng mà còn cải thiện trải nghiệm người dùng và tối ưu hóa khả năng tìm kiếm trên web. Qua bài viết này, hy vọng bạn đã có cái nhìn tổng quan về cách thức hoạt động và lợi ích của SSR trong việc phát triển ứng dụng Vue. Hãy tiếp tục khám phá và áp dụng những kiến thức này vào dự án của bạn trên Cafedev!

Tham khảo thêm: MIỄN PHÍ 100% | Series tự học Vuejs từ cơ bản tới nâng cao

Các nguồn kiến thức MIỄN PHÍ VÔ GIÁ từ cafedev tại đây

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của CafeDev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!