SQLite Wasm trong trình duyệt, được hỗ trợ bởi Hệ thống tệp riêng tư theo nguồn gốc

Sử dụng SQLite để xử lý hiệu quả mọi nhu cầu về bộ nhớ trên web.

SQLite là một hệ thống quản lý cơ sở dữ liệu quan hệ nguồn mở, nhẹ, được nhúng và phổ biến. Nhiều nhà phát triển sử dụng thư viện này để lưu trữ dữ liệu theo cách có cấu trúc, dễ sử dụng. Do kích thước nhỏ và yêu cầu bộ nhớ thấp, SQLite thường được tận dụng làm công cụ cơ sở dữ liệu trong các thiết bị di động, ứng dụng máy tính và trình duyệt web.

Một trong những tính năng chính của SQLite là đây là cơ sở dữ liệu không có máy chủ, nghĩa là không yêu cầu quy trình máy chủ riêng để hoạt động. Thay vào đó, cơ sở dữ liệu được lưu trữ trong một tệp trên thiết bị của người dùng, giúp dễ dàng tích hợp vào các ứng dụng.

Biểu trưng SQLite.

SQLite dựa trên Web Assembly

Có một số phiên bản SQLite không chính thức dựa trên Web Assembly (Wasm), cho phép sử dụng trong trình duyệt web, chẳng hạn như sql.js. Dự án phụ sqlite3 WASM/JS là nỗ lực đầu tiên được liên kết chính thức với dự án SQLite, tạo các bản dựng Wasm của thư viện đã thành lập các thành viên trong nhóm các sản phẩm SQLite được hỗ trợ. Các mục tiêu cụ thể của dự án này bao gồm:

  • Liên kết một API sqlite3 cấp thấp gần với API C nhất có thể về mặt sử dụng.
  • Một API hướng đối tượng cấp cao hơn, tương tự như sql.jscác phương thức triển khai kiểu Node.js, giao tiếp trực tiếp với API cấp thấp. Bạn phải sử dụng API này từ cùng một luồng với API cấp thấp.
  • Một API dựa trên Worker giao tiếp với các API trước đó thông qua thông báo Worker. Lớp này được dùng trong luồng chính, với các API cấp thấp hơn được cài đặt trong luồng Worker và giao tiếp với các API đó thông qua thông báo Worker.
  • Một biến thể dựa trên Lời hứa của Worker API giúp ẩn hoàn toàn các khía cạnh giao tiếp giữa luồng khỏi người dùng.
  • Hỗ trợ bộ nhớ phía máy khách ổn định bằng các API JavaScript hiện có, bao gồm cả Hệ thống tệp riêng tư gốc (OPFS).

Sử dụng SQLite Wasm với phần phụ trợ lưu trữ hệ thống tệp riêng tư của Origin

Cài đặt thư viện từ npm

Cài đặt gói @sqlite.org/sqlite-wasm từ npm bằng lệnh sau:

npm install @sqlite.org/sqlite-wasm

Hệ thống tệp riêng tư của Origin

Hệ thống tệp riêng tư gốc (OPFS, một phần của API truy cập hệ thống tệp) được tăng cường bằng một giao diện đặc biệt mang lại quyền truy cập hiệu quả cao vào dữ liệu. Nền tảng mới này khác với các nền tảng hiện có ở chỗ cung cấp quyền ghi tại chỗ và độc quyền vào nội dung của tệp. Thay đổi này, cùng với khả năng đọc nhất quán các nội dung sửa đổi chưa được làm mới và khả năng có một biến thể đồng bộ trên các worker chuyên dụng, giúp cải thiện đáng kể hiệu suất và bỏ chặn các trường hợp sử dụng mới.

Như bạn có thể tưởng tượng, điểm cuối cùng trong các mục tiêu của dự án, Hỗ trợ bộ nhớ phía máy khách ổn định bằng cách sử dụng các API JavaScript hiện có, đi kèm với các yêu cầu nghiêm ngặt về hiệu suất liên quan đến việc lưu trữ dữ liệu vào tệp cơ sở dữ liệu. Đây là nơi Hệ thống tệp riêng tư của nguồn gốc và cụ thể hơn là phương thức createSyncAccessHandle() của các đối tượng FileSystemFileHandle phát huy tác dụng. Phương thức này trả về một Lời hứa phân giải thành đối tượng FileSystemSyncAccessHandle có thể dùng để đồng bộ đọc và ghi vào tệp. Tính chất đồng bộ của phương thức này mang lại lợi thế về hiệu suất, nhưng do đó, bạn chỉ có thể sử dụng phương thức này bên trong Trình chạy web chuyên dụng cho các tệp trong Hệ thống tệp riêng tư của nguồn gốc để không thể chặn luồng chính.

Đặt các tiêu đề bắt buộc

Trong số các tệp khác, tệp lưu trữ SQLite Wasm đã tải xuống chứa các tệp sqlite3.jssqlite3.wasm, tạo nên bản dựng sqlite3 WASM/JS. Thư mục jswasm chứa các sản phẩm chính của sqlite3 và thư mục cấp cao nhất chứa các ứng dụng minh hoạ và kiểm thử. Trình duyệt sẽ không phân phát tệp Wasm từ các URL file://, vì vậy, mọi ứng dụng bạn tạo bằng cách này đều yêu cầu một máy chủ web và máy chủ đó phải đưa các tiêu đề sau vào phản hồi khi phân phát tệp:

  • Cross-Origin-Opener-Policy được đặt thành lệnh same-origin, giúp tách riêng ngữ cảnh duyệt web chỉ dành cho các tài liệu có cùng nguồn gốc. Tài liệu trên nhiều nguồn gốc không được tải trong cùng một ngữ cảnh duyệt web.
  • Cross-Origin-Embedder-Policy được đặt thành lệnh require-corp, vì vậy, một tài liệu chỉ có thể tải tài nguyên từ cùng một nguồn gốc hoặc tài nguyên được đánh dấu rõ ràng là có thể tải từ một nguồn gốc khác.

Lý do cho các tiêu đề này là SQLite Wasm phụ thuộc vào SharedArrayBuffer và việc đặt các tiêu đề này là một phần của các yêu cầu bảo mật.

Nếu kiểm tra lưu lượng truy cập bằng Công cụ cho nhà phát triển, bạn sẽ thấy các thông tin sau:

Hai tiêu đề được đề cập ở trên, Cross-Origin-Embedder-Policy và Cross-Origin-Opener-Policy, được làm nổi bật trong Công cụ của Chrome cho nhà phát triển.

Speedtest

Nhóm SQLite đã chạy một số phép đo điểm chuẩn về việc triển khai WebAssembly so với Web SQL không còn được dùng nữa. Các điểm chuẩn này cho thấy SQLite Wasm thường nhanh như Web SQL. Đôi khi chậm hơn một chút, đôi khi nhanh hơn một chút. Xem tất cả thông tin chi tiết trên trang kết quả.

Mã mẫu để bắt đầu

Như đã đề cập trước đó, SQLite Wasm với phần phụ trợ lưu trữ hệ thống tệp riêng tư của Origin cần chạy trong ngữ cảnh Worker. Tin vui là thư viện sẽ tự động xử lý tất cả những việc này cho bạn và bạn có thể sử dụng thư viện ngay từ luồng chính.

import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';

(async () => {
  try {
    console.log('Loading and initializing SQLite3 module...');

    const promiser = await new Promise((resolve) => {
      const _promiser = sqlite3Worker1Promiser({
        onready: () => {
          resolve(_promiser);
        },
      });
    });

    console.log('Done initializing. Running demo...');

    let response;

    response = await promiser('config-get', {});
    console.log('Running SQLite3 version', response.result.version.libVersion);

    response = await promiser('open', {
      filename: 'file:worker-promiser.sqlite3?vfs=opfs',
    });
    const { dbId } = response;
    console.log(
      'OPFS is available, created persisted database at',
      response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
    );

    await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
    console.log('Creating a table...');

    console.log('Insert some data using exec()...');
    for (let i = 20; i <= 25; ++i) {
      await promiser('exec', {
        dbId,
        sql: 'INSERT INTO t(a,b) VALUES (?,?)',
        bind: [i, i * 2],
      });
    }

    console.log('Query data with exec()');
    await promiser('exec', {
      dbId,
      sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
      callback: (result) => {
        if (!result.row) {
          return;
        }
        console.log(result.row);
      },
    });

    await promiser('close', { dbId });
  } catch (err) {
    if (!(err instanceof Error)) {
      err = new Error(err.result.message);
    }
    console.error(err.name, err.message);
  }
})();

Bản minh hoạ

Xem mã trên trong bản minh hoạ. Hãy nhớ xem mã nguồn trên Glitch. Lưu ý cách phiên bản nhúng bên dưới không sử dụng phần phụ trợ OPFS, nhưng khi bạn mở bản minh hoạ trong một thẻ riêng, thì phiên bản này sẽ sử dụng.

Gỡ lỗi Hệ thống tệp riêng tư của Origin

Để gỡ lỗi đầu ra Hệ thống tệp riêng của nguồn gốc SQLite Wasm, hãy sử dụng tiện ích Chrome OPFS Explorer.

Trình khám phá OPFS trong Cửa hàng Chrome trực tuyến.

Sau khi cài đặt tiện ích, hãy mở Công cụ của Chrome cho nhà phát triển, chọn thẻ Trình khám phá OPFS, sau đó bạn có thể kiểm tra nội dung mà SQLite Wasm ghi vào Hệ thống tệp riêng của nguồn gốc.

Tiện ích Chrome của OPFS Explorer hiển thị cấu trúc Hệ thống tệp riêng tư của Origin của ứng dụng minh hoạ.

Nếu chọn bất kỳ tệp nào trong cửa sổ Trình khám phá OPFS trong DevTools, bạn có thể lưu tệp đó vào ổ đĩa cục bộ. Sau đó, bạn có thể sử dụng một ứng dụng như SQLite Viewer để kiểm tra cơ sở dữ liệu, nhờ đó bạn có thể tự tin rằng SQLite Wasm thực sự hoạt động như đã hứa.

Ứng dụng SQLite Viewer dùng để mở tệp cơ sở dữ liệu từ bản minh hoạ SQLite Wasm.

Yêu cầu trợ giúp và đưa ra ý kiến phản hồi

SQLite Wasm do cộng đồng SQLite phát triển và duy trì. Hãy tìm sự trợ giúp và đưa ra ý kiến phản hồi bằng cách tìm kiếm và đăng trên diễn đàn hỗ trợ. Bạn có thể xem tài liệu đầy đủ trên trang web SQLite.