在前端使用C++意味着什么?
我一直在开发一个基于浏览器的图像编辑器,使用的是C++语言。当我告诉我的朋友们这个项目时,他们最常见的反应是“哈???”和“为什么???”……让我们来详细解释一下。
首先:等等,C++是如何在浏览器中运行的?
我并不是简单地将原始C++代码放入浏览器标签中。浏览器只懂两种语言:JavaScript和WebAssembly。WebAssembly(WASM)是一种在浏览器中解释的字节码语言。关键在于编写C++函数,并使用Emscripten将其编译为WASM。JavaScript仍然控制着DOM,因此WASM并不能做所有事情——你需要从JavaScript中调用C++函数。
如果JavaScript和WASM需要协同工作,它们就需要一种通信和数据传输的方式!为此,JavaScript分配共享缓冲区,将数据写入其中,然后通过ccall调用C++。C++函数处理数据后,将控制权返回给JavaScript,后者可以从共享缓冲区读取数据。
C++编译器通常会通过编码额外信息(如参数类型)来改变函数名称,以支持函数重载等特性并防止命名冲突。为了使C++函数可以被JavaScript访问,我使用了“extern C”指令,这告诉编译器保留原始函数名称并禁用名称改变。
是的,如果你管理内存分配不当或忘记释放,可能会导致浏览器应用程序出现未定义的行为。
其次:为什么要经历这些麻烦?
图像编辑——尤其是实时滤镜、频繁的画布更新以及支持数十(甚至数百)层——计算量很大。仅靠JavaScript可能无法跟上,特别是在你追求高性能和流畅用户体验时。
为什么?因为JavaScript是一种解释性语言——它在运行时逐行读取和执行,这会增加开销。而WebAssembly则是一种更底层的字节码。当你将C++编译为WASM时,你可以享受到LLVM编译器优化的好处,以及Web的可移植性。
所以,尽管WASM在技术上仍然是解释性的,但它更接近机器代码,并以接近本地速度运行。这意味着复杂的图像处理操作——如应用自定义滤镜或合并高分辨率层——可以快速完成,而不会导致浏览器卡顿或掉帧。最终结果是?一个感觉像本地桌面应用程序的前端,但却在你的浏览器中运行。
对于任何感兴趣的人,这里是GitHub仓库! https://github.com/alicehe2003/ImageEditor
这个项目的灵感来自于Figma的构建方式!
https://www.linkedin.com/posts/alice-he-95406b293_github-alicehe2003imageeditor-web-based-activity-7340407818077859842-r3FK?utm_source=share&utm_medium=member_desktop&rcm=ACoAAEcFpZABjEOydMovU7l8KMPjazq9tzhE9Rc
查看原文
I’ve been working on a browser-based image editor written in C++, and when I tell my friends about it, the most common reactions I get are “Huh???” and “Why???” ...Let’s break it down.<p>First: Wait, how does C++ run in the browser?
I’m not just tossing raw C++ into a browser tab. The browser only knows how to speak 2 languages: JavaScript and WebAssembly. WebAssembly (WASM) is a bytecode language that is interpreted in the browser. The trick is to write C++ functions and compile them to WASM using Emscripten. Javascript still controls the DOM, so WASM can’t do everything - you’ll have to call the C++ functions from JavaScript.<p>If Javascript and WASM need to work together, they’ll need a way to communicate and transfer data! To do this, JS allocates shared buffers, writes data into it, then calls into C++ using ccall. The C++ function processes the data and returns control to JS, which can then read from the shared buffers.<p>C++ compilers typically mangle function names by encoding additional information—like parameter types—to support features like function overloading and prevent naming conflicts. To make C++ functions accessible from JavaScript, I used “extern C”, a directive that tells the compiler to preserve the original function names and disable name mangling.<p>And yes, if you mismanage memory allocation or forget to free, you can cause undefined behaviours your browser app<p>Second: Why go through all this trouble?
Image editing—especially with real-time filters, frequent canvas updates, and support for dozens (or even hundreds) of layers—is computationally heavy. JavaScript alone may not keep up, especially when you're pushing for high performance and smooth UX.<p>Why? Because JavaScript is an interpreted language—it’s read and executed line by line at runtime, which adds overhead. WebAssembly, on the other hand, is a lower-level bytecode. When you compile C++ to WASM, you get the benefits of LLVM's compiler optimizations along with the portability of the web.<p>So even though WASM is still technically interpreted, it's much closer to machine code and runs at near-native speed. That means complex image processing operations—like applying custom filters or merging high-resolution layers—can happen fast, without freezing the browser or dropping frames. The end result? A frontend that feels like a native desktop app, but runs in your browser.<p>For anyone who's interested, here's the GitHub repo! https://github.com/alicehe2003/ImageEditor<p>This project was inspired by how Figma is built!<p>https://www.linkedin.com/posts/alice-he-95406b293_github-alicehe2003imageeditor-web-based-activity-7340407818077859842-r3FK?utm_source=share&utm_medium=member_desktop&rcm=ACoAAEcFpZABjEOydMovU7l8KMPjazq9tzhE9Rc