Photoshop is now on the web!

Addy Osmani
8 min readSep 30, 2023

Enabled by WebAssembly + Emscripten, Web Components + Lit, Service Workers + Workbox & new Web APIs. Chrome & Adobe enjoyed collaborating on it.

Bringing the Photoshop desktop application to the web (photoshop.adobe.com) represents an enormous milestone in bringing highly complex and graphically intensive software to the browser. This was made possible through years of effort by Adobe engineers and collaboration with browser vendors like Chrome to push the web forward.

Photoshop for web includes a broad range of advanced features, including Generate fill.

In this case study, we’ll take a close look at the advanced web capabilities unlocked, performance optimizations undertaken, and future possibilities this enables. “Photoshop’s journey to the web” is also an excellent read.

The Vision: Photoshop in the Browser

For decades, Photoshop has been the gold standard in image editing and graphic design, powering creativity across Windows and macOS. But a world of new opportunities opens up by untethering it from the desktop.

The web promises ubiquitous, frictionless access. Users can start editing and collaborating instantly with just a browser, no installation needed. And they can pick up seamlessly across devices.

Linkability enables sharing workflows. Photoshop documents can be accessed at a URL, rather than buried in the files system. Creators can easily send a link to collaborators.

Cross-platform flexibility. The web as a runtime abstracts away underlying operating systems. Photoshop can reach users on multiple platforms.

But substantial technical challenges stood in the way of realizing this vision, requiring rethinking how an intense app like Photoshop could work on the web.

New Web Capabilities Unlock Photoshop’s Potential

In recent years, new web platform capabilities have emerged that can finally enable Photoshop-class applications, through both standardization and implementation. Adobe engineers made innovative use of several key next-generation APIs:

High-Performance Local File Access with the Origin Private File System

Photoshop operations involve reading and writing potentially massive PSD files. This requires efficient access to a local file system. The new Origin Private File System API (OPFS) provides a fast, origin-specific virtual file system.

const opfsRoot = await navigator.storage.getDirectory();

OPFS enables quickly creating, reading, writing, and deleting files. For example:

// Create file
const file = await opfsRoot.getFileHandle('image.psd', {create: true});

// Get read/write handle
const handle = await file.createSyncAccessHandle();

// Write contents
handle.write(buffer);

// Read contents
handle.read(buffer);

// Delete file
await file.remove();

For the absolute fastest synchronous operations, Web Workers can get a FileSystemSyncAccessHandle.

This local high-performance file system was critical for implementing Photoshop’s demanding file workflows in the browser.

Unleashing the Power of WebAssembly

WebAssembly was an essential ingredient for recreating Photoshop’s computationally intensive graphics processing in JavaScript. Adobe used the Emscripten compiler to port their existing C/C++ codebase to WebAssembly modules.

Several WebAssembly capabilities were critical:

  • Threads — Photoshop uses worker threads for parallel execution of tasks like processing image tiles:
// Thread function
void* tileProcessor(void* data) {
// Process image tile data
return NULL;
}

// Start worker threads
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, tileProcessor, NULL);
pthread_create(&thread2, NULL, tileProcessor, NULL);

// Wait for threads to finish
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
  • SIMD — SIMD vector instructions accelerate pixel manipulations and filtering.
  • Exception handling — C++ exceptions are widely used throughout Photoshop’s codebase.
  • Streaming instantiation — Photoshop’s 80MB+ WASM modules require streaming compilation.
  • Debugging — Chrome’s WebAssembly debugging support in DevTools was invaluable.

Harnessing the Wide P3 Color Gamut

sRGB’s color spectrum pales in comparison to the wider P3 gamut, but it has long been the only option on the web.

Photoshop uses the new color() function and Canvas APIs to unlock the full vibrancy of P3, enabling more accurate color representation.

color: color(display-p3 1 0.5 0)

UI Flexibility with Web Components

Photoshop is part of Adobe’s broader Creative Cloud ecosystem. Using a standardized Web Components strategy built on Lit allows UI consistency across applications.

Photoshop’s UI elements come from Adobe’s Spectrum Web Components library, which implements Adobe’s design system.

Spectrum Web Components are:

  • Accessible by default — Developed with existing and emerging browser specs in mind to support assistive technologies.
  • Lightweight — Implemented with LitElement for minimal overhead.
  • Standards based — Built on Web Component standards like custom elements and Shadow DOM.
  • Framework agnostic — Work with any framework thanks to browser-level support.

Furthermore, the entire Photoshop app is built using Lit-based Web Components. Lit’s templating and virtual DOM diffing allow efficient UI updates. Web Components encapsulation also made it easy to integrate React code from other teams when needed.

Overall, Web Components’ browser-native custom elements, combined with Lit’s performance, provided the flexibility Adobe needed to build Photoshop’s complex UI while maintaining efficiency.

Optimizing Photoshop’s Performance in the Browser

While new web capabilities provided the foundations, an intensive desktop application like Photoshop still needed extensive tracing and performance work to deliver a first-class experience online.

Long tasks broken up in the loading of the initial Photoshop web application

Caching Assets and Code with Service Workers

Service Workers allow web apps to cache their assets, code, and other resources locally for much faster load times after the initial visit. Although not yet a fully offline-capable app, Photoshop already leverages Service Workers to cache its WebAssembly modules, scripts, and other assets.

Chrome DevTools Application panel > Cache storage showing the different kinds of resources being precached by Photoshop for web. Here ew see a number of the JavaScript chunks that they code-split that are locally cached, enabling very fast subsequent loads.

This caching makes a dramatic difference in load performance. After the first visit, subsequent loads are typically very fast (M1 Macbook):

Adobe used the Workbox libraries to more easily integrate Service Worker caching into their build process.

V8 Optimization of Cached Resources

V8 employs some optimizations when resources are returned from Service Worker caches:

  • Resources cached during install are compiled eagerly and code cached immediately for consistent, fast performance.
  • Resources cached via the Cache API during fetch get optimized caching on the 2nd load, faster than typical caching.
  • V8 detects resource importance based on being cached and compiles more aggressively.

These allow optimizing Photoshop’s massive cached Wasm modules.

A subsequent load of Photoshop web loading key views faster thanks in part to V8 code-caching.

Streaming and Caching Large WebAssembly Modules

Photoshop’s codebase requires multiple large WebAssembly modules, some over 80MB. Streaming compilation support in V8 and Chrome allows these massive modules to be handled performantly.

In addition, the first time a WebAssembly module is requested from a Service Worker, V8 generates and stores an optimized version to cache — critical for Photoshop’s large code size.

Multithreading for Parallel Graphics Operations

Many core image processing operations in Photoshop like transforming pixels can be massively sped up through parallel execution across threads. WebAssembly’s threads support unlocks leveraging multi-core devices for computationally intensive graphics tasks.

This allows Photoshop to use the same multithreading approaches from desktop for performance-critical image processing functions ported to WebAssembly.

Debugging WebAssembly for Optimization

Robust WebAssembly debugging support was critical for diagnosing and fixing performance bottlenecks during development.

Chrome DevTool’s ability to profile WASM code, set breakpoints, and inspect rich variables mirrors the debuggability of JavaScript:

Integrating On-Device Machine Learning with TensorFlow.js

Recent versions of Photoshop on the web include AI-powered capabilities using TensorFlow.js. Running models on-device rather than in the cloud improves privacy, latency, and cost.

“TensorFlow.js is an open-source machine learning library from Google aimed at JavaScript developers that’s able to run client side in the browser. It’s the most mature option for web ML with comprehensive WebGL and WebAssembly backend operators support, and in the future, there will also be an option for a WebGPU backend to be used within the browser for faster performance as new web standards evolve.”

The Select Subject feature uses machine learning to automatically extract the main foreground object in an image, drastically speeding up complex selections.

I have an illustration of a sunset that I wanted to change to be set at night. I used “select subject” and an AI prompt to try picking the region(s) of greatest interest to update.
Photoshop was able to both generate an updated illustration based on my AI prompt
…as well as several beautiful variations.

The model was converted from TensorFlow to TensorFlow.js to enable local execution:

// Load Select Subject model
const model = await tf.loadGraphModel('select_subject.json');

// Run inference on image tensor
const {mask, background} = model.execute(imgTensor);

// Refine selection from mask

Adobe and Google collaborated to resolve synchronization issues between Photoshop’s WebAssembly code and TensorFlow.js by developing a proxying API for Emscripten. This allows seamless integration between the frameworks.

“Since the Google team has improved TensorFlow.js hardware execution performance via its various supported backends (WebGL, WASM, Web GPU), it has resulted in models seeing anywhere from 30% to 200% performance improvements (especially for the larger models that tend to see the biggest gains), enabling close to real time performance right in the browser.”

Key models were optimized focusing on performance-critical operations like Conv2D. Photoshop can choose whether to run models on-device or in the cloud based on performance needs.

See the TensorFlow.js Photoshop article for more details.

The Future of Photoshop on the Web

The general availability of Photoshop on the web represents an enormous milestone, but only scratches the surface of the possibilities.

Photoshop will continue to expand on the web, with more features coming online through progressive enhancement as browser vendors evolve standards and performance. And Photoshop is just the beginning. Adobe plans to aggressively build out its entire Creative Cloud suite on the web, unlocking many more sophisticated design applications in the browser.

The collaboration between Adobe and browser engineers will continue driving the web forward as a platform for ever more ambitious applications through advancing standards and performance improvements. There are exciting times ahead!

Trying Photoshop on the Web

Photoshop on the web is currently available on desktop versions of:

  • Chrome 102+
  • Edge 102+
  • Firefox 111+

and work to close the gap in support for Safari is underway.

You can try it out today at photoshop.adobe.com. The future of creativity and design on the web is right at your fingertips!

--

--