Apryse Announces Acquisition of AI-Powered Document Toolkit Provider LEAD Technologies
By Roger Dunham | 2024 Feb 10
Summary: This article explains how WebAssembly threads can help speed up document loading, and demonstrates how to safely enable them in IIS using cross-origin isolation.
WebAssembly threads are a feature that allows WebAssembly apps to use traditional multithreading paradigms on the web. It enables you to either run parts of your code in parallel on separate cores, or to run the same code over independent parts of the input data. This scales it to as many cores as the user has and significantly reduces the overall execution time.
WebAssembly threads were introduced into Chrome in 2018 and offered significant improvement. Unfortunately, their implementation opened a security loophole that allowed the Spectre/Meltdown cyberattacks to occur, so the option was removed unless explicitly enabled.
In this article, we look at how to safely enable WebAssembly threads in IIS by enabling cross-origin isolation. The article is largely based on Chrome, but other browsers behave in a similar way.
The article assumes that you have some familiarity with DevTools. If not, you can read more about what DevTools are and how to enable them.
If you head to a website that contains the Apryse WebViewer where the web server has not been configured to support WebAssembly threads, you will see a message in the DevTools console.
Figure 1 – The message shown in DevTools if your server is not configured to support WebAssembly threads
This message says:
Your server has not been configured to serve WebAssembly threads. See https://docs.apryse.com/documentation/web/faq/wasm-threads for instructions on how to resolve this.
The message is self-explanatory and includes a link to a page that explains what WebAssembly threads are and how to enable them.
We will follow that advice in a minute. Before we do, let’s look at the potential benefits of enabling WebAssembly threads.
WebAssembly threads allow some documents to be displayed more quickly by performing some parts of the processing in parallel. Of course, if the document is very simple, there may be little real benefit. As such, the amount of time that WebAssembly threads saves varies from document to document. Large documents with complex drawings or many annotations are likely to show much greater reduction in rendering time than short, simple documents. The value therefore depends on the type of document that your users will typically be viewing.
Measuring the benefit of WebAssembly threads in an objective way is not straightforward. Many things happen on a computer that are not directly associated with the browser rendering a document – background processes may spin up at an unexpected time, for example. Furthermore, data may be cached in some situations, which gives a speedy result. This can mean that the first time a file is rendered, it may be significantly slower than when exactly the same file is rendered again.
To make things more complicated, the speed of rendering may vary between different browsers, and even with different versions of the same browser.
As such, the following figures should be treated as indicative, but feel free to download the source code and try for yourself. The code is based on the sample used for the blog about getting started with Blazor and WASM.
The data were collected by initially clearing the cached data in Chrome v121, then loading a single document automatically, then manually loading three moderately complex documents two times each and averaging the time taken.
For these three files, the time taken to render the file when WebAssembly threads were enabled was considerably faster than when it was not. However, the reduction in time for one of the files – from just over to just under 1 second – is not very exciting. On the other hand, the reduction in time for the slowest file – from 8 to 4 seconds – will be extremely noticeable to the user.
Figure 2 – Time to render each of three files, with and without WebAssembly threads, within a Blazor App running in IIS
I ran the same tests using similar code in a Vite/ReactJS app using a local dev server, and found similar results.
Figure 3 – Time to render each of three files, with and without WebAssembly threads, within a Vite/ReactJS app running in a local dev server
In this case, the benefits are obvious. But for other documents or other hardware, the results may be less clear cut.
Life is full of trade-offs, and WebAssembly threads are no different.
While WebAssembly threads may allow for faster rendering of documents, they require cross-origin isolation to be enabled. Enabling cross-origin isolation will block the loading of cross-origin resources that you don't explicitly opt-in. This might, for example, affect the ability to display advertisements from a third-party site. It will also prevent your top-level document from being able to communicate with pop-up windows.
You may wish to read a guide to enable cross-origin isolation, which explores this further and describes how you can assess the impact of the changes. These issues may also be resolved by future development work within browsers.
WebAssembly threads rely on SharedArrayBuffer which in turn relies on cross-origin isolation.
That requires you to enable the response headers Cross-Origin-Opener-Policy (COOP) and Cross-Origin-Embedder-Policy (COEP).
Despite the complex names, this is remarkably straightforward in IIS.
Within the IIS Manager, click on the website, select HTTP response headers, and add the headers with associated values:
Figure 4 – The HTTP Response headers option in IIS
Figure 5 – Adding one of the required headers
Figure 6 – IIS showing that both headers have been added
Once the headers have been added, restart the IIS server.
One problem that may occur is that some resource types will need to have their MIME type specified. For example, the following error may occur:
Figure 7 – The error associated with MIME type not being specified for .dat
This is solved by specifying the MIME type for the file extension .dat as application/octet-stream.
Figure 8 – Specifying the MIME type for .dat
You may also need to specify the same MIME type for .res and .mem.
A word of warning – IIS, and browsers have a tendency to cache data. As such, even when you have correctly configured everything, it may not be available immediately. You may need to clear the cache in the browser, restart the IIS server, and browse again from IIS.
Once everything is configured correctly, the warning message about WebAssembly threads will disappear. (Although other warnings for .gz and .br files, and watermarking may still be seen – we can look at getting rid of them in a different article.)
Figure 9 – DevTools console output with WebAssembly correctly configured. The warning about WebAssembly threads is no longer shown.
You can also verifythat it is correctly configured by checking that entering self.crossOriginIsolated in the console within DevTools returns true.
Figure 10 – Verifying that CrossOriginIsolated is true
The mechanism for configuring Response Headers and specifying MIME types differs for Apache and NGINX, as well as for cloud-based hosting platforms. These will be covered in a future article, but please reach out to support if you require assistance.
WebAssembly threads can help make a faster and better experience for your users, depending on the types of documents they open. Enabling them requires a few changes on the server, but can cause issues with showing pop-ups and loading content from third party websites. As such, you may wish to discuss your requirements with the support team.
Share this post