Prpl

patternsdev/skills/javascript/prpl

作者 patternsdev48bf58a488cdMIT253 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫5 個月前更新

Teaches the PRPL pattern for optimizing initial page load. Use when building Progressive Web Apps or when you need to push critical resources, render the initial route, pre-cache remaining routes, and lazy-load on demand.

AI 產生的概覽

說明用於最佳化漸進式網頁應用程式首次載入的 PRPL 模式。

功能
此技能提供 PRPL 模式的指引:推送關鍵資源、渲染初始路由、預先快取其餘路由,以及視需求延遲載入。它說明了 HTTP/2 的伺服器推送與預載提示、應用程式外殼架構、程式碼拆分,以及 Service Worker 快取。它產出的是說明性指引,而非程式碼或檔案。
適用情境
適用於建置漸進式網頁應用程式,或需要在低階裝置與慢速網路上有效率載入的網頁應用程式。它也適用於最佳化網頁應用程式的關鍵渲染路徑。
執行需求
不需要任何工具、套件、執行環境、認證或網路存取。它不隨附指令碼,僅為說明性內容。

PRPL Pattern

Making our applications globally accessible can be a challenge! We have to make sure the application is performant on low-end devices and in regions with a poor internet connectivity. In order to make sure our application can load as efficiently as possible in difficult conditions, we can use the PRPL pattern.

When to Use

  • Use this when building applications that need to perform well on low-end devices and slow networks
  • This is helpful for optimizing the critical rendering path of web applications

Instructions

  • Push critical resources efficiently using HTTP/2 server push or preload hints
  • Render the initial route as soon as possible for fast first paint
  • Pre-cache frequently visited routes using service workers for offline support
  • Lazily load routes and assets that aren't immediately needed
  • Use an app shell architecture as the main entry point

Details

The PRPL pattern focuses on four main performance considerations:

  • Push critical resources efficiently, which minimizes the amount of roundtrips to the server and reducing the loading time.
  • Render the initial route as soon as possible to improve the user experience
  • Pre-cache assets in the background for frequently visited routes to minimize the amount of requests to the server and enable a better offline experience
  • Lazily load routes or assets that aren't requested as frequently

When we want to visit a website, we first have to make a request to the server in order to get those resources. The file that the entrypoint points to gets returned from the server, which is usually our application's initial HTML file! The browser's HTML parser starts to parse this data as soon as it starts receiving it from the server. If the parser discovers that more resources are needed, such as stylesheets or scripts, another HTTP request is sent to the server in order to get those resources!

Having to repeatedly request the resources isn't optimal, as we're trying to minimize the amount of round trips between the client and the server!

For a long time, we used HTTP/1.1 in order to communicate between the client and the server. HTTP/2 introduced some significant changes compared to HTTP/1.1, which make it easier for us to optimize the message exchange between the client and the server.

Whereas HTTP/1.1 used a newline delimited plaintext protocol in the requests and responses, HTTP/2 splits the requests and responses up in smaller pieces called frames. An HTTP request that contains headers and a body field gets split into at least two frames: a headers frame, and a data frame!

HTTP/1.1 had a maximum amount of 6 TCP connections between the client and the server. Before a new request can get sent over the same TCP connection, the previous request has to be resolved! If the previous request is taking a long time to resolve, this request is blocking the other requests from being sent. This common issue is called head of line blocking, and can increase the loading time of certain resources!

HTTP/2 makes use of bidirectional streams, which makes it possible to have one single TCP connection that includes multiple bidirectional streams, which can carry multiple request and response frames between the client and the server!

HTTP/2 solves head of line blocking by allowing multiple requests to get sent on the same TCP connection before the previous request resolves!

HTTP/2 also introduced a more optimized way of fetching data, called server push. Instead of having to explicitly ask for resources each time by sending an HTTP request, the server can send the additional resources automatically, by "pushing" these resources.

After the client has received the additional resources, the resources will get stored in browser cache. When the resources get discovered while parsing the entry file, the browser can quickly get the resources from cache instead of having to make an HTTP request to the server!

Although pushing resources reduces the amount of time to receive additional resources, server push is not HTTP cache aware! The pushed resources won't be available to us the next time we visit the website, and will have to be requested again. In order to solve this, the PRPL pattern uses service workers after the initial load to cache those resources in order to make sure the client isn't making unnecessary requests.

As the authors of a site, we usually know what resources are critical to fetch early on, while browsers do their best to guess this. We can help the browser by adding a preload resource hint to the critical resources!

By telling the browser that you'd like to preload a certain resource, you're telling the browser that you would like to fetch it sooner than the browser would otherwise discover it! Preloading is a great way to optimize the time it takes to load resources that are critical for the current route.

Although preloading resources is a great way to reduce the amount of roundtrips and optimize loading time, pushing too many files can be harmful. The browser's cache is limited, and you may be unnecessarily using bandwidth by requesting resources that weren't actually needed by the client.

The PRPL pattern focuses on optimizing the initial load. No other resources get loaded before the initial route has loaded and rendered completely!

We can achieve this by code-splitting our application into small, performant bundles. Those bundles should make it possible for the users to only load the resources they need, when they need it, while also maximizing cachability!

Caching larger bundles can be an issue. It can happen that multiple bundles share the same resources. A browser has a hard time identifying which parts of the bundle are shared between multiple routes, and can therefore not cache these resources. Caching resources is important to reduce the number of roundtrips to the server, and to make our application offline-friendly!

When working with the PRPL pattern, we need to make sure that the bundles we're requesting contain the minimal amount of resources we need at that time, and are cachable by the browser.

The PRPL pattern often uses an app shell as its main entry point, which is a minimal file that contains most of the application's logic and is shared between routes! It also contains the application's router, which can dynamically request the necessary resources.

The PRPL pattern makes sure that no other resources get requested or rendered before the initial route is visible on the user's device. Once the initial route has been loaded successfully, a service worker can get installed in order to fetch the resources for the other frequently visited routes in the background!

Since this data is being fetched in the background, the user won't experience any delays. If a user wants to navigate to a frequently visited route that's been cached by the service worker, the service worker can quickly get the required resources from cache instead of having to send a request to the server.

Resources for routes that aren't as frequently visited can be dynamically imported.

Source

來源與署名

來源:patternsdev/skills位於javascript/prpl提交48bf58a

授權條款: MIT

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架