Web Caching for Our JavaScript PDF Viewer
To let your users experience a fast PDF viewer, the loading performance of assets — especially your PDF files — is critical. In this guide, you’ll learn how to make your assets load fast and how to cache them for a long time.
gzip and Brotli
All modern browsers support gzipped content. This allows your server to deliver a compressed version of your assets with a reduced file size. The browser will take care of uncompressing the assets as soon as it has received them.
Many web servers, like Apache or Nginx, can gzip responses automatically right before they get sent to the client. However, unless your assets are created dynamically for every request, an even smarter solution is to create gzipped versions of your assets when you deploy them.
Tools like webpack offer plugins to gzip your assets at build time. Once you deploy them, make sure your server sends the gzipped version of the file if the user’s browser supports it. In this case, the user’s browser will send the following header with the request:
Accept-encoding: gzip, deflate
An even better compression method for your assets is Brotli. With Brotli, you can achieve a 20-percent decrease in file size in comparison to gzip. However, Brotli is not as well supported by browsers as gzip is. If a browser supports Brotli, it will include it in its Accept-encoding
header:
Accept-encoding: gzip, br
There’s also a webpack plugin that compresses your assets with Brotli at build time.
Long Caching
Ideally, everything required to load PSPDFKit should be loaded in the browser before a user even enters a page that displays a PDF.
When using PSPDFKit in Standalone mode, this applies especially to the pspdfkit.js
and pspdfkit.wasm
files, which are large.
Once your users have downloaded your assets, you should make sure they don’t have to download them again every time they need them. The easiest and most efficient way to do this is to tell the browser to cache your assets for a long time and to give them a unique path that changes whenever the asset’s content changes.
In this way, the browser only needs to download an asset once and can serve further requests for the same assets from the browser cache. When an asset changes, tell the browser about the new path, for example by passing the new path in PSPDFKit’s document
option. Once the browser has downloaded the changed file, it will serve it from the cache again for a long time.
To tell the browser to keep your assets for a certain time without fetching them again, pass the following HTTP header along with the asset response:
Cache-Control: max-age=8640000
This tells the browser to keep your asset in its cache for up to 100 days (100 _ 24 _ 60 * 60 = 8640000 seconds).
Inspecting Asset Loading
In Your Browser’s Dev Tools
To check if your assets are delivered with the correct encoding and headers, you can use your browser’s dev tools. In this example, we’ll use Chrome’s dev tools, but you’ll find similar tools in every modern browser.
You can see above that the PDF was served with a Cache-Control
header, which prevents refetching when you access the same file again within one day.
The browser also states that it supports gzip compression, but apparently the server can’t deliver a gzipped version; otherwise, there would be the response header Content-Encoding: gzip
. To improve loading performance of the PDF, you should configure the server to deliver a gzipped version.
Using cURL
You can also use cURL to send an HTTP request and check the response headers. For instance, if you want to check that the pspdfkit.wasm
file is being served with proper caching and compression response headers, you can try the following:
curl 'https://example.com/pspdfkit-lib/pspdfkit-9709cb17eadf2572.wasm' \ -I \ -X GET \ -H "accept-encoding: gzip, deflate, br"
A response might then look like this:
HTTP/1.1 200 OK Content-Type: application/wasm Content-Length: 3035090 Connection: keep-alive vary: Accept-Encoding cache-control: public, max-age=31536000 accept-ranges: bytes content-encoding: br Access-Control-Allow-Origin: *
Notice the presence of both the cache-control
and content-encoding
HTTP response headers — just like what can be seen in the example in the previous section.
Precaching on the Browser
Using service workers, you can intercept fetch requests from the browser and return cached versions of the requested assets instead of going through the network.
Service workers have many nice features — among them, the ability to add files to the browser cache when the service worker is installing. This feature is called precaching.
An easy solution to implement precaching is using the Workbox library. Workbox not only precaches assets, but it also takes care of both loading a newer version when something has changed and removing old versions from the cache. This way, your browser cache is used more efficiently than it is with HTTP caching.
You’ll find all the details relevant to this in the Workbox precaching guide.
If you’re using webpack, there’s a Workbox webpack plugin. This will precache all files of your webpack build by default. If you only want to precache the PSPDFKit assets, you can set a limit in the plugin configuration:
new Workbox.GenerateSW({ include: ["pspdfkit.js", "pspdfkit.wasm"] });
Caching is a comprehensive topic and we’ve barely scratched the surface here. If you want to learn more, check out the Google and Mozilla guides on HTTP caching.
Content Delivery Network
If you serve customers all around the world, you should consider using a Content Delivery Network (CDN). CDNs store your assets on several servers in different parts of the world. Your CDN will make sure your users always receive content from the closest available server. This reduces latency and download speed, and it takes the load away from your production server, which will no longer have to serve the assets.
An additional benefit of CDNs is the high availability of your content: Should one server become unreachable, your content can still be delivered from another available server.
Typically, CDNs let you configure the caching headers your assets are delivered with, and you can also provide a gzipped version of your files, which gets served automatically if the user’s browser supports it.
For more information on how to set up caching with your CDN of choice, check out the following links:
-
Amazon CloudFront: Request and Response Behavior and Expiration
-
Microsoft Azure: Manage expiration of Blob storage and web content
Caching on Server-Backed
PSPDFKit for Web Server-Backed caches rendered pages in memory to speed up future rendering. When you run into server performance issues, increasing the server’s memory will keep more pages in the cache, leading to faster page loads on average.
For a multi-server setup, you can use Redis to cache pages that have been rendered by an arbitrary server, and a server can even access a cached page created by another server.
For more details on this, see the server caching guide.