阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

前端“秀肌肉”,云端 Photoshop 亮相

作者 | Addy Osmani

  • 2023-10-30
    北京
  • 本文字数:4172 字

    阅读完需:约 14 分钟

前端“秀肌肉”,云端 Photoshop 亮相

WebAssembly + Emscripten, Web 组件 + Lit, Service Workers + Workbox,以及全新 Web API 在此汇聚。Chrome 和 Adobe 正在携手打造新的图像编辑体验。


为 Photoshop 桌面应用程序开发 Web(photoshop.adobe.com)版,标志着将高度复杂和图形密集型软件引入浏览器的一个巨大里程碑。它的诞生离不开 Adobe 工程师们的多年努力,以及同 Chrome 等浏览器供应商的携手合作与 Web 技术本身的持续发展。



Photoshop Web 版中包含一系列高级功能,例如生成填充等


在本次案例研究中,我们将一同了解现已公布的高级 Web 功能、已经实现的性能优化以及未来有望落地的更多可能性。感兴趣的朋友还可参考《Photoshop 的 Web 之旅》(https://web.dev/ps-on-the-web/)一文了解更多细节信息。


发展愿景:让 Photoshop 登陆浏览器


几十年来,Photoshop 一直是图像编辑和图形设计领域的黄金标准,一直在 Windows 和 macOS 平台上为创意人士提供助力。但随着将其从桌面平台上解放出来,一个充满机遇的新世界也由此敞开了大门。


Web 的优势,在于无处不在、顺畅灵活的访问方式。用户只需打开浏览器即可着手编辑和协作,无需任何安装步骤。工作内容还可跨设备实现无缝衔接。


通过链接形式共享工作流程。Photoshop 文档可以通过 URL 访问,而不再隐藏于文件系统之内。如此一来,创作者可以轻松将链接发送给其他协作伙伴。


轻松实现跨平台操作。作为运行时,Web 抽象掉了底层操作系统,使得 Photoshop 能够覆盖用户手中的多种不同平台。


但实现这个愿景也面临着巨大的技术挑战,工程师们需要重新思考 Photoshop 这样强大的应用程序要如何在 Web 上运行、起效。


全新 Web 功能,释放 Photoshop 潜力


近年来,新的 Web 平台功能不断涌现。依托各种标准化和实施成果,Photoshop 级的应用程序终于具备了登陆 Web 端的可能性。Adobe 工程师也在项目中创新性地使用了几大关键下一代 API。


使用 Origin 私有文件系统,实现高性能本地文件访问


Photoshop 在操作中需要读取和写入大量 PSD 文件,这就要求其必须高效访问本地文件系统。新的 Origin 私有文件系统 API(OPFS)就提供一套指定特定数据源的快速虚拟文件系统。


const opfsRoot = await navigator.storage.getDirectory();
复制代码


OPFS 能够快速创建、读取、写入和删除文件。例如:


// Create fileconst file = await opfsRoot.getFileHandle('image.psd', {create: true});// Get read/write handleconst handle = await file.createSyncAccessHandle();// Write contents handle.write(buffer);// Read contentshandle.read(buffer);// Delete fileawait file.remove();
复制代码


对于绝对速度最快的同步操作,Web Workers 能够使用 FileSystemSyncAccessHandle。


这种本地高性能文件系统,让 Photoshop 具备了在浏览器端严格处理文件工作流程的能力。


释放 WebAssembly 的力量


WebAssembly 的任务,是使用 JavaScript 重新创建 Photoshop 计算密集型图形处理体系的重要前提。Adobe 使用 Emscripten 编译器将其现有 C/C++ 代码库移植成了 WebAseembly 模块。


其中,WebAssembly 的以下重要功能发挥了关键作用:


  • Threads —Photoshop 使用工作线程以并行方式处理任务,例如处理图像图块:

  • SIMD — SIMD 矢量指令用于加速像素操作与过滤。

  • 异常处理 — C++ 异常在 Photoshop 代码库中得到广泛应用。

  • 流实例化 — Photoshop 的 80 MB+ WASM 模块离不开流式编译的支持。

  • 调试 — Chrome 的 WebAssembly 调试支持在 DevTools 中发挥着重要作用。

  • 运用 P3 宽色域


P3 那宽广的色域足以令 sRGB 色谱相形见绌,但长期以来,后者一直是 Web 端上的唯一选择。



如今,Photoshop 使用新的 color() 函数与 Canvas API 将 P3 充分运用起来,带来了更加准确的色彩表现。


color: color(display-p3 1 0.5 0)
复制代码


Web 组件让 UI 更加灵活


Photoshop 属于 Adobe 整体 Creative Cloud 生态系统中的组成部分。使用基于 Lit 构建的标准化 Web 组件策略,即可实现跨应用程序的 UI 一致性。



Photoshop 的 UI 元素来自 Adobe 的 Spectrum Web 组件库,Adobe 设计系统中的各种实现均来自该库。


Spectrum Web 组件具备以下特性:


  • 默认可及性——开发时即考虑到各现有及新兴浏览器规范,并可支持辅助服务选项。

  • 轻量化——使用 LitElement 以将运行开销控制在最低。

  • 基于标准——基于 Web 组件标准(例如自定义元素与 Shaodw DOM)进行构建。

  • 框架中立性——依托于浏览器的支持,可匹配任意框架。


此外,整个 Photoshop 应用均使用基于 Lit 的 Web 组件构建而成。Lit 的模板和虚拟 DOM diffing 可实现高效 UI 更新。Web 组件封装更可以在必要时轻松集成来自其他团队的 React 代码。


总体而言,Web 组件的浏览器原生自定义元素与 Lit 的性能优势相结合,共同为 Adobe 提供了构建 Photoshop 复杂 UI 所需要的灵活性,同时保持其拥有良好的运行效率。


优化 Photoshop 在浏览器中的性能表现


虽然有各项 Web 新功能作为实现基础,但像 Photoshop 这样的资源密集型桌面应用程序仍需要大量的性能跟踪与优化调整,才能转化为一流的线上使用体验。



在 Photoshop Web 应用进行初始加载时,会对长任务进行拆分


使用 Service Workers 缓存资产与代码


Service Workers 允许 Web 应用在本地缓存其资产、代码和其他资源,以便在初次访问之后加快加载速度。尽管尚不完全支持离线运行,但 Photoshop 已经依托 Service Workers 来缓存其 WebAssembly 模块、脚本及其他资源。



在 Chrome DevTools Application 面板 > 缓存存储处,可查看 Photoshop Web 版已经预缓存的各种资源类型。在这里,我们可以看到其代码被拆分成多个 JavaScript 块进行本地缓存,这样就能在后续加载时获得极快的加载速度。


这套缓存机制对于加载性能产生了巨大影响。在首次访问之后,后续加载往往非常快(以 M1 Macbook 平台为例):



Adobe 还使用 Workbox 库,轻松将 Service Worker 缓存集成至整个构建过程当中。


V8 引擎对缓存资源进行优化


当从 Service Worker 缓存处返回资源时,V8 引擎会采取以下优化策略:


  • 在 install 期间缓存的资源,会被立即编译并进行代码缓存,从而实现更快、更一致的性能表现。

  • 在 fetch 期间通过 Cache API 缓存的资源,在第二次加载时将获得缓存优化,速度高于常规缓存。

  • V8 会根据缓存检测资源的重要度,并更主动地进行编译。


这些优化策略能够覆盖 Photoshop 中的大量缓存 Wasm 模块。



Photoshop Web 版在后续加载中能够更快显示关键视图,这在一定程度上归功于 V8 的代码缓存机制。


大型 WebAssembly 模块的流式处理与缓存


Photoshop 的代码库需要多个大型 WebAssembly 模块,有些大小已经超过 80 MB。V8 和 Chrome 能够支持流式编译,因此可以高效处理这些大体量模块。


此外,在首次从 Serivce Worker 处请求 WebAssembly 模块时,V8 会生成优化版本并将其存入缓存,这种方式对于 Photoshop 这类大体量应用至关重要。


通过多线程实现图形并行操作


Photoshop 中的很多核心图像处理操作(例如转换像素)可以通过跨线程并行处理来大幅加快速度。WebAssembly 的多线程支持可以利用多核设备的算力优势,快速执行各类计算密集型图形任务。


如此一来,Photoshop 就能以与桌面版相同的多线程方法高效执行 WebAssembly 当中的关键图像功能。


调试 WebAssembly 以做进一步优化


强大的 WebAssembly 调试支持,对于诊断和修复开发过程中的性能瓶颈至关重要。


Chrome DevTool 能够分析 WASM 代码、设置断点并检查各种变量,由此体现 JavaScript 自身的可调试性优势:



将设备上的机器学习功能与 TensorFlow.js 相集成


Web 版 Photoshop 的最新版本,还包含基于 TensorFlow.js 的 AI 驱动功能。将云端模型转为本地设备运行,有助于改善隐私、延迟和成本。


TensorFlow.js 是谷歌发布的一套开源机器学习库,主要面向希望在浏览器中运行客户端的 JS 开发人员。其具备成熟的 Web 机器学习选项,以及全面的 WebGL 及 WebAssembly 后端操作程序支持。未来随着 Web 新标准的持续发展,用户还可选择在浏览器中使用 WebGPU 后端以获得更佳性能。


Select Subject(选择对象)功能,可使用机器学习自动提取图像中的主要前景对象,从而大大加快复杂取像的执行速度。



以这张夕阳插图为例,我想将画面改为夜间。这时我们可以使用“选择对象”加 AI 提示来提取相应区域进行修改。



Photoshop 能够根据我的 AI 提示词生成更新后的插图。



还可添加更多视觉效果。


其中的 AI 模型已经由 TensorFlow 转换为 TensorFlow.js,因此可实现本地运行:


// Load Select Subject modelconst model = await tf.loadGraphModel('select_subject.json');// Run inference on image tensor const {mask, background} = model.execute(imgTensor);// Refine selection from mask
复制代码


Adobe 还与谷歌合作为 Emscripten 开发了代理 API,希望借此解决 Photoshop 中 WebAssembly 代码与 TensforFlow.js 之间的同步问题,并由此实现了框架间的无缝集成。


“由于谷歌团队通过各种受支持的后端(WebGL、WASM、Web GPU)提高了 TensorFlow.js 的硬件执行性能,模型性能实现了 30% 至 200% 的提升(模型体量越大,性能收益越高),并在浏览器端实现了近实时性能。”


关键模型也进行了优化,重点关注 Conv2D 等重视性能的操作类型。Photoshop 还可根据性能需求,选择在本地设备还是云端运行模型。


关于更多详细信息,请参阅 TensorFlow.js Photoshop 说明文章:


https://blog.tensorflow.org/2023/03/how-adobe-used-web-ml-with-tensorflowjs-to-enhance-photoshop-for-web.html。


Web 版 Photoshop 的未来规划


Photoshop Web 版的发布代表着一个巨大的里程碑,同时也是通往无穷可能性与全新世界的第一步。


Photoshop 将继续在 Web 端不断开拓,随着浏览器供应商对标准和性能的增强而逐步提升,并陆续发布更多功能选项。Photoshop Web 版仅仅只是开始,Adobe 后续计划在 Web 上积极构建完整的 Creative Cloud 套件,立足浏览器解锁更多更为复杂的设计类应用。


Adobe 还将与浏览器工程师们密切合作,共同推进标准和性能的提升,协力将 Web 打造成真正的独立平台,为各类雄心勃勃的用例提供支持。更多激动人心的时刻,就在前方!


原文链接:


https://medium.com/@addyosmani/photoshop-is-now-on-the-web-38d70954365a


相关阅读:


WebAssembly 的核心语言特性与未来发展

Photoshop 崩溃怎么办无法打开 Photoshop

Java 极客眼中的 WebAssembly

Photoshop 2023 如何切换语言?

2023-10-30 09:473435

评论

发布
暂无评论
发现更多内容

【虚拟机专栏】智能合约执行引擎的前世今生

趣链科技

传统到敏捷的转型中,谁更适合做Scrum Master?

华为云开发者联盟

Scrum 敏捷 团队 项目经理 Scrum Master

NameServer 核心原理解析

leonsh

RocketMQ 消息队列 NameServer

Java NIO在接口自动化中应用

FunTester

Java nio 接口测试 测试开发

多样数字人民币钱包来袭,阻力与动力并存

CECBC

来了!《中国移动2021智能硬件质量报告》正式发布

在?进来看看新一季周边到底做点啥?【话题讨论】

气气

话题讨论

🏆「作者推荐」Java技术专题-JDK/JVM的新储君—GraalVM和Quarkus

洛神灬殇

Java JVM GraalVM 8月日更

6种常用Bean拷贝工具一览

码农参上

8月日更 对象拷贝

protocol buffer的高效编码方式

程序那些事

Java protobuf 程序那些事

区块链+物联网设备,能产生什么反应?

CECBC

带你梳理Jetty自定义ProxyServlet实现反向代理服务

华为云开发者联盟

容器 k8s jetty Servlet引擎 ProxyServlet

从lowcode看下一代前端应用框架

百度Geek说

大前端 lowcode

KubeCube开源:魔方六面,降阶Kubernetes落地应用

网易数帆

开源 Kubernetes 容器 KubeCube

国产接口调试工具ApiPost中的内置变量

Proud lion

大前端 测试 后端 Postman 开发工具

使用mock.js给前端生成需要的数据

与风逐梦

大前端 后端 开发工具

Golang:再谈生产者消费者模型

Regan Yue

协程 Go 语言 8月日更

Android模块化开发实践

vivo互联网技术

android 架构 开发 项目实战 模块

最小二乘法,了解一下?

华为云开发者联盟

数据 数据处理 计算 最小二乘法 数学工具

Go- 函数参数和返回值

HelloBug

函数 参数 返回值 Go 语言

打造数字人民币的大运应用场景

CECBC

一分钟学会使用ApiPost中的全局参数和目录参数

CodeNongXiaoW

大前端 测试 后端 接口工具

web技术分析| 一篇前端图像处理秘籍

anyRTC开发者

大前端 音视频 WebRTC web技术分享

GraphQL设计思想

Ryan Zheng

graphql

后Kubernetes时代的虚拟机管理技术之kubevirt篇

谐云

虚拟机 #Kubernetes#

零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能

JackJiang

音视频 WebRTC 即时通讯 IM

模块一作业

小智

架构实战营

没有7年经验你真学不会这份SpringCloud实战演练文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

以区块链为基础 通证经济是下一代互联网的数字经济

CECBC

带头撸抽奖系统,DDD + RPC 开发分布式架构!

小傅哥

DDD 小傅哥 架构设计 springboot 抽奖系统

云小课 | 详解华为云独享型负载均衡如何计费

华为云开发者联盟

负载均衡 华为云 弹性负载均衡 独享型ELB实例 独享型负载均衡

前端“秀肌肉”,云端 Photoshop 亮相_工程化_InfoQ精选文章