Skip to content

Commit

Permalink
Improve long page editing performance (logseq#3855)
Browse files Browse the repository at this point in the history
* Remove expensive parsing when saving files

* Add limit to page blocks query

* Don't collapse block's body to make it compatible with other tools

* Alert if there're unsaved changes when switching graphs

* DB schema migration for :block/collapsed? from it's property

Co-authored-by: Andelf <[email protected]>
  • Loading branch information
tiensonqin and andelf authored Jan 18, 2022
1 parent 6a15193 commit 6aba8c3
Show file tree
Hide file tree
Showing 28 changed files with 429 additions and 348 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ jobs:
- name: Run Playwright test
run: xvfb-run -- yarn e2e-test
env:
CI: true
DEBUG: "pw:test"

- name: Save test artifacts
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ test('create page and blocks', async ({ page }) => {
await page.waitForTimeout(500)
expect(await page.$$('.ls-block')).toHaveLength(5)

await page.waitForTimeout(500)
await page.waitForTimeout(1000)

const contentOnDisk = await fs.readFile(
path.join(graphDir, `pages/${pageTitle}.md`),
Expand Down
13 changes: 4 additions & 9 deletions e2e-tests/basic.with-diacritics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test('create page and blocks (diacritics)', async ({ page }) => {
hotkeyOpenLink = 'Meta+o'
hotkeyBack = 'Meta+['
}

const rand = randomString(20)

// diacritic opening test
Expand All @@ -22,14 +22,9 @@ test('create page and blocks (diacritics)', async ({ page }) => {
// build target Page with diacritics
await activateNewPage(page)
await page.type(':nth-match(textarea, 1)', 'Diacritic title test content')
await page.keyboard.press(hotkeyBack)

// visit target Page with diacritics (looks same but not same in Unicode)
await newBlock(page)
await page.type(':nth-match(textarea, 1)', '[[Einführung in die Allgemeine Sprachwissenschaft' + rand + ']] diacritic-block-2')
await page.keyboard.press(hotkeyOpenLink)
await lastInnerBlock(page)
expect(await page.inputValue(':nth-match(textarea, 1)')).toBe('Diacritic title test content')
await page.keyboard.press('Enter')
await page.fill(':nth-match(textarea, 1)', '[[Einführung in die Allgemeine Sprachwissenschaft' + rand + ']] diacritic-block-2')
await page.keyboard.press(hotkeyBack)

// check if diacritics are indexed
Expand All @@ -41,4 +36,4 @@ test('create page and blocks (diacritics)', async ({ page }) => {
const results = await page.$$('#ui__ac-inner .block')
expect(results.length).toEqual(3) // 2 blocks + 1 page
await page.keyboard.press("Escape")
})
})
54 changes: 27 additions & 27 deletions e2e-tests/code-editing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ test('switch code editing mode', async ({ page }) => {
await page.waitForSelector('.CodeMirror pre', { state: 'hidden' })
expect(await page.inputValue('.block-editor textarea')).toBe('```clojure\n;; comment\n\n \n(+ 1 1)\n```')

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
})


Expand All @@ -70,13 +70,13 @@ test('convert from block content to code', async ({ page }) => {
await page.press('.block-editor textarea', 'Escape')
await page.waitForSelector('.CodeMirror pre', { state: 'visible' })

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.click('.CodeMirror pre')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
expect(await page.locator('.CodeMirror-gutter-wrapper .CodeMirror-linenumber >> nth=-1').innerText()).toBe('1')

await page.press('.CodeMirror textarea', 'Escape')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)

expect(await page.inputValue('.block-editor textarea')).toBe('```\n```')

Expand Down Expand Up @@ -113,13 +113,13 @@ test('code block mixed input source', async ({ page }) => {
await createRandomPage(page)

await page.fill('.block-editor textarea', '```\n ABC\n```')
await page.waitForTimeout(100) // wait for fill
await page.waitForTimeout(500) // wait for fill
await escapeToCodeEditor(page)
await page.type('.CodeMirror textarea', ' DEF\nGHI')

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.press('.CodeMirror textarea', 'Escape')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
// NOTE: auto-indent is on
expect(await page.inputValue('.block-editor textarea')).toBe('```\n ABC DEF\n GHI\n```')
})
Expand All @@ -128,13 +128,13 @@ test('code block with text around', async ({ page }) => {
await createRandomPage(page)

await page.fill('.block-editor textarea', 'Heading\n```\n```\nFooter')
await page.waitForTimeout(100)
await page.waitForTimeout(200)
await escapeToCodeEditor(page)
await page.type('.CodeMirror textarea', 'first\n second')

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.press('.CodeMirror textarea', 'Escape')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
expect(await page.inputValue('.block-editor textarea')).toBe('Heading\n```\nfirst\n second\n```\nFooter')
})

Expand All @@ -149,31 +149,31 @@ test('multiple code block', async ({ page }) => {
await page.waitForSelector('.CodeMirror pre', { state: 'visible' })

// first
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.click('.CodeMirror pre >> nth=0')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)

await page.type('.CodeMirror textarea >> nth=0', ':key-test\n', { strict: true })
await page.waitForTimeout(500)
await page.waitForTimeout(1000)

await page.press('.CodeMirror textarea >> nth=0', 'Escape')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
expect(await page.inputValue('.block-editor textarea'))
.toBe('中文 Heading\n```clojure\n:key-test\n\n```\nMiddle 🚀\n```clojure\n```\nFooter')

// second
await page.press('.block-editor textarea', 'Escape')
await page.waitForSelector('.CodeMirror pre', { state: 'visible' })

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.click('.CodeMirror pre >> nth=1')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)

await page.type('.CodeMirror textarea >> nth=1', '\n :key-test 日本語\n', { strict: true })
await page.waitForTimeout(500)
await page.waitForTimeout(1000)

await page.press('.CodeMirror textarea >> nth=1', 'Escape')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
expect(await page.inputValue('.block-editor textarea'))
.toBe('中文 Heading\n```clojure\n:key-test\n\n```\nMiddle 🚀\n```clojure\n\n :key-test 日本語\n\n```\nFooter')
})
Expand All @@ -182,18 +182,18 @@ test('click outside to exit', async ({ page }) => {
await createRandomPage(page)

await page.fill('.block-editor textarea', 'Header ``Click``\n```\n ABC\n```')
await page.waitForTimeout(100) // wait for fill
await page.waitForTimeout(200) // wait for fill
await escapeToCodeEditor(page)
await page.type('.CodeMirror textarea', ' DEF\nGHI')

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.click('text=Click')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
// NOTE: auto-indent is on
expect(await page.inputValue('.block-editor textarea')).toBe('Header ``Click``\n```\n ABC DEF\n GHI\n```')
})

test('click lanuage label to exit #3463', async ({ page }) => {
test('click language label to exit #3463', async ({ page }) => {
await createRandomPage(page)

await page.press('.block-editor textarea', 'Enter')
Expand All @@ -204,9 +204,9 @@ test('click lanuage label to exit #3463', async ({ page }) => {
await escapeToCodeEditor(page)
await page.type('.CodeMirror textarea', '#include<iostream>')

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.click('text=cpp') // the language label
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
expect(await page.inputValue('.block-editor textarea')).toBe('```cpp\n#include<iostream>\n```')
})

Expand All @@ -227,12 +227,12 @@ test('multi properties with code', async ({ page }) => {

// first character of code
await page.click('.CodeMirror pre', { position: { x: 1, y: 5 } })
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.type('.CodeMirror textarea', '// Returns nil\n')

await page.waitForTimeout(500)
await page.waitForTimeout(1000)
await page.press('.CodeMirror textarea', 'Escape')
await page.waitForTimeout(500)
await page.waitForTimeout(1000)
expect(await page.inputValue('.block-editor textarea')).toBe(
'type:: code\n' +
'类型:: 代码\n' +
Expand Down
11 changes: 8 additions & 3 deletions e2e-tests/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ let electronApp: ElectronApplication
let context: BrowserContext
let page: Page

// NOTE: Will test against a newly opened graph
const repoName = 'Test' + randomString(6)
export const graphDir = path.resolve(__dirname, '../tmp/e2e-graph', repoName)
let repoName = randomString(10)
let testTmpDir = path.resolve(__dirname, '../tmp')

if (fs.existsSync(testTmpDir)) {
fs.rmdirSync(testTmpDir, { recursive: true })
}

export let graphDir = path.resolve(testTmpDir, "e2e-test", repoName)

// NOTE: This is a console log watcher for error logs.
const consoleLogWatcher = (msg: ConsoleMessage) => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"dev-electron-app": "gulp electron",
"release-electron": "run-s gulp:build && gulp electronMaker",
"debug-electron": "cd static/ && yarn electron:debug",
"e2e-test": "npx playwright test --reporter github",
"e2e-test": "cross-env CI=true npx playwright test --reporter github",
"run-android-release": "yarn clean && yarn release-app && rm -rf ./public/static && rm -rf ./static/js/*.map && mv static ./public && npx cap sync android && npx cap run android",
"run-ios-release": "yarn clean && yarn release-app && rm -rf ./public/static && rm -rf ./static/js/*.map && mv static ./public && npx cap sync ios && npx cap run ios",
"clean": "gulp clean",
Expand Down
9 changes: 5 additions & 4 deletions src/electron/electron/handler.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,17 @@

(defn- get-graphs-dir
[]
(let [dir (.join path (.homedir os) ".logseq" "graphs")]
(let [dir (if utils/ci?
(.resolve path js/__dirname "../tmp/graphs")
(.join path (.homedir os) ".logseq" "graphs"))]
(fs-extra/ensureDirSync dir)
dir))

(defn- get-graphs
[]
(let [dir (get-graphs-dir)
graphs-path (.join path (.homedir os) ".logseq" "graphs")]
(let [dir (get-graphs-dir)]
(->> (readdir dir)
(remove #{graphs-path})
(remove #{dir})
(map #(path/basename % ".transit"))
(map graph-name->path))))

Expand Down
5 changes: 5 additions & 0 deletions src/electron/electron/utils.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
(defonce linux? (= (.-platform js/process) "linux"))

(defonce prod? (= js/process.env.NODE_ENV "production"))

(defonce ci? (let [v js/process.env.CI]
(or (true? v)
(= v "true"))))

(defonce dev? (not prod?))
(defonce logger (js/require "electron-log"))

Expand Down
Loading

0 comments on commit 6aba8c3

Please sign in to comment.