Bird
Raised Fist0
Denoframework~8 mins

SQLite for embedded use in Deno - Performance & Optimization

Choose your learning style10 modes available
Performance: SQLite for embedded use
MEDIUM IMPACT
This affects page load speed and interaction responsiveness by how quickly data can be read and written locally without network delays.
Accessing and updating local data in a Deno app using SQLite
Deno
const db = new DB();
// Use a worker thread or asynchronous API to run queries
// Example using a worker thread or Deno subprocess
const process = Deno.run({ cmd: ["sqlite3", "db.sqlite", "SELECT * FROM large_table"] });
await process.status();
process.close();
Running queries asynchronously or off the main thread prevents blocking UI and improves responsiveness.
📈 Performance Gainreduces main thread blocking to near zero, improving INP significantly
Accessing and updating local data in a Deno app using SQLite
Deno
const db = new DB();
db.query("SELECT * FROM large_table"); // runs on main thread synchronously
// heavy queries block UI and delay interaction
Running large or complex SQLite queries synchronously blocks the main thread, causing slow UI response and poor user experience.
📉 Performance Costblocks main thread for 100+ ms on large queries, causing input delay
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Synchronous SQLite queries on main threadMinimal0Low but blocks JS execution[X] Bad
Asynchronous SQLite queries or worker threadsMinimal0Low and non-blocking[OK] Good
Rendering Pipeline
SQLite queries run on the main thread can block JavaScript execution, delaying style calculation and layout updates, which hurts interaction responsiveness.
→JavaScript Execution
→Style Calculation
→Layout
→Paint
⚠️ BottleneckJavaScript Execution blocking due to synchronous DB queries
Core Web Vital Affected
INP
This affects page load speed and interaction responsiveness by how quickly data can be read and written locally without network delays.
Optimization Tips
1Avoid running large SQLite queries synchronously on the main thread.
2Use asynchronous APIs or worker threads to run SQLite queries.
3Monitor main thread blocking in DevTools Performance panel to catch slow queries.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance risk of running SQLite queries synchronously in a Deno app?
AIncreasing network latency
BCausing layout shifts
CBlocking the main thread and causing input delays
DIncreasing bundle size
DevTools: Performance
How to check: Record a performance profile while running SQLite queries and look for long tasks blocking the main thread.
What to look for: Look for long JavaScript execution blocks causing input delay and frame drops.

Practice

(1/5)
1. What is the main advantage of using SQLite in a Deno application?
easy
A. It stores data in a simple file without needing a separate server.
B. It requires a complex setup with multiple servers.
C. It only works with large-scale distributed systems.
D. It cannot be used for local data storage.

Solution

  1. Step 1: Understand SQLite's design

    SQLite is designed as a lightweight, file-based database that does not require a separate server.
  2. Step 2: Compare options

    Claims of needing servers, complex setups, or only working with distributed systems are incorrect for SQLite, which is simple and local.
  3. Final Answer:

    It stores data in a simple file without needing a separate server. -> Option A
  4. Quick Check:

    SQLite = file-based, no server needed [OK]
Hint: Remember SQLite is serverless and file-based [OK]
Common Mistakes:
  • Thinking SQLite needs a server
  • Confusing SQLite with large distributed databases
  • Assuming SQLite can't store local data
2. Which of the following is the correct way to import the SQLite module in a Deno script?
easy
A. require('sqlite');
B. import DB from "sqlite";
C. import { DB } from "https://deno.land/x/sqlite/mod.ts";
D. import * as sqlite from 'sqlite3';

Solution

  1. Step 1: Identify Deno import syntax

    Deno uses ES module imports with URLs, so the correct import includes the full URL and curly braces for named imports.
  2. Step 2: Check each option

    require() is Node.js syntax. Bare specifiers like "sqlite" omit the required URL. 'sqlite3' is a Node.js module. Only the import with URL and named import matches Deno style.
  3. Final Answer:

    import { DB } from "https://deno.land/x/sqlite/mod.ts"; -> Option C
  4. Quick Check:

    Deno imports use URLs and named imports [OK]
Hint: Deno imports modules via URLs with named imports [OK]
Common Mistakes:
  • Using Node.js require() syntax
  • Omitting the full URL in import
  • Using incorrect module names
3. Given this Deno SQLite code snippet, what will be the output?
import { DB } from "https://deno.land/x/sqlite/mod.ts";
const db = new DB();
db.query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
db.query("INSERT INTO users (name) VALUES (?)", ["Alice"]);
const result = [...db.query("SELECT name FROM users")];
console.log(result);
db.close();
medium
A. ["Alice"]
B. [["Alice"]]
C. [[1, "Alice"]]
D. []

Solution

  1. Step 1: Understand the query results format

    db.query returns an iterator of rows, each row is an array of column values. Selecting 'name' returns rows like ["Alice"].
  2. Step 2: Spread into array and log

    Using [...db.query(...)] collects rows into an array of arrays, so result is [["Alice"]].
  3. Final Answer:

    [["Alice"]] -> Option B
  4. Quick Check:

    Query returns array of rows, each row an array [OK]
Hint: Query returns array of rows, each row is an array [OK]
Common Mistakes:
  • Expecting a flat array instead of nested arrays
  • Confusing row data with column names
  • Forgetting to spread iterator into array
4. What is wrong with this Deno SQLite code snippet?
import { DB } from "https://deno.land/x/sqlite/mod.ts";
const db = new DB("mydb.sqlite");
db.query("CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT)");
db.query("INSERT INTO items (name) VALUES (?)", ["Book"]);
// Missing db.close()
medium
A. The database connection is not closed, which can cause resource leaks.
B. The table creation syntax is incorrect.
C. The INSERT statement is missing a value for id.
D. The DB constructor requires no arguments.

Solution

  1. Step 1: Check resource management

    The code opens a database but does not call db.close(), which is needed to release resources properly.
  2. Step 2: Verify SQL statements and constructor

    Table creation and insert syntax are correct; id is auto-incremented primary key; DB constructor accepts filename.
  3. Final Answer:

    The database connection is not closed, which can cause resource leaks. -> Option A
  4. Quick Check:

    Always close DB connections to avoid leaks [OK]
Hint: Always call db.close() after database work [OK]
Common Mistakes:
  • Assuming id must be provided when auto-incremented
  • Ignoring the need to close the database
  • Thinking DB constructor takes no arguments
5. You want to store user preferences in a Deno app using SQLite. Which approach correctly creates a table with a default value and inserts a new user with a custom preference?
import { DB } from "https://deno.land/x/sqlite/mod.ts";
const db = new DB();
// Which code below is correct?
hard
A. db.query("CREATE TABLE prefs (user TEXT PRIMARY KEY, theme TEXT DEFAULT 'light')"); db.query("INSERT INTO prefs (user, theme) VALUES ('Bob')");
B. db.query("CREATE TABLE prefs (user TEXT, theme TEXT)"); db.query("INSERT INTO prefs VALUES ('Bob')");
C. db.query("CREATE TABLE prefs (user TEXT PRIMARY KEY, theme TEXT DEFAULT 'light')"); db.query("INSERT INTO prefs (user) VALUES ('Bob')");
D. db.query("CREATE TABLE prefs (user TEXT PRIMARY KEY, theme TEXT DEFAULT 'light')"); db.query("INSERT INTO prefs (user, theme) VALUES (?, ?)", ["Bob", "dark"]);

Solution

  1. Step 1: Check table creation with default value

    The table must define PRIMARY KEY on user and DEFAULT 'light' on theme.
  2. Step 2: Check insert statements

    To insert with custom preference, specify both columns using placeholders and provide a custom value like 'dark' to override default. Omitting theme uses default (not custom). Mismatched VALUES without placeholders cause errors.
  3. Final Answer:

    db.query("CREATE TABLE prefs (user TEXT PRIMARY KEY, theme TEXT DEFAULT 'light')"); db.query("INSERT INTO prefs (user, theme) VALUES (?, ?)", ["Bob", "dark"]); -> Option D
  4. Quick Check:

    Use DEFAULT in table and specify values to override [OK]
Hint: Use DEFAULT in table and specify values to override [OK]
Common Mistakes:
  • Not using placeholders in INSERT statements
  • Missing PRIMARY KEY in table
  • Assuming default values override explicit inserts
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard