Notion是一个多功能工具,用于笔记、文档、项目管理等,具有出色的协作功能和美观的用户界面。尽管拥有超过3000万用户,其中400万是付费用户,但Notion的一个常见批评是它在使用时感觉较慢,尤其是在页面间导航时。
是什么导致 Notion 运行缓慢?
- 第三方脚本依赖:Notion 依赖于许多第三方脚本。可能用于协作功能、分析和图像等第三方资产。
- 频繁的API调用:频繁对 Notion 服务器进行 API 调用。这是因为浏览器中没有缓存或缓存非常有限。
- 未充分利用CPU核心:CPU 核心未用于处理任务。大多数人拥有4 到 8 个核心,这意味着可以同时处理 4 到 8 个任务。Notion 没有利用这一点。
尝试的解决方案:
- LocalStorage: 团队使用LocalStorage在浏览器中缓存数据,但存储空间有限,对拥有大量页面的用户不利。
- IndexedDB: 尝试使用IndexedDB进行缓存,但并未发布,因为它没有提高性能,在某些设备上甚至比LocalStorage更慢。
SQLite的使用:
- 桌面和移动应用: 通过使用SQLite数据库缓存数据,团队提高了桌面和移动应用的性能,因此决定在浏览器中尝试使用SQLite。
- WebAssembly: SQLite是一个数据库,使用SQL作为查询语言,与MySQL和Postgres类似,但它将所有数据存储在一个文件中,没有服务器。SQLite不是浏览器原生支持的,但它有WebAssembly版本,允许在浏览器中运行非JavaScript语言编写的代码。
SQLite 为何有效
SQLite 是一个类似MySQL和Postgres 的数据库,使用SQL作为其查询语言。但它与它们不同,因为它将所有数据保存在一个文件中,并且没有服务器。
数据库倾向于使用服务器来管理数据访问、防止冲突和控制用户权限。与其他数据库相比,缺少服务器限制了 SQLite。但它非常适合 Notion 的缓存需求。
浏览器本身并不支持 SQLite。但它有一个WebAssembly版本。
- WebAssembly 允许您在浏览器中运行用 JavaScript 以外的语言编写的代码。如果我用C++编写了一个非常快速复杂的计算并想在浏览器中运行它。我不需要用JavaScript 重写它,而是可以保留 C++ 代码,将其编译为WebAssembly ,然后在浏览器中运行它。
- 由于 SQLite 是用C编写的,因此可以将其编译成 WebAssembly。
- 但用户必须下载整个 SQLite才能使用。
不幸的是,Notion 不能直接将 SQLite 放入他们的项目中然后就完事了。他们必须先进行大量更改。
SQLite 的问题
除了 WebAssembly 之外,SQLite 还使用一些其他 Web 技术。
- 它使用Web Worker来处理数据库的读写。允许代码在后台运行,不会阻塞主站点操作。
- SQLite 文件存储在Origin 私有文件系统(OPFS) 中。如果一个选项卡正在读取或写入文件,它会将文件锁定到该选项卡,这意味着其他选项卡所做的更改将不起作用。
为了解决这个问题,Notion 创建了一个系统,其中其他选项卡所做的更改将发送给有权访问数据库文件的单个工作人员。这就是Active Worker 。
- 创建SharedWorker来确定哪个选项卡将拥有活跃的工作者
- 如果活动 worker 选项卡已关闭,SharedWorker 将使另一个 web worker 处于活动状态。
SQLite可以以两种方式与OPFS虚拟文件系统交互
- OPFS sqlite3_vfs:确实支持在多个选项卡上运行。但仅适用于跨域隔离。跨域隔离将浏览器置于“保护气泡”中,从而为其提供额外的安全性。但这限制了它与其他网站共享数据,这对 Notion 不起作用,因为它们依赖于第三方脚本。
- OPFS SyncAccessHandle Pool VFS:Notion选择了OPFS SyncAccessHandle Pool VFS,因为它在所有主流浏览器中都受支持,并且性能略优于sqlite3_vfs。
下载问题
团队在采用这种方法时遇到的另一个问题是,页面最初加载速度较慢。
这是因为如果用户没有SQLite,则必须下载它。它并不大,不到 1 MB。但在较慢的连接上,这一点很明显。
为了解决这个问题,团队改变了 SQLite 的加载方式。他们不再将 SQLite 与网站一起加载,而是等到页面加载完成后再下载 SQLite 。
这意味着初始页面数据并非来自缓存。但使用 SQLite 加载初始数据所带来的轻微速度提升并不值得付出如此复杂的代价。
总体来说,在浏览器中迁移到 SQLite 是成功的。
世界某些地区的 Notion 网站页面导航速度提升了 33% 。
性能提升:
- 页面加载速度: 由于用户需要下载SQLite,页面加载速度最初会较慢。为了解决这个问题,团队改变了SQLite的加载方式,等待页面加载完成后再下载SQLite。
- 速度提升: 在世界某些地区的Notion网站在页面间导航时速度提高了33%。