浏览器处理 base64 数据的速度有多快?
How fast can browsers process base64 data?

原始链接: https://lemire.me/blog/2025/11/29/how-fast-can-browsers-process-base64-data/

## Base64 编码:摘要 Base64 是一种使用 64 个字符的字母表将二进制数据转换为文本格式的方法。这对于在基于文本的环境(如 HTML 或 JavaScript)中嵌入数据,或通过基于文本的协议传输二进制文件非常有用。该过程通过将二进制数据分成 6 位段,然后将每个段映射到 Base64 字母表中的一个字符来工作。当输入不是 3 字节的倍数时,使用“=”号进行填充。 现代浏览器提供内置函数(`Uint8Array.toBase64()` 和 `Uint8Array.fromBase64()`)来实现高效的编码和解码。基准测试显示不同浏览器之间存在显著的性能差异。基于 Chromium 的浏览器(Chrome、Edge、Brave)展示了更快的编码速度(高达 19 GB/s),而 Safari 在解码方面表现出色(9.4 GB/s)。Firefox 和 Servo 显示出明显较慢的性能。 这些速度通常比典型的磁盘或网络速度更快。Chromium 浏览器中的解码速度稍慢,因为存在中间缓冲区步骤。正在进行中的改进,例如 Firefox 计划的改进,旨在进一步提高 Base64 的性能。

一篇最近发表在lemire.me上的文章探讨了网页浏览器中base64数据处理的速度,并在Hacker News上引发了讨论。文章重点介绍了一个V8 JavaScript引擎(用于Chrome和Node.js)的关键更新——一项消除了解码过程中临时缓冲区的更改,可能使解码速度*翻倍*。 讨论还涉及JavaScript中base64解码的一些特点,特别是它忽略空白字符的能力。这个看似微小的细节为在看似无害的文本中巧妙地隐藏有效载荷提供了可能性。用户分享了指向Chromium代码审查的链接,详细介绍了V8的更改,以及MDN文档,解释了空白字符的处理行为,并指出文档本身存在一个拼写错误。总而言之,该讨论展示了常见Web技术中持续的优化和令人惊讶的细微之处。
相关文章

原文

Base64 is a binary-to-text encoding scheme that converts arbitrary binary data (like images, files, or any sequence of bytes) into a safe, printable ASCII string using a 64-character alphabet (A–Z, a–z, 0–9, +, /). Browsers use it in JavaScript to embedding binary data directly in code or HTML or to transmitting binary data as text.

Browsers recently added convenient and safe functions to process base 64 functions Uint8Array.toBase64() and Uint8Array.fromBase64(). Though they are several parameters, it comes down to an encoding and a decoding function.

const b64 = Base64.toBase64(bytes);      // string          
const recovered = Base64.fromBase64(b64); // Uint8Array 

When encoding, it takes 24 bits from the input. These 24 bits are divided into four 6-bit segments, and each 6-bit value (ranging from 0 to 63) is mapped to a specific character from the Base64 alphabet: the first 26 characters are uppercase letters A-Z, the next 26 are lowercase a-z, then digits 0-9, followed by + and / as the 62nd and 63rd characters. The equals sign = is used as padding when the input length is not a multiple of 3 bytes.

How fast can they be ?

Suppose that you consumed 3 bytes and produced 4 bytes per CPU cycle. At 4.5 GHz, it would be that you would encode to base64 at 13.5 GB/s. We expect lower performance going in the other direction. When encoding, any input is valid: any binary data will do. However, when decoding, we must handle errors and skip spaces.

I wrote an in-browser benchmark. You can try it out in your favorite browser.

I decided to try it out on my Apple M4 processor, to see how fast the various browsers are. I use blocks of 64 kiB. The speed is measured with respect to the binary data.

browser encoding speed decoding speed
Safari 17 GB/s 9.4 GB/s
SigmaOS 17 GB/s 9.4 GB/s
Chrome 19 GB/s 4.6 GB/s
Edge 19 GB/s 4.6 GB/s
Brave 19 GB/s 4.6 GB/s
Servo 0.34 GB/s 0.40 GB/s
Firefox 0.34 GB/s 0.40 GB/s

Safari seems to have slightly slower encoding speed than the Chromium browsers (Chome, Edge, Brave), however it is about twice as fast at decoding. Servo and Firefox have similarly poor performance with the unexpected result of having faster decoding speed than encoding speed. I could have tried other browsers but most seem to be derivatives of Chromium or WebKit.

For context, the disk of a good laptop can sustain over 3 GB/s of read or write speed. Some high-end laptops have disks that are faster than 5 GB/s. In theory, your wifi connections might get close to 5 GB/s with Wifi 7. Some Internet providers might get close to providing similar network speeds although your Internet connection is likely several times slower.

The speeds on most browsers are faster than you might naively guess. They are faster than networks or disks.

Note. The slower decoding speed on Chromium-based browsers appears to depend on the v8 JavaScript engine which decodes the string first to a temporary buffer, before finally copying from the temporary buffer to the final destination. (See BUILTIN(Uint8ArrayFromBase64) in v8/src/builtins/builtins-typed-array.cc.)

Note. Denis Palmeiro from Mozzila let me know that upcoming changes in Firefox will speed up performance of the base64 functions. In my tests with Firefox nightly, the performance is up by about 20%.

`; modal.addEventListener('click', function(e) { if (e.target === modal) modal.close(); }); modal.querySelector('#bibtex-copy-btn').addEventListener('click', function() { const text = modal.querySelector('#bibtex-target').textContent; navigator.clipboard.writeText(text).then(() => { const origText = this.innerText; this.innerText = "Copied!"; setTimeout(() => this.innerText = origText, 1500); }); }); document.body.appendChild(modal); const style = document.createElement('style'); style.innerHTML = `dialog::backdrop { background: rgba(0, 0, 0, 0.5); }`; document.head.appendChild(style); }                         // 1. Extract the URL             const fullLinkHtml = el.dataset.fullLink;              const tempDiv = document.createElement('div');             tempDiv.innerHTML = fullLinkHtml;              const linkElement = tempDiv.querySelector('a');             const rawUrl = linkElement ? linkElement.href : '';                           // 2. Compute the current access date             const accessedDate = this.getCurrentAccessedDate();              // 3. --- NEW LOGIC: Extract ONLY the year (YYYY) ---             // Gets the full date string, e.g., "November 23, 2025"             const fullDateString = el.dataset.year;             // Use regex to find the four-digit year at the end of the string             const match = fullDateString.match(/(\d{4})$/);             const publicationYear = match ? match[0] : '????'; // e.g., '2025'                          // 4. Generate BibTeX Data with the corrected year             const safeTitle = el.dataset.title.replace(/[^a-zA-Z0-9]/g, '').substring(0, 15);             // Use the clean year for the BibKey             const bibKey = (publicationYear + safeTitle);             const content = `@misc{${bibKey},   author = {${el.dataset.author}},   title  = {${el.dataset.title}},   year   = {${publicationYear}},   url    = {${rawUrl}},   note   = {Accessed: ${accessedDate}} }`;                          // 5. Show Modal             document.getElementById('bibtex-target').textContent = content;             modal.showModal();         }     }; })();
联系我们 contact @ memedata.com