Skip to content

Commit

Permalink
Merge pull request #266 from powersync-ja/fix-web-performance
Browse files Browse the repository at this point in the history
[web] debounce update notifications
  • Loading branch information
rkistner authored Aug 14, 2024
2 parents a2fa493 + 2db0e8f commit f2ebd02
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-feet-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@powersync/web': patch
---

Debounce update notifications to fix performance issue with large amounts of data synced
8 changes: 4 additions & 4 deletions packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ export class WASQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement

this.methods = await dbOpener(this.options.dbFilename);
this.methods.registerOnTableChange(
Comlink.proxy((opType: number, tableName: string, rowId: number) => {
this.iterateListeners((cb) => cb.tablesUpdated?.({ opType, table: tableName, rowId }));
Comlink.proxy((event) => {
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
})
);

return;
}
this.methods = await _openDB(this.options.dbFilename, { useWebWorker: false });
this.methods.registerOnTableChange((opType: number, tableName: string, rowId: number) => {
this.iterateListeners((cb) => cb.tablesUpdated?.({ opType, table: tableName, rowId }));
this.methods.registerOnTableChange((event) => {
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
});
}

Expand Down
16 changes: 15 additions & 1 deletion packages/web/src/shared/open-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '@journeyapps/wa-sqlite';
import * as Comlink from 'comlink';
import type { DBFunctionsInterface, OnTableChangeCallback, WASQLExecuteResult } from './types';
import { Mutex } from 'async-mutex';
import { BatchedUpdateNotification } from '@powersync/common';

let nextId = 1;

Expand All @@ -26,8 +27,21 @@ export async function _openDB(
*/
const listeners = new Map<number, OnTableChangeCallback>();

let updatedTables = new Set<string>();
let updateTimer: any = null;

function fireUpdates() {
updateTimer = null;
const event: BatchedUpdateNotification = { tables: [...updatedTables], groupedUpdates: {}, rawUpdates: [] };
updatedTables.clear();
Array.from(listeners.values()).forEach((l) => l(event));
}

sqlite3.register_table_onchange_hook(db, (opType: number, tableName: string, rowId: number) => {
Array.from(listeners.values()).forEach((l) => l(opType, tableName, rowId));
updatedTables.add(tableName);
if (updateTimer == null) {
updateTimer = setTimeout(fireUpdates, 0);
}
});

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/shared/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { QueryResult } from '@powersync/common';
import type { BatchedUpdateNotification, QueryResult } from '@powersync/common';

export type WASQLExecuteResult = Omit<QueryResult, 'rows'> & {
rows: {
Expand All @@ -22,7 +22,7 @@ export type DBWorkerInterface = DBFunctionsInterface;

export type WASQLiteExecuteMethod = (sql: string, params?: any[]) => Promise<WASQLExecuteResult>;
export type WASQLiteExecuteBatchMethod = (sql: string, params?: any[]) => Promise<WASQLExecuteResult>;
export type OnTableChangeCallback = (opType: number, tableName: string, rowId: number) => void;
export type OnTableChangeCallback = (event: BatchedUpdateNotification) => void;
export type OpenDB = (dbFileName: string) => DBWorkerInterface;

export type SQLBatchTuple = [string] | [string, Array<any> | Array<Array<any>>];

0 comments on commit f2ebd02

Please sign in to comment.