Làm cách nào để cải thiện hiệu suất trên ứng dụng nuxt?

Mặc dù có rất nhiều lời khuyên rải rác trên internet về việc cải thiện tốc độ, hiệu suất và điểm số cho các ứng dụng Nuxt, nhưng tôi nghĩ mình sẽ tóm tắt một vài điều mà tôi thấy đặc biệt hữu ích trong một bài viết ngắn.

Lưu ý - mặc dù cá nhân tôi chỉ áp dụng các kỹ thuật này cho các ứng dụng Nuxt, nhưng chúng sẽ hoạt động với bất kỳ dự án SSR Vue nào

1] Lười hydrat hóa. Hóa ra hydrat hóa đắt một cách đáng ngạc nhiên. Lấy trang Kết xuất phía máy chủ của bạn và biến nó trở lại thành một DOM động trong trình duyệt mà Vue có quyền kiểm soát sẽ mất một chút công việc. Hơn nữa, thường có rất nhiều nội dung trong một trang web không cần phải cập nhật. Có thể có những yếu tố chỉ hiển thị và không thay đổi sau khi hiển thị hoặc những thứ chỉ cần được cung cấp nước nếu được nhấp vào hoặc cuộn vào xem

Tôi thấy rằng vue-lazy-hydrat hóa là cách tốt nhất để nhanh chóng cải thiện hiệu suất. Chỉ cần sử dụng thẻ

8 với một trong các tùy chọn sau

Mặc dù bạn không thể làm gì với việc dưỡng ẩm không có gì trên trang của mình [nếu không thì việc sử dụng Vue có ích lợi gì?], nhưng bạn có thể giảm 10/20% TTI của mình trong vòng vài phút

2] Tách/phân đoạn mã. Là một người mới sử dụng webpack, tôi đã nghe rất nhiều về điều này và nghĩ rằng nó nghe thật tuyệt, và thông điệp mà tôi thường nhận được là đó là điều gì đó ít nhiều xảy ra một cách tự động. Mặc dù điều này là đúng, nhưng bạn phải cấu trúc quá trình nhập của mình theo một cách nhất định để điều đó xảy ra

Đây là cách ban đầu tôi nhập các thành phần của mình

Tuy nhiên, sau đó tôi đã thay đổi quá trình nhập của mình sang định dạng này

Điều này dẫn đến việc webpack chunking Javascript của tôi tốt hơn nhiều, tạo ra nhiều gói nhỏ hơn và được tối ưu hóa hơn. Tôi không phải là chuyên gia về webpack, nhưng với thiết lập Nuxt mặc định, cách tiếp cận này mang lại kết quả tốt hơn

Nhưng làm thế nào để bạn kiểm tra kết quả?

3] Sử dụng webpack-bundle-analyser. Trình phân tích gói Webpack thật tuyệt vời. Nó làm cho nó cực kỳ dễ dàng để tìm ra những gì đang chiếm dung lượng. Đặt

9 trong phần xây dựng của
0 sẽ mở một tab trong trình duyệt của bạn khi bạn chạy
1, hiển thị cho bạn bằng hình ảnh nguyên nhân khiến bạn đau buồn là gì

Đương nhiên, có những thứ cần thiết cho ứng dụng của bạn. Tôi không thể tưởng tượng việc triển khai một ứng dụng mà không có Sentry, mặc dù nó chiếm ~20% gói

2 của tôi

Điều này dẫn tôi đến điểm cuối cùng của tôi [rant?]

4] Không sử dụng Vuetify. Nó sẽ fuck bạn lên. Trang bắt đầu nhanh mặc định của nó [về cơ bản không có bất kỳ nội dung nào] có điểm số rất cao. Nó có mức độ bao phủ và tối ưu hóa khủng khiếp – ngay cả khi đã bật A la carte, hơn 90% CSS bạn gửi tới trình duyệt vẫn chưa được sử dụng. Bất chấp sự phản đối kịch liệt từ người dùng về sự phình to của nó, không có gì được thực hiện, bất chấp những lời đề nghị trợ giúp, v.v.

Trong phần hôm nay của loạt bài Vue Performance, chúng ta sẽ tập trung vào framework thú vị nhất trong Vue. hệ sinh thái js - Nuxt. Cụ thể, chúng tôi sẽ tập trung vào cách cơ chế Kết xuất phía máy chủ [SSR] tác động đến hiệu suất và những gì chúng tôi có thể làm để tối ưu hóa cơ chế đó. Tất nhiên, tất cả các mẹo trước đây từ loạt bài này vẫn khả thi trong Nuxt

Cách kết xuất phía máy chủ hoạt động?

Để tìm hiểu cách tối ưu hóa SSR, điều quan trọng là phải hiểu cách nó hoạt động và nó khác với kết xuất phía máy khách như thế nào

Khi chúng tôi vào SPA [Ứng dụng một trang] được hiển thị phía máy khách, trước tiên chúng tôi thấy một màn hình trống với nội dung của

3 [thường chỉ là một

trong một cơ thể]. Sau đó, JavaScript bắt đầu thực thi và tạo giao diện người dùng một cách linh hoạt và dần dần. Chúng tôi có thể thấy nội dung trên màn hình của mình thay đổi như thế nào cho đến khi nội dung đó được tải đầy đủ

Đầu tiên chúng ta thường thấy phần đầu trang, chân trang và một số phần của nội dung trang. Số liệu mô tả thời gian cần thiết để các bit nội dung đầu tiên xuất hiện trên màn hình được gọi là First Contentful Paint - FCP. Các phần khác của giao diện người dùng sẽ xuất hiện cho đến khi ứng dụng hoàn thiện về mặt hình ảnh và đầy đủ chức năng. Số liệu đo lường thời gian cần thiết để ứng dụng trở nên tương tác hoàn toàn được gọi là Thời gian tương tác - TTI

lưu ý bên lề. Nếu bạn muốn tìm hiểu thêm về các số liệu đo lường hiệu suất web, hãy xem bài viết tuyệt vời này của Artem Denysov

Trong các ứng dụng được kết xuất phía máy chủ, chúng tôi không thấy tiến trình này. Đây là cách họ tải

  • Đầu tiên, mã JavaScript đang được thực thi trên máy chủ và Vue tạo tệp HTML tĩnh chứa toàn bộ đánh dấu ứng dụng của bạn
  • Tệp HTML tĩnh này được gửi tới trình duyệt. Số liệu mô tả thời gian cần thiết để người dùng nhận được nó được gọi là Thời gian đến byte đầu tiên [TTFB]
  • Sau khi tải xuống, người dùng gần như ngay lập tức nhìn thấy toàn bộ trang [nhưng nó chưa tương tác. ]
  • JavaScript đang được thực thi ở phía máy khách, chiếm quyền kiểm soát HTML tĩnh và làm cho nó tương tác. Quá trình này được gọi là
    4. Bạn có thể coi điều này giống như việc cung cấp HTML tĩnh [đã khử nước] với khả năng tương tác Vue [nước]
  • Ứng dụng ngậm nước trở nên tương tác [TTI]

Điều quan trọng cần đề cập là quá trình kết xuất phía máy chủ chỉ xảy ra khi chúng tôi truy cập trực tiếp vào trang web [hoặc làm mới trang web]. Sau khi ngậm nước, ứng dụng hoạt động giống như một SPA kết xuất phía máy khách bình thường

Chúng ta nên tập trung vào số liệu nào?

Biết cách hoạt động của Kết xuất phía máy chủ, chúng tôi có thể kết luận rằng có hai số liệu chính mà chúng tôi phải tối ưu hóa ứng dụng của mình để đạt được hiệu suất tuyệt vời trong lĩnh vực này

  • Thời gian đến Byte đầu tiên [TTFB] -. Nói cách khác, thời gian cho đến khi HTML tĩnh được hiển thị đến trình duyệt của người dùng. Điều quan trọng là giữ cho số liệu này ở mức thấp nhất có thể [lý tưởng là khoảng 1 giây trên mạng trung bình] bởi vì, ngược lại với các ứng dụng kết xuất phía máy khách được tải liên tục, người dùng sẽ không thấy bất kỳ thứ gì cho đến khi toàn bộ trang được tải xuống
  • Thời gian để tương tác [TTI] - Ngay cả khi trang kết xuất phía máy chủ của chúng tôi có thể được gửi nhanh chóng tới người dùng, điều quan trọng không kém là làm cho trang tương tác càng sớm càng tốt. Nếu không, người dùng của chúng tôi có thể cảm thấy thất vọng với các phần tử động không hoạt động như dự kiến

lưu ý bên lề. Xin lưu ý rằng ứng dụng của chúng tôi hoạt động giống như một SPA bình thường trong khi chúng tôi đang thực hiện điều hướng trong ứng dụng, vì vậy chúng tôi vẫn phải quan tâm đến kích thước gói của các nội dung khác và hiệu suất thời gian chạy

Tối ưu hóa thời gian cho byte đầu tiên

Chúng tôi có thể chia tổng thời gian cho Byte đầu tiên thành 2 giai đoạn

  • Giai đoạn thực thi khi mã phía máy chủ đang được thực thi và tệp HTML tĩnh được tạo
  • Giai đoạn "Tải xuống" trong khi tệp HTML được tạo đang được tải xuống trình duyệt của người dùng

Chúng ta đã biết cách tối ưu hóa giai đoạn thực thi từ các bài viết trước. Hầu hết các kỹ thuật tối ưu hóa phía máy khách đã biết sẽ ảnh hưởng tích cực đến số liệu này

Phần khó khăn là giai đoạn tải xuống. Nó hoàn toàn tương quan với kích thước của tệp HTML được xuất ra và điều này có thể dễ dàng vượt khỏi tầm kiểm soát của chúng tôi. Để hiểu tại sao, chúng ta phải tìm hiểu cách Nuxt truyền tải dữ liệu được tìm nạp ở phía máy chủ sang phía máy khách và cách nó ảnh hưởng đến kích thước của HTML được tạo phía máy chủ

Truyền tải dữ liệu phía máy chủ

Tôi đã viết rằng cùng một mã được thực thi ở phía máy chủ và máy khách. Nó ngụ ý rằng tất cả các cuộc gọi không đồng bộ cũng được thực hiện ở cả hai phía nhưng điều này không hoàn toàn đúng. Nếu chúng ta viết mã nguyên trạng thì đây là điều sẽ xảy ra nhưng đó sẽ là một sự lãng phí rất lớn về thời gian và băng thông. Nếu chúng tôi đã tìm nạp dữ liệu ở phía máy chủ để tạo HTML tĩnh thì mục đích của việc thực hiện lại điều này ở phía máy khách là gì?

Nhóm cốt lõi của Nuxt nhận thức rất rõ về vấn đề đó và đây là lý do tại sao họ giới thiệu

5 và
6 được sử dụng để truyền dữ liệu phía máy chủ sang phía máy khách

Hãy xem ví dụ này từ tài liệu Nuxt


  

Blog posts

Fetching posts...

Error while fetching posts: {{ $fetchState.error.message }}

  • {{ post.title }}

Khi bạn vào trang trực tiếp từ URL [vì vậy chúng tôi sử dụng SSR], bạn sẽ không thấy yêu cầu bổ sung đối với

0 trong tab mạng của mình. Điều này là do mọi thứ đã được tìm nạp trong
5 trên máy chủ đều có sẵn ở phía máy khách mà không cần thêm lệnh gọi mạng

Được rồi, chúng tôi biết điều gì xảy ra nhưng chúng tôi không biết nó xảy ra NHƯ THẾ NÀO. Dữ liệu này không xuất hiện một cách kỳ diệu trên máy khách. Phải có một cách để truyền đạt nó

Thứ duy nhất mà chúng tôi nhận được từ máy chủ là tệp

3 khổng lồ này nên dữ liệu phải ở đó. Nếu bạn kiểm tra nguồn của tệp này, bạn sẽ nhận thấy một
3

Mặc dù công cụ mạnh mẽ này có thể giúp chúng tôi tiết kiệm thời gian tìm nạp nội dung ở phía máy khách nhưng nó cũng có thể làm tăng đáng kể kích thước của

3. Càng nhiều dữ liệu chúng tôi quyết định truyền tải thì dữ liệu càng lớn và người dùng sẽ phải đợi lâu hơn để xem bất kỳ nội dung nào. Đây là lý do tại sao chúng tôi phải rất cẩn thận với dữ liệu mà chúng tôi đang gửi cho phía khách hàng

Thực sự có một điều chúng ta có thể làm để tránh các vấn đề về hiệu suất trong lĩnh vực đó - không gửi dữ liệu mà chúng ta không cần phải gửi. Nghe có vẻ hiển nhiên nhưng chính xác thì đó là loại dữ liệu nào?

Tôi muốn nói rằng mọi thứ chúng tôi cần để hiển thị các phần quan trọng về SEO trên trang web của chúng tôi, chẳng hạn như điều hướng hoặc nội dung trang chính phải luôn được chuyển đến phía trước

Chúng tôi không phải truyền tải nội dung không quan trọng đối với trình thu thập dữ liệu như dữ liệu chỉ dành cho người dùng đã đăng nhập hoặc bất kỳ nội dung được cá nhân hóa nào khác [như giỏ hàng] và nội dung thanh bên bật lên/ngoài màn hình

Ngoài ra, chúng ta nên làm cho các đối tượng phải gửi đến máy khách càng nhỏ càng tốt

  • Nếu bạn đang sử dụng GraphQL, bạn phải luôn giới hạn các trường trong truy vấn ở những trường thực sự được sử dụng
  • Nếu bạn không sử dụng GraphQL, hãy thử giới hạn các trường bạn đang gửi ở những trường cần thiết bằng cách xóa chúng khỏi đối tượng mà bạn đang lưu vào trạng thái thành phần. Ví dụ: trong đoạn mã dưới đây, chúng tôi chỉ cần các thuộc tính
    5 và
    6 từ
    7 để chúng tôi có thể loại bỏ các thuộc tính khác

Bây giờ khi chúng tôi biết cách tối ưu hóa TTI, hãy xem chúng tôi có thể làm gì để giúp ứng dụng của chúng tôi tương tác nhanh hơn

Lưu ý bên quan trọng. Xin lưu ý rằng việc giới hạn dữ liệu được truyền tải cũng là một sự đánh đổi. Bạn đang có hiệu suất tốt hơn nhưng nếu quá trình thực thi JS không thành công [và do đó bị hydrat hóa], ứng dụng của bạn có thể không sử dụng được nếu thiếu một số dữ liệu quan trọng. Nếu bạn muốn làm cho ứng dụng của mình hoạt động ngay cả khi JavaScript bị lỗi, bạn phải đảm bảo rằng bạn đang truyền tải mọi thứ cần thiết để người dùng điều hướng. Bạn cũng phải loại bỏ các phần tử giao diện người dùng động như thanh bên ngoài màn hình và cửa sổ bật lên vì chúng sẽ không hoạt động nếu không có JavaScript

Tối ưu hóa thời gian để tương tác

Tổng số lượng mã JS trong ứng dụng của chúng tôi và số lượng thành phần phải được cung cấp nước là hai yếu tố chính ảnh hưởng đến chỉ số Thời gian tương tác. Chúng ta đã biết các kỹ thuật tách mã hiệu quả từ các phần trước của loạt bài này có thể giảm thiểu lượng JavaScript trong đường dẫn quan trọng nhưng chúng ta có thể làm gì để giảm thiểu lượng thành phần ngậm nước không?

May mắn thay, nhờ có thư viện

8 tuyệt vời do Markus Oberlehner tạo ra, chúng tôi có thể làm được rất nhiều việc

Như chúng ta có thể đọc trong thư viện README

"

8 là một Vue không kết xuất. js để cải thiện Độ trễ đầu vào ước tính và Thời gian tương tác của Vue được hiển thị phía máy chủ. ứng dụng js. ”

Chính xác những gì chúng tôi đang tìm kiếm. README cung cấp cho chúng tôi một ví dụ cho thấy những kết quả mà chúng tôi có thể mong đợi

Đây là kết quả của dự án thử nghiệm mà không cần hydrat hóa lười biếng

Và những thứ này - với việc hydrat hóa lười biếng được áp dụng

Như chúng ta có thể thấy TTI trong ví dụ trên nhỏ hơn 25% với

    npm install vue-lazy-hydration --save
0 [tất nhiên kết quả của bạn có thể hoàn toàn khác]. Bạn sẽ thấy trong một phút rằng thư viện này cực kỳ dễ sử dụng, điều này khiến nó trở thành một công cụ tuyệt vời để đạt được những cải tiến hiệu suất nhanh chóng và đáng kể

Để cài đặt thư viện, chỉ cần thêm nó thông qua sổ đăng ký npm/sợi vào dự án của bạn

    npm install vue-lazy-hydration --save

Bây giờ chúng ta sẽ có quyền truy cập vào thành phần

    npm install vue-lazy-hydration --save
1 mà chúng ta có thể sử dụng để bọc các thành phần khác và trì hoãn quá trình hydrat hóa của chúng

Ví dụ: đây là cách chúng tôi có thể trì hoãn quá trình hydrat hóa thành phần cho đến khi nó hiển thị trên màn hình

2

TIỀN BOA. Thư viện cũng cho phép bạn hydrat hóa các thành phần trong các điều kiện khác [như

    npm install vue-lazy-hydration --save
2]. Bạn có thể kiểm tra các tùy chọn có sẵn trong README

Và đó là nó. Cách sử dụng thư viện này rất đơn giản. Bây giờ hãy xem khi nào chúng ta có thể sử dụng nó

Chúng ta có thể chia các thành phần của mình thành ba nhóm

Các thành phần phải được hydrat hóa ngay lập tức

Thông thường, đây là những thành phần hiển thị ngay trên màn hình [còn gọi là trong màn hình đầu tiên]. Chúng ta không thể làm gì nhiều về chúng. Họ chỉ cần được ngậm nước

Các thành phần có thể được hydrat hóa sau

Trong hầu hết các trường hợp, đây là các thành phần ngoài màn hình hoặc dưới màn hình đầu tiên

Hydrat hóa chúng khi chúng trở nên rõ ràng trong hầu hết các trường hợp là chiến lược đúng đắn để lựa chọn

4

Các thành phần hoàn toàn không cần phải ngậm nước

Đúng. Có những thành phần như vậy. Chúng tôi thường có các thành phần chỉ hiển thị một số văn bản nhưng không tương tác theo bất kỳ cách nào. Các thành phần như vậy, một khi được kết xuất trên máy chủ có thể ở trạng thái tĩnh và hoàn toàn không cần phải ngậm nước

Chúng ta có thể đạt được điều đó với

    npm install vue-lazy-hydration --save
3 prop trên thành phần
    npm install vue-lazy-hydration --save
1

4

Tóm lược

Tối ưu hóa hiệu suất Nuxt không khác nhiều so với tối ưu hóa bất kỳ ứng dụng Vuejs nào khác. Phần phía máy khách đang hoạt động như một ứng dụng Vue thông thường nhưng trong lần truy cập đầu tiên, trang đang được hiển thị ở phía máy chủ, do đó người dùng sẽ thấy một màn hình trống cho đến khi ứng dụng được tải. Đây là lý do tại sao điều quan trọng là cung cấp nội dung ban đầu này càng sớm càng tốt. Nếu chúng ta biết các lĩnh vực có khả năng xảy ra tắc nghẽn hiệu suất thì đó sẽ là một miếng bánh

Cái nào tốt hơn js tiếp theo hoặc NuxtJS?

Tiếp theo. js được phân loại là full-stack framework vì nó cũng hỗ trợ các chức năng back-end. Mặt khác, Nuxt. js được phân loại là khung giao diện người dùng .

Nuxt có nhanh hơn Vue không?

Nuxt cung cấp cải thiện SEO tốt hơn với tính năng hiển thị phía máy chủ, phát triển nhanh hơn với bộ định tuyến chung tự động, tính năng chia sẻ công khai và quản lý với các tùy chọn cấu hình và phương pháp thẻ meta tuyệt vời, phân tách mã tự động với các trang được kết xuất trước — tất cả điều này là

Quá trình sản xuất Nuxt 3 đã sẵn sàng chưa?

Nux 3. 0. 0 đi kèm với một API sẵn sàng sản xuất ổn định, và hơn 50 mô-đun được hỗ trợ được cộng đồng và nhóm Nuxt xây dựng bằng cách sử dụng Bộ công cụ Nuxt.

Tại sao Nuxt tốt cho SEO?

Nuxt cho phép bạn xác định tất cả các thẻ config. js sử dụng thuộc tính head . Điều này rất hữu ích để thêm tiêu đề và thẻ mô tả mặc định cho mục đích SEO hoặc để đặt chế độ xem hoặc thêm biểu tượng yêu thích.

Chủ Đề