Browsers can do that?
Tags: webdev, javascript, html, tutorial
Published: 2022-02-10 05:55:20

For the past few years since I began my [endeavor](https://github.com/DustinBrett/daedalOS) to make a [web desktop environment](https://dustinbrett.com/) I've become fascinated to know what is possible with a modern web browser and where the limits are. Throughout that time I've been repeatedly surprised with how far we've come and what features have made it into some of todays browsers.

Here is my list of the amazing things browsers can do!

## Local Directory Access
- [MDN](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) / [Can I use](https://caniuse.com/native-filesystem-api)

Not to be confused with the [File and Directory Entries API](https://developer.mozilla.org/en-US/docs/Web/API/File_and_Directory_Entries_API), this rather new and still in development spec is called the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) and allows "_reading files, writing or saving files, and access to directory structure_". It's currently supported in Chromium browsers which includes Edge, Chrome & Opera. Also as of Dec 2021 with [15.2](https://developer.apple.com/documentation/safari-release-notes/safari-15_2-release-notes) we now have partial support for this API in Safari. And as of last week the spec has been partially moved to [WHATWG](https://fs.spec.whatwg.org/) which could be considered progress towards better all around browser support going forward.

```js
const dirHandle = await window.showDirectoryPicker();

for await (const [key, value] of dirHandle.entries()) {
    console.log({ key, value });
}
```

## Multithreading
- [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) / [Can I use](https://caniuse.com/webworkers)

I've recently been experimenting more with Web Workers and I've found they can have a huge improvement in performance depending on what kind of workloads you are able to offload to them. A worker can be created by referencing a `.js` file but the method I've preferred involves converting an function directly into a string which the worker can load.

One use case that I've found improved loading time greatly was moving my [three.js](https://threejs.org/) [animated 3D background](https://www.vantajs.com/) to a web worker by passing the canvas to the worker via [OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas) which is [currently not available](https://caniuse.com/offscreencanvas) on Firefox or Safari, so the traditional main thread rendering method still needs to be a fallback at this point.

```js
const workerFunction = () =>
  console.log(`typeof window === ${typeof window}`);
const workerUrl = URL.createObjectURL(
  new Blob(["(", workerFunction.toString(), ")()"], {
    type: "application/javascript",
  })
);

new Worker(workerUrl, { name: "ExampleWorker" });
```

## Emulation, Manipulation & Compression
- [MDN](https://developer.mozilla.org/en-US/docs/WebAssembly) / [Can I use](https://caniuse.com/wasm)

Even before WebAssembly was popular, people were already porting some pretty cool stuff to `.wasm` which can run in the browser with the help of a `.js` file to load it typically. This has made it much easier to convert existing codebases from languages such as C, C++ & Rust to run in the browser.

For example, although [Adobe Flash](https://www.adobe.com/ca/products/flashplayer/end-of-life.html) has lost support in browsers, you can now use [Ruffle](https://ruffle.rs/) which is written in Rust and has been compiled to run in the browser. Another very cool example is the x86 emulator known as [v86](https://github.com/copy/v86) which is written in C & Rust and has the ability to run various operating systems such as Linux from within the browser.

Also often realized via the power of [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly), the ability to convert/edit media formats is not the sole domain of the backend. Most of these operations could in theory happen in the frontend.

When it comes to audio/video the trusted tool that is often used on the desktop is [FFmpeg](https://www.ffmpeg.org/) and this too has been [ported](https://ffmpegwasm.netlify.app/) to run in the browser, although if you want multithreading you will need to make sure you have special CORS headers enabled to gain access to the [SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer). For images on desktop there is the popular [ImageMagick](https://imagemagick.org/index.php) which indeed also has been [ported](https://github.com/KnicKnic/WASM-ImageMagick).

Another operation that is sometimes desired is to take several files and give the user a compressed file. There are actually a surprisingly large amount ([jszip](https://github.com/Stuk/jszip), [pako](https://github.com/nodeca/pako)) of client side options here, but my favorite so far when it comes to speed, size and working with `.zip` has been [fflate](https://github.com/101arrowz/fflate). But if you'd like to work with other formats, there are also libraries to decompress [7-Zip, RAR & TAR](https://github.com/nika-begiashvili/libarchivejs).

## The Future in Action

Thanks for checking out this article where I go over the browser technologies that I've been most excited about. If you would like to try out some of these technologies, I implement them all within [my website](https://dustinbrett.com/). I also stream about my web/coding adventures on YouTube if you'd like to check out [my channel](https://www.youtube.com/c/DustinBrett/featured).

{% youtube Jyb8Erp_I2Y %}