Merge pull request #13820 from atom/mb-ns-long-lines

Avoid hangs when opening minified files
This commit is contained in:
Max Brunsfeld 2017-02-15 13:54:16 -08:00 committed by GitHub
commit 4a3c92f689
4 changed files with 104 additions and 2 deletions

View File

@ -26,7 +26,7 @@ export default async function ({test}) {
console.log(text.length / 1024)
let t0 = window.performance.now()
const buffer = new TextBuffer(text)
const buffer = new TextBuffer({text})
const editor = new TextEditor({buffer, largeFileMode: true})
atom.workspace.getActivePane().activateItem(editor)
let t1 = window.performance.now()

View File

@ -0,0 +1,97 @@
/** @babel */
import path from 'path'
import fs from 'fs'
import {TextEditor, TextBuffer} from 'atom'
const SIZES_IN_KB = [
512,
1024,
2048
]
const REPEATED_TEXT = fs.readFileSync(path.join(__dirname, '..', 'spec', 'fixtures', 'sample.js'), 'utf8').replace(/\n/g, '')
const TEXT = REPEATED_TEXT.repeat(Math.ceil(SIZES_IN_KB[SIZES_IN_KB.length - 1] * 1024 / REPEATED_TEXT.length))
export default async function ({test}) {
const data = []
const workspaceElement = atom.views.getView(atom.workspace)
document.body.appendChild(workspaceElement)
atom.packages.loadPackages()
await atom.packages.activate()
console.log(atom.getLoadSettings().resourcePath);
for (let pane of atom.workspace.getPanes()) {
pane.destroy()
}
for (const sizeInKB of SIZES_IN_KB) {
const text = TEXT.slice(0, sizeInKB * 1024)
console.log(text.length / 1024)
let t0 = window.performance.now()
const buffer = new TextBuffer({text})
const editor = new TextEditor({buffer, largeFileMode: true})
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
atom.workspace.getActivePane().activateItem(editor)
let t1 = window.performance.now()
data.push({
name: 'Opening a large single-line file',
x: sizeInKB,
duration: t1 - t0
})
const tickDurations = []
for (let i = 0; i < 20; i++) {
await timeout(50)
t0 = window.performance.now()
await timeout(0)
t1 = window.performance.now()
tickDurations[i] = t1 - t0
}
data.push({
name: 'Max time event loop was blocked after opening a large single-line file',
x: sizeInKB,
duration: Math.max(...tickDurations)
})
t0 = window.performance.now()
editor.setCursorScreenPosition(editor.element.screenPositionForPixelPosition({
top: 100,
left: 30
}))
t1 = window.performance.now()
data.push({
name: 'Clicking the editor after opening a large single-line file',
x: sizeInKB,
duration: t1 - t0
})
t0 = window.performance.now()
editor.element.setScrollTop(editor.element.getScrollTop() + 100)
t1 = window.performance.now()
data.push({
name: 'Scrolling down after opening a large single-line file',
x: sizeInKB,
duration: t1 - t0
})
editor.destroy()
buffer.destroy()
await timeout(10000)
}
workspaceElement.remove()
return data
}
function timeout (duration) {
return new Promise((resolve) => setTimeout(resolve, duration))
}

View File

@ -16,6 +16,7 @@ TextEditorElement = require './text-editor-element'
{isDoubleWidthCharacter, isHalfWidthCharacter, isKoreanCharacter, isWrapBoundary} = require './text-utils'
ZERO_WIDTH_NBSP = '\ufeff'
MAX_SCREEN_LINE_LENGTH = 500
# Essential: This class represents all essential editing state for a single
# {TextBuffer}, including cursor and selection positions, folds, and soft wraps.
@ -2964,7 +2965,7 @@ class TextEditor extends Model
else
@getEditorWidthInChars()
else
Infinity
MAX_SCREEN_LINE_LENGTH
###
Section: Indentation

View File

@ -8,6 +8,8 @@ ScopeDescriptor = require './scope-descriptor'
TokenizedBufferIterator = require './tokenized-buffer-iterator'
NullGrammar = require './null-grammar'
MAX_LINE_LENGTH_TO_TOKENIZE = 500
module.exports =
class TokenizedBuffer extends Model
grammar: null
@ -251,6 +253,8 @@ class TokenizedBuffer extends Model
buildTokenizedLineForRowWithText: (row, text, ruleStack = @stackForRow(row - 1), openScopes = @openScopesForRow(row)) ->
lineEnding = @buffer.lineEndingForRow(row)
if text.length > MAX_LINE_LENGTH_TO_TOKENIZE
text = text.slice(0, MAX_LINE_LENGTH_TO_TOKENIZE)
{tags, ruleStack} = @grammar.tokenizeLine(text, ruleStack, row is 0, false)
new TokenizedLine({openScopes, text, tags, ruleStack, lineEnding, @tokenIterator})