Bài viết này nhận được sự hỗ trợ nhiệt tình của những người bạn thân mến của chúng tôi tại Netlify, một nhóm gồm những tài năng đáng kinh ngạc đến từ khắp nơi trên thế giới và cung cấp nền tảng cho các nhà phát triển web giúp tăng năng suất. Cảm ơn bạn!

Một trong những nỗi đau lớn nhất khi làm việc với các trang web được tạo tĩnh là quá trình xây dựng chậm dần theo thời gian khi ứng dụng của bạn phát triển. Đây là vấn đề không thể tránh khỏi mà bất kỳ ngăn xếp nào cũng phải đối mặt tại một thời điểm nào đó và nó có thể xuất hiện từ nhiều điểm khác nhau tùy thuộc vào loại sản phẩm bạn đang làm việc.
Ví dụ: nếu ứng dụng của bạn có nhiều trang (lượt xem, tuyến đường) khi tạo hiện vật triển khai, thì mỗi tuyến đường đó sẽ trở thành một tệp. Sau đó, khi bạn đã đạt đến hàng nghìn, bạn bắt đầu tự hỏi khi nào bạn có thể triển khai mà không cần phải lập kế hoạch trước. Kịch bản này thường gặp trên các nền tảng thương mại điện tử hoặc blog, vốn đã chiếm một phần lớn trên web nhưng không phải là tất cả. Tuy nhiên, các tuyến đường không phải là nút thắt cổ chai duy nhất có thể xảy ra.
Một ứng dụng nặng về tài nguyên cuối cùng cũng sẽ đạt đến bước ngoặt này. Nhiều trình tạo tĩnh thực hiện tối ưu hóa tài sản để đảm bảo trải nghiệm người dùng tốt nhất. Nếu không có tối ưu hóa bản dựng (bản dựng gia tăng, lưu trữ đệm, chúng ta sẽ sớm tìm hiểu về những điều này), điều này cuối cùng cũng sẽ trở nên không thể quản lý được — hãy nghĩ đến việc xem qua tất cả các hình ảnh trong một trang web: thay đổi kích thước, xóa và/hoặc tạo các tệp mới nhiều lần. Và sau khi tất cả những điều đó được thực hiện: hãy nhớ rằng Jamstack phục vụ các ứng dụng của chúng ta từ các cạnh của Mạng phân phối nội dung. Vì vậy, chúng ta vẫn cần di chuyển các thứ từ máy chủ nơi chúng được biên dịch đến các rìa của mạng.

Ngoài ra, còn có một thực tế khác: dữ liệu thường động, nghĩa là khi chúng ta xây dựng ứng dụng và triển khai, có thể mất vài giây, vài phút hoặc thậm chí là một giờ. Trong khi đó, thế giới vẫn tiếp tục quay và nếu chúng ta lấy dữ liệu từ nơi khác, ứng dụng của chúng ta chắc chắn sẽ trở nên lỗi thời. Không thể chấp nhận được! Xây dựng lại để cập nhật!
Tuy nhiên, việc xác định thuật toán khác biệt không phải là nhiệm vụ dễ dàng. Để người dùng cuối thực sự được hưởng lợi từ cải tiến này, cần phải cân nhắc các chiến lược vô hiệu hóa bộ đệm. Tóm lại: chúng ta không muốn vô hiệu hóa bộ đệm cho một trang hoặc một tài sản không thay đổi.
Next.js đã đưa ra Tái tạo tĩnh gia tăng (ISR). Về bản chất, đây là một cách để khai báo cho mỗi tuyến đường tần suất chúng ta muốn xây dựng lại. Bên trong, nó đơn giản hóa rất nhiều công việc cho phía máy chủ. Bởi vì mọi tuyến đường (động hay không) sẽ tự xây dựng lại theo một khung thời gian cụ thể và nó hoàn toàn phù hợp với tiên đề Jamstack về việc vô hiệu hóa bộ nhớ đệm trên mọi bản dựng. Hãy nghĩ về nó như tiêu đề
Để bắt đầu ứng dụng của bạn, ISR chỉ là một thuộc tính cấu hình. Trên thành phần tuyến đường của bạn (bên trong thư mục
Đoạn mã trên sẽ đảm bảo trang của tôi được xây dựng lại sau mỗi giờ và tìm kiếm thêm Pokémon để hiển thị.
Chúng tôi vẫn nhận được bản dựng hàng loạt thỉnh thoảng (khi phát hành một triển khai mới). Nhưng điều này cho phép chúng tôi tách nội dung khỏi mã, bằng cách di chuyển nội dung đến Hệ thống quản lý nội dung (CMS), chúng tôi có thể cập nhật thông tin trong vài giây, bất kể ứng dụng của chúng tôi lớn đến mức nào. Tạm biệt webhooks để cập nhật lỗi đánh máy!
Sau khi hoàn tất, nó cũng giống như việc tạo một Hàm Netlify mới. Nếu bạn chưa thiết lập thư mục cụ thể cho chúng, hãy truy cập
Như bạn có thể thấy từ đoạn trích ở trên, trình xây dựng theo yêu cầu tách biệt khỏi Hàm Netlify thông thường vì nó bao bọc trình xử lý của mình bên trong phương thức
Netlify sẽ hỗ trợ bạn. Chỉ trong vài bước, chúng ta có thể tận dụng toàn bộ sức mạnh của Jamstack trong ứng dụng Next.js của mình. Đã đến lúc xắn tay áo lên và bắt tay vào thực hiện ngay bây giờ.
Trước On-Demand Builders,
Chúng tôi đang thu thập danh sách tất cả các trang pokémon mà chúng tôi dự định có, ánh xạ tất cả các đối tượng
Bạn có thể kiểm tra cả hai phiên bản được triển khai trên Netlify:
Mã này cũng mã nguồn mở trên Github và bạn có thể dễ dàng tự triển khai để kiểm tra thời gian dựng. Và với hàng đợi này, chúng ta sẽ chuyển sang chủ đề tiếp theo.
Vì mục đích tái tạo, tôi đã giới hạn yêu cầu của chúng tôi (ở mức
Sau đó, chạy cả hai phiên bản trong các nhánh riêng biệt tới Netlify, nhờ triển khai bản xem trước, chúng có thể cùng tồn tại trong cùng một môi trường. Để thực sự đánh giá sự khác biệt giữa cả hai phương pháp, cách tiếp cận ODB là cực đoan, không có trang nào được kết xuất trước cho tuyến đường động đó. Mặc dù không được khuyến nghị cho các tình huống thực tế (bạn sẽ muốn kết xuất trước các tuyến đường có lưu lượng truy cập cao), nhưng nó đánh dấu rõ ràng phạm vi cải thiện hiệu suất thời gian xây dựng mà chúng ta có thể đạt được bằng phương pháp này.
Các trang trong Ứng dụng PokéDex khá nhỏ, tài sản hình ảnh rất gọn nhẹ, nhưng lợi ích về thời gian triển khai rất đáng kể. Nếu một ứng dụng có số lượng tuyến đường từ trung bình đến lớn, thì chắc chắn nên cân nhắc chiến lược ODB.
Nó giúp triển khai nhanh hơn và do đó đáng tin cậy hơn. Hiệu suất chỉ giảm ở yêu cầu đầu tiên, từ yêu cầu tiếp theo trở đi, trang được kết xuất sẽ được lưu vào bộ nhớ đệm ngay trên Edge, giúp hiệu suất giống hệt như Fully Static Generated.
DPR là bước tiếp theo dành cho On-Demand Builders. Nó tận dụng các bản dựng nhanh hơn bằng cách sử dụng các bước xây dựng không đồng bộ như vậy và sau đó lưu trữ đệm các tài sản cho đến khi chúng thực sự được cập nhật. Không còn bản dựng đầy đủ cho trang web có 10.000 trang nữa. DPR trao quyền cho các nhà phát triển để kiểm soát hoàn toàn các hệ thống xây dựng và triển khai thông qua bộ nhớ đệm vững chắc và sử dụng On-Demand Builders.
Hãy hình dung tình huống này: một trang web thương mại điện tử có 10.000 trang sản phẩm, điều này có nghĩa là sẽ mất khoảng 2 giờ để xây dựng toàn bộ ứng dụng để triển khai. Chúng ta không cần phải tranh luận về việc này đau đớn như thế nào.
Với DPR, chúng ta có thể thiết lập 500 trang hàng đầu để xây dựng trên mỗi lần triển khai. Các trang có lưu lượng truy cập lớn nhất của chúng tôi luôn sẵn sàng cho người dùng của chúng tôi. Nhưng chúng tôi là một cửa hàng, tức là mỗi giây đều có giá trị. Vì vậy, đối với 9500 trang còn lại, chúng ta có thể thiết lập một móc sau khi dựng để kích hoạt trình dựng của chúng — triển khai phần còn lại của các trang của chúng ta theo cách không đồng bộ và lưu vào bộ nhớ đệm ngay lập tức. Không có người dùng nào bị ảnh hưởng, trang web của chúng ta đã được cập nhật với bản dựng nhanh nhất có thể và mọi thứ khác không tồn tại trong bộ nhớ đệm sau đó đã được lưu trữ.
Bạn nghĩ gì về Distributed Persistent Rendering? Bạn đã thử On-Demand Builders trong ứng dụng của mình chưa? Hãy cho tôi biết thêm trong phần bình luận hoặc gọi cho tôi trên Twitter. Tôi thực sự tò mò!
Một trong những nỗi đau lớn nhất khi làm việc với các trang web được tạo tĩnh là quá trình xây dựng chậm dần theo thời gian khi ứng dụng của bạn phát triển. Đây là vấn đề không thể tránh khỏi mà bất kỳ ngăn xếp nào cũng phải đối mặt tại một thời điểm nào đó và nó có thể xuất hiện từ nhiều điểm khác nhau tùy thuộc vào loại sản phẩm bạn đang làm việc.
Ví dụ: nếu ứng dụng của bạn có nhiều trang (lượt xem, tuyến đường) khi tạo hiện vật triển khai, thì mỗi tuyến đường đó sẽ trở thành một tệp. Sau đó, khi bạn đã đạt đến hàng nghìn, bạn bắt đầu tự hỏi khi nào bạn có thể triển khai mà không cần phải lập kế hoạch trước. Kịch bản này thường gặp trên các nền tảng thương mại điện tử hoặc blog, vốn đã chiếm một phần lớn trên web nhưng không phải là tất cả. Tuy nhiên, các tuyến đường không phải là nút thắt cổ chai duy nhất có thể xảy ra.
Một ứng dụng nặng về tài nguyên cuối cùng cũng sẽ đạt đến bước ngoặt này. Nhiều trình tạo tĩnh thực hiện tối ưu hóa tài sản để đảm bảo trải nghiệm người dùng tốt nhất. Nếu không có tối ưu hóa bản dựng (bản dựng gia tăng, lưu trữ đệm, chúng ta sẽ sớm tìm hiểu về những điều này), điều này cuối cùng cũng sẽ trở nên không thể quản lý được — hãy nghĩ đến việc xem qua tất cả các hình ảnh trong một trang web: thay đổi kích thước, xóa và/hoặc tạo các tệp mới nhiều lần. Và sau khi tất cả những điều đó được thực hiện: hãy nhớ rằng Jamstack phục vụ các ứng dụng của chúng ta từ các cạnh của Mạng phân phối nội dung. Vì vậy, chúng ta vẫn cần di chuyển các thứ từ máy chủ nơi chúng được biên dịch đến các rìa của mạng.

Ngoài ra, còn có một thực tế khác: dữ liệu thường động, nghĩa là khi chúng ta xây dựng ứng dụng và triển khai, có thể mất vài giây, vài phút hoặc thậm chí là một giờ. Trong khi đó, thế giới vẫn tiếp tục quay và nếu chúng ta lấy dữ liệu từ nơi khác, ứng dụng của chúng ta chắc chắn sẽ trở nên lỗi thời. Không thể chấp nhận được! Xây dựng lại để cập nhật!
Xây dựng một lần, cập nhật khi cần
Giải quyết Bản dựng cồng kềnh luôn là ưu tiên hàng đầu đối với hầu hết mọi nền tảng, khuôn khổ hoặc dịch vụ Jamstack trong một thời gian. Nhiều giải pháp xoay quanh các bản dựng gia tăng. Trên thực tế, điều này có nghĩa là các bản dựng sẽ cồng kềnh như những khác biệt mà chúng mang lại so với triển khai hiện tại.Tuy nhiên, việc xác định thuật toán khác biệt không phải là nhiệm vụ dễ dàng. Để người dùng cuối thực sự được hưởng lợi từ cải tiến này, cần phải cân nhắc các chiến lược vô hiệu hóa bộ đệm. Tóm lại: chúng ta không muốn vô hiệu hóa bộ đệm cho một trang hoặc một tài sản không thay đổi.
Next.js đã đưa ra Tái tạo tĩnh gia tăng (ISR). Về bản chất, đây là một cách để khai báo cho mỗi tuyến đường tần suất chúng ta muốn xây dựng lại. Bên trong, nó đơn giản hóa rất nhiều công việc cho phía máy chủ. Bởi vì mọi tuyến đường (động hay không) sẽ tự xây dựng lại theo một khung thời gian cụ thể và nó hoàn toàn phù hợp với tiên đề Jamstack về việc vô hiệu hóa bộ nhớ đệm trên mọi bản dựng. Hãy nghĩ về nó như tiêu đề
max-age
nhưng dành cho các tuyến đường trong ứng dụng Next.js của bạn.Để bắt đầu ứng dụng của bạn, ISR chỉ là một thuộc tính cấu hình. Trên thành phần tuyến đường của bạn (bên trong thư mục
/pages
), hãy chuyển đến phương thức getStaticProps
và thêm khóa revalidate
vào đối tượng trả về:
Mã:
export async function getStaticProps() { const { limit, count, pokemons } = await fetchPokemonList() return { props: { limit, count, pokemons, }, revalidate: 3600 // seconds }}
Chúng tôi vẫn nhận được bản dựng hàng loạt thỉnh thoảng (khi phát hành một triển khai mới). Nhưng điều này cho phép chúng tôi tách nội dung khỏi mã, bằng cách di chuyển nội dung đến Hệ thống quản lý nội dung (CMS), chúng tôi có thể cập nhật thông tin trong vài giây, bất kể ứng dụng của chúng tôi lớn đến mức nào. Tạm biệt webhooks để cập nhật lỗi đánh máy!
Trình xây dựng theo yêu cầu
Netlify gần đây đã ra mắt On-Demand Builders, đây là cách tiếp cận của họ để hỗ trợ ISR cho Next.js, nhưng cũng hoạt động trên các khuôn khổ bao gồm Eleventy và Nuxt. Trong phiên trước, chúng tôi đã xác định rằng ISR là một bước tiến lớn hướng tới thời gian xây dựng ngắn hơn và giải quyết một phần đáng kể các trường hợp sử dụng. Tuy nhiên, vẫn có những cảnh báo:- Xây dựng đầy đủ khi triển khai liên tục.
Giai đoạn gia tăng chỉ xảy ra sau khi triển khai và đối với dữ liệu. Không thể vận chuyển mã theo từng bước - Xây dựng gia tăng là sản phẩm của thời gian.
Bộ nhớ đệm bị vô hiệu hóa theo thời gian. Vì vậy, các bản dựng không cần thiết có thể xảy ra hoặc các bản cập nhật cần thiết có thể mất nhiều thời gian hơn tùy thuộc vào thời gian xác thực lại được đặt trong mã.
- Quan trọng
Không cần thực hiện hành động nào. Mọi thứ bạn triển khai sẽ được xây dựng khi push. - Hoãn
Một phần cụ thể của ứng dụng sẽ không được xây dựng khi triển khai, nó sẽ được hoãn lại để được xây dựng theo yêu cầu bất cứ khi nào yêu cầu đầu tiên xảy ra, sau đó nó sẽ được lưu vào bộ nhớ đệm như bất kỳ tài nguyên nào khác cùng loại.
Tạo trình xây dựng theo yêu cầu
Trước hết, hãy thêm một gói netlify/functions dưới dạngdevDependency
vào dự án của bạn:
Mã:
yarn add -D @netlify/functions
netlify/functions/
và tạo một tệp có tên bất kỳ cho trình xây dựng của bạn.
Mã:
import type { Handler } from '@netlify/functions'import { builder } from '@netlify/functions'const myHandler: Handler = async (event, context) => { return { statusCode: 200, body: JSON.stringify({ message: 'Built on-demand! 🎉' }), }}export const handler = builder(myHandler)
builder()
. Phương thức này kết nối hàm của chúng ta với các tác vụ xây dựng. Và đó là tất cả những gì bạn cần để có một phần ứng dụng của mình được hoãn lại để chỉ xây dựng khi cần thiết. Bản dựng gia tăng nhỏ ngay từ đầu!Next.js trên Netlify
Để xây dựng ứng dụng Next.js trên Netlify, có 2 plugin quan trọng mà người dùng nên thêm vào để có trải nghiệm tốt hơn nói chung: Netlify Plugin Cache Next.js và Next-on-Netlify thiết yếu. Cái trước lưu trữ NextJS của bạn hiệu quả hơn và bạn cần tự thêm nó, trong khi cái sau thực hiện một vài điều chỉnh nhỏ về cách xây dựng kiến trúc Next.js để nó phù hợp hơn với Netlify và có sẵn theo mặc định cho mọi dự án mới mà Netlify có thể xác định là đang sử dụng Next.js.Trình xây dựng theo yêu cầu với Next.js
Xây dựng hiệu suất, triển khai hiệu suất, lưu trữ đệm, trải nghiệm của nhà phát triển. Đây đều là những chủ đề rất quan trọng, nhưng rất nhiều — và mất thời gian để thiết lập đúng cách. Sau đó, chúng ta sẽ đến với cuộc thảo luận cũ về việc tập trung vào Trải nghiệm của nhà phát triển thay vì Trải nghiệm của người dùng. Đó là lúc mọi thứ được chuyển đến một vị trí ẩn trong danh sách tồn đọng để bị lãng quên. Không thực sự.Netlify sẽ hỗ trợ bạn. Chỉ trong vài bước, chúng ta có thể tận dụng toàn bộ sức mạnh của Jamstack trong ứng dụng Next.js của mình. Đã đến lúc xắn tay áo lên và bắt tay vào thực hiện ngay bây giờ.
Định nghĩa Đường dẫn được kết xuất trước
Nếu bạn đã từng làm việc với thế hệ tĩnh bên trong Next.js trước đây, có lẽ bạn đã nghe nói đến phương thứcgetStaticPaths
. Phương thức này dành cho các tuyến động (các mẫu trang sẽ kết xuất nhiều trang).Không đi sâu vào sự phức tạp của phương pháp này, điều quan trọng cần lưu ý là kiểu trả về là một đối tượng có 2 khóa, giống như trong Proof-of-Concept của chúng tôi, đây sẽ là tệp [Pokémon]dynamic route:
Mã:
export async function getStaticPaths() { return { paths: [], fallback: 'blocking', }}
-
paths
là mộtmảng
thực hiện tất cả đường dẫn khớp với tuyến đường này sẽ được kết xuất trước -
fallback
có 3 giá trị có thể: chặn,đúng
hoặcsai
getStaticPaths
của chúng tôi đang xác định:- Không có đường dẫn nào được kết xuất trước;
- Bất cứ khi nào tuyến đường này được gọi, chúng tôi sẽ không phục vụ mẫu dự phòng, chúng tôi sẽ kết xuất trang theo yêu cầu và giữ người dùng chờ, chặn ứng dụng thực hiện bất kỳ thao tác nào khác.
Trước On-Demand Builders,
getStaticPaths
của chúng tôi hơi khác một chút:
Mã:
export async function getStaticPaths() { const { pokemons } = await fetchPkmList() return { paths: pokemons.map(({ name }) => ({ params: { pokemon: name } })), fallback: false, }}
pokemon
thành một chuỗi
chỉ với tên pokémon và chuyển tiếp trả về đối tượng { params }
mang nó đến getStaticProps
. fallback
của chúng tôi được đặt thành false
vì nếu một tuyến đường không khớp, chúng tôi muốn Next.js trả về trang 404: Không tìm thấy
.Bạn có thể kiểm tra cả hai phiên bản được triển khai trên Netlify:
Mã này cũng mã nguồn mở trên Github và bạn có thể dễ dàng tự triển khai để kiểm tra thời gian dựng. Và với hàng đợi này, chúng ta sẽ chuyển sang chủ đề tiếp theo.
Thời gian xây dựng
Như đã đề cập ở trên, bản demo trước thực chất là Bằng chứng về khái niệm, không có gì thực sự tốt hay xấu nếu chúng ta không thể đo lường. Đối với nghiên cứu nhỏ của mình, tôi đã chuyển sang PokéAPI và quyết định bắt tất cả các pokémon.Vì mục đích tái tạo, tôi đã giới hạn yêu cầu của chúng tôi (ở mức
1000
). Chúng không thực sự là tất cả trong API, nhưng nó thực thi số lượng trang sẽ giống nhau cho tất cả các bản dựng bất kể mọi thứ có được cập nhật tại bất kỳ thời điểm nào hay không.
Mã:
export const fetchPkmList = async () => { const resp = await fetch(`${API}pokemon?limit=${LIMIT}`) const { count, results, }: { count: number results: { name: string url: string }[] } = await resp.json() return { count, pokemons: results, limit: LIMIT, }}
Chiến lược | Số trang | Số lượng tài sản | Thời gian xây dựng | Tổng thời gian triển khai |
---|---|---|---|---|
Được tạo hoàn toàn tĩnh | 1002 | 1005 | 2 phút 32 giây | 4 phút 15 giây |
Trình xây dựng theo yêu cầu | 2 | 0 | 52 giây | 52 giây |
Nó giúp triển khai nhanh hơn và do đó đáng tin cậy hơn. Hiệu suất chỉ giảm ở yêu cầu đầu tiên, từ yêu cầu tiếp theo trở đi, trang được kết xuất sẽ được lưu vào bộ nhớ đệm ngay trên Edge, giúp hiệu suất giống hệt như Fully Static Generated.
Tương lai: Kết xuất liên tục phân tán
Vào cùng ngày, On-Demand Builders đã được công bố và đưa vào quyền truy cập sớm, Netlify cũng đã công bố Yêu cầu bình luận về Kết xuất liên tục phân tán (DPR).DPR là bước tiếp theo dành cho On-Demand Builders. Nó tận dụng các bản dựng nhanh hơn bằng cách sử dụng các bước xây dựng không đồng bộ như vậy và sau đó lưu trữ đệm các tài sản cho đến khi chúng thực sự được cập nhật. Không còn bản dựng đầy đủ cho trang web có 10.000 trang nữa. DPR trao quyền cho các nhà phát triển để kiểm soát hoàn toàn các hệ thống xây dựng và triển khai thông qua bộ nhớ đệm vững chắc và sử dụng On-Demand Builders.
Hãy hình dung tình huống này: một trang web thương mại điện tử có 10.000 trang sản phẩm, điều này có nghĩa là sẽ mất khoảng 2 giờ để xây dựng toàn bộ ứng dụng để triển khai. Chúng ta không cần phải tranh luận về việc này đau đớn như thế nào.
Với DPR, chúng ta có thể thiết lập 500 trang hàng đầu để xây dựng trên mỗi lần triển khai. Các trang có lưu lượng truy cập lớn nhất của chúng tôi luôn sẵn sàng cho người dùng của chúng tôi. Nhưng chúng tôi là một cửa hàng, tức là mỗi giây đều có giá trị. Vì vậy, đối với 9500 trang còn lại, chúng ta có thể thiết lập một móc sau khi dựng để kích hoạt trình dựng của chúng — triển khai phần còn lại của các trang của chúng ta theo cách không đồng bộ và lưu vào bộ nhớ đệm ngay lập tức. Không có người dùng nào bị ảnh hưởng, trang web của chúng ta đã được cập nhật với bản dựng nhanh nhất có thể và mọi thứ khác không tồn tại trong bộ nhớ đệm sau đó đã được lưu trữ.
Kết luận
Mặc dù nhiều điểm thảo luận trong bài viết này là khái niệm và việc triển khai vẫn chưa được xác định, tôi rất hào hứng về tương lai của Jamstack. Những tiến bộ mà chúng ta đang thực hiện với tư cách là một cộng đồng xoay quanh trải nghiệm của người dùng cuối.Bạn nghĩ gì về Distributed Persistent Rendering? Bạn đã thử On-Demand Builders trong ứng dụng của mình chưa? Hãy cho tôi biết thêm trong phần bình luận hoặc gọi cho tôi trên Twitter. Tôi thực sự tò mò!
Tài liệu tham khảo
- “Hướng dẫn đầy đủ về tái tạo tĩnh gia tăng (ISR) với Next.js,” Lee Robinson
- “Xây dựng nhanh hơn cho các trang web lớn trên Netlify với trình xây dựng theo yêu cầu,” Asavari Tayal, Blog Netlify
- “Kết xuất liên tục phân tán: Một phương pháp tiếp cận Jamstack mới để xây dựng nhanh hơn,” Matt Biilmann, Blog Netlify
- “Kết xuất liên tục phân tán (DPR),” Cassidy Williams, GitHub
Đọc thêm
- Một mẫu mới cho Jamstack: Kết xuất phân đoạn
- Hướng dẫn tối ưu hóa hình ảnh trên các trang web Jamstack
- GraphQL đầy đủ với Next.js, Neo4j AuraDB và Vercel
- Tạo biểu mẫu nhiều bước hiệu quả để có trải nghiệm người dùng tốt hơn