Merge pull request #864 from ajaxorg/fix/performance
Improve performance
This commit is contained in:
commit
658c5a2bb3
6 changed files with 560 additions and 15 deletions
43
demo/requirejs+build.html
Normal file
43
demo/requirejs+build.html
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>Editor</title>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#editor {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="editor">function foo(items) {
|
||||
var i;
|
||||
for (i = 0; i < items.length; i++) {
|
||||
alert("Ace Rocks " + items[i]);
|
||||
}
|
||||
}</pre>
|
||||
|
||||
<script src="../demo/kitchen-sink/require.js"></script>
|
||||
<script src="../build/src/ace.js" charset="utf-8"></script>
|
||||
<script>
|
||||
var editor = ace.edit("editor");
|
||||
editor.setTheme("ace/theme/twilight");
|
||||
editor.session.setMode("ace/mode/javascript");
|
||||
require(["ace/requirejs/text!src/ace"], function(e){
|
||||
editor.setValue(e);
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
150
demo/scrollable-page.html
Normal file
150
demo/scrollable-page.html
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>Editor</title>
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
.ace_editor {
|
||||
position: relative !important;
|
||||
border: 1px solid lightgray;
|
||||
margin: auto;
|
||||
height: 200px;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.ace_editor.fullScreen {
|
||||
height: auto;
|
||||
width: auto;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
position: fixed !important;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.fullScreen {
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.scrollmargin {
|
||||
height: 500px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.large-button {
|
||||
color: lightblue;
|
||||
cursor: pointer;
|
||||
font: 30px arial;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
border: medium solid transparent;
|
||||
display: inline-block;
|
||||
}
|
||||
.large-button:hover {
|
||||
border: medium solid lightgray;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
box-shadow: 0 0 12px 0 lightblue;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="scrollmargin">
|
||||
<span onclick="scroll()" class="large-button">
|
||||
scroll down ⇓
|
||||
</span>
|
||||
</div>
|
||||
<pre id="editor">function foo(items) {
|
||||
var i;
|
||||
for (i = 0; i < items.length; i++) {
|
||||
alert("Ace Rocks " + items[i]);
|
||||
}
|
||||
|
||||
}</pre>
|
||||
<div class="scrollmargin">
|
||||
<div style="padding:20px">
|
||||
press F11 to switch to fullscreen mode
|
||||
</div>
|
||||
<span onclick="add()" class="large-button">
|
||||
+
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="../build/src/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
var $ = document.getElementById.bind(document);
|
||||
var dom = require("ace/lib/dom");
|
||||
|
||||
//add command to all new editor instaces
|
||||
require("ace/commands/default_commands").commands.push({
|
||||
name: "Toggle Fullscreen",
|
||||
bindKey: "F11",
|
||||
exec: function(editor) {
|
||||
dom.toggleCssClass(document.body, "fullScreen")
|
||||
dom.toggleCssClass(editor.container, "fullScreen")
|
||||
editor.resize()
|
||||
}
|
||||
})
|
||||
|
||||
// create first editor
|
||||
var editor = ace.edit("editor");
|
||||
editor.setTheme("ace/theme/twilight");
|
||||
editor.session.setMode("ace/mode/javascript");
|
||||
|
||||
|
||||
var count = 1;
|
||||
function add() {
|
||||
var oldEl = editor.container
|
||||
var pad = document.createElement("div")
|
||||
pad.style.padding = "40px"
|
||||
oldEl.parentNode.insertBefore(pad, oldEl.nextSibling)
|
||||
|
||||
var el = document.createElement("div")
|
||||
oldEl.parentNode.insertBefore(el, pad.nextSibling)
|
||||
|
||||
count++
|
||||
var theme = "ace/theme/" + themes[Math.floor(themes.length * Math.random() - 1e-5)]
|
||||
editor = ace.edit(el)
|
||||
editor.setTheme(theme)
|
||||
editor.session.setMode("ace/mode/javascript")
|
||||
|
||||
editor.setValue([
|
||||
"this is editor number: ", count, "\n",
|
||||
"using theme \"", theme, "\"\n",
|
||||
":)"
|
||||
].join(""), -1)
|
||||
|
||||
scroll()
|
||||
}
|
||||
|
||||
|
||||
function scroll(speed) {
|
||||
var top = editor.container.getBoundingClientRect().top
|
||||
speed = speed || 10
|
||||
if (top > 60 && speed < 500) {
|
||||
if (speed > top - speed - 50)
|
||||
speed = top - speed - 50
|
||||
else
|
||||
setTimeout(scroll, 10, speed + 10)
|
||||
window.scrollBy(0, speed)
|
||||
}
|
||||
}
|
||||
|
||||
var themes = {
|
||||
bright: [ "chrome", "clouds", "crimson_editor", "dawn", "dreamweaver", "eclipse", "github",
|
||||
"solarized_light", "textmate", "tomorrow"],
|
||||
dark: [ "clouds_midnight", "cobalt", "idle_fingers", "kr_theme", "merbivore", "merbivore_soft",
|
||||
"mono_industrial", "monokai", "pastel_on_dark", "solarized_dark", "tomorrow_night",
|
||||
"tomorrow_night_blue", "tomorrow_night_bright", "tomorrow_night_eighties", "twilight", "vibrant_ink"]
|
||||
}
|
||||
themes = [].concat(themes.bright, themes.dark);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -131,7 +131,6 @@
|
|||
|
||||
.ace_gutter .ace_layer {
|
||||
position: relative;
|
||||
min-width: 40px;
|
||||
width: auto;
|
||||
text-align: right;
|
||||
pointer-events: auto;
|
||||
|
|
|
|||
|
|
@ -148,17 +148,15 @@ var Gutter = function(parentEl) {
|
|||
i++;
|
||||
}
|
||||
|
||||
if (this.session.$useWrapMode)
|
||||
html.push(
|
||||
"<div class='ace_gutter-cell' style='pointer-events:none;opacity:0'>",
|
||||
this.session.getLength() - 1,
|
||||
"</div>"
|
||||
);
|
||||
|
||||
this.element = dom.setInnerHtml(this.element, html.join(""));
|
||||
this.element.style.height = config.minHeight + "px";
|
||||
|
||||
var gutterWidth = this.element.offsetWidth;
|
||||
if (this.session.$useWrapMode)
|
||||
i = this.session.getLength();
|
||||
|
||||
var gutterWidth = ("" + --i).length * config.characterWidth;
|
||||
var padding = this.$padding || this.$computePadding();
|
||||
gutterWidth += padding.left + padding.right;
|
||||
if (gutterWidth !== this.gutterWidth) {
|
||||
this.gutterWidth = gutterWidth;
|
||||
this._emit("changeGutterWidth", gutterWidth);
|
||||
|
|
|
|||
|
|
@ -735,12 +735,10 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
else if (changes & this.CHANGE_LINES) {
|
||||
if (this.$updateLines()) {
|
||||
this.$updateScrollBar();
|
||||
if (this.showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
} else if (changes & this.CHANGE_GUTTER) {
|
||||
if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
|
||||
if (this.showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
|
|
|
|||
357
tool/perf-test.html
Normal file
357
tool/perf-test.html
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="..">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Ace Profile util</title>
|
||||
<link rel="stylesheet" href="demo/kitchen-sink/styles.css" type="text/css" media="screen" charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a href="http://ajaxorg.github.com/ace/" >
|
||||
<img id="logo" src="demo/kitchen-sink/logo.png">
|
||||
</a>
|
||||
<table id="controls">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<label for="profile">profile</label>
|
||||
<input type="checkbox" checked id="profile"></input>
|
||||
<label for="timeout">delay</label>
|
||||
<input id="timeout" type="text" value="3" style="width:10em"></input>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<button onclick = "start(this.textContent)">scroll</button>
|
||||
<button onclick = "start(this.textContent)">select</button>
|
||||
<button onclick = "start(this.textContent)">type</button>
|
||||
<button onclick = "start(this.textContent)">selectH</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<button onclick = "start(this.textContent)">tokenize</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="doc">Document</label>
|
||||
</td><td>
|
||||
<select id="doc" size="1">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="mode">Mode</label>
|
||||
</td><td>
|
||||
<select id="mode" size="1">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="split">Split</label>
|
||||
</td><td>
|
||||
<select id="split" size="1">
|
||||
<option value="none">None</option>
|
||||
<option value="below">Below</option>
|
||||
<option value="beside">Beside</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="theme">Theme</label>
|
||||
</td><td>
|
||||
<select id="theme" size="1">
|
||||
<optgroup label="Bright">
|
||||
<option value="ace/theme/chrome">Chrome</option>
|
||||
<option value="ace/theme/clouds">Clouds</option>
|
||||
<option value="ace/theme/crimson_editor">Crimson Editor</option>
|
||||
<option value="ace/theme/dawn">Dawn</option>
|
||||
<option value="ace/theme/dreamweaver">Dreamweaver</option>
|
||||
<option value="ace/theme/eclipse">Eclipse</option>
|
||||
<option value="ace/theme/github">GitHub</option>
|
||||
<option value="ace/theme/solarized_light">Solarized Light</option>
|
||||
<option value="ace/theme/textmate" selected="selected">TextMate</option>
|
||||
<option value="ace/theme/tomorrow">Tomorrow</option>
|
||||
</optgroup>
|
||||
<optgroup label="Dark">
|
||||
<option value="ace/theme/clouds_midnight">Clouds Midnight</option>
|
||||
<option value="ace/theme/cobalt">Cobalt</option>
|
||||
<option value="ace/theme/idle_fingers">idleFingers</option>
|
||||
<option value="ace/theme/kr_theme">krTheme</option>
|
||||
<option value="ace/theme/merbivore">Merbivore</option>
|
||||
<option value="ace/theme/merbivore_soft">Merbivore Soft</option>
|
||||
<option value="ace/theme/mono_industrial">Mono Industrial</option>
|
||||
<option value="ace/theme/monokai">Monokai</option>
|
||||
<option value="ace/theme/pastel_on_dark">Pastel on dark</option>
|
||||
<option value="ace/theme/solarized_dark">Solarized Dark</option>
|
||||
<option value="ace/theme/twilight">Twilight</option>
|
||||
<option value="ace/theme/tomorrow_night">Tomorrow Night</option>
|
||||
<option value="ace/theme/tomorrow_night_blue">Tomorrow Night Blue</option>
|
||||
<option value="ace/theme/tomorrow_night_bright">Tomorrow Night Bright</option>
|
||||
<option value="ace/theme/tomorrow_night_eighties">Tomorrow Night 80s</option>
|
||||
<option value="ace/theme/vibrant_ink">Vibrant Ink</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fontsize">Font Size</label>
|
||||
</td><td>
|
||||
<select id="fontsize" size="1">
|
||||
<option value="10px">10px</option>
|
||||
<option value="11px">11px</option>
|
||||
<option value="12px" selected="selected">12px</option>
|
||||
<option value="14px">14px</option>
|
||||
<option value="16px">16px</option>
|
||||
<option value="20px">20px</option>
|
||||
<option value="24px">24px</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="folding">Code Folding</label>
|
||||
</td><td>
|
||||
<select id="folding" size="1">
|
||||
<option value="manual">manual</option>
|
||||
<option value="markbegin" selected="selected">mark begin</option>
|
||||
<option value="markbeginend">mark begin and end</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="keybinding">Key Binding</label>
|
||||
</td><td>
|
||||
<select id="keybinding" size="1">
|
||||
<option value="ace">Ace</option>
|
||||
<option value="vim">Vim</option>
|
||||
<option value="emacs">Emacs</option>
|
||||
<option value="custom">Custom</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="soft_wrap">Soft Wrap</label>
|
||||
</td><td>
|
||||
<select id="soft_wrap" size="1">
|
||||
<option value="off">Off</option>
|
||||
<option value="40">40 Chars</option>
|
||||
<option value="80">80 Chars</option>
|
||||
<option value="free">Free</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="2">
|
||||
<table id="more-controls">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="select_style">Full Line Selection</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="select_style" id="select_style" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="highlight_active">Highlight Active Line</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="highlight_active" id="highlight_active" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="show_hidden">Show Invisibles</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="show_hidden" id="show_hidden" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="display_indent_guides">Show Indent Guides</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="display_indent_guides" id="display_indent_guides" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="show_hscroll">Persistent HScroll</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="show_hscroll" id="show_hscroll">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="animate_scroll">Animate scrolling</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="animate_scroll" id="animate_scroll">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="show_gutter">Show Gutter</label>
|
||||
</td><td>
|
||||
<input type="checkbox" id="show_gutter" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="show_print_margin">Show Print Margin</label>
|
||||
</td><td>
|
||||
<input type="checkbox" id="show_print_margin" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="soft_tab">Use Soft Tab</label>
|
||||
</td><td>
|
||||
<input type="checkbox" id="soft_tab" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="highlight_selected_word">Highlight selected word</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" id="highlight_selected_word" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="enable_behaviours">Enable Behaviours</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" id="enable_behaviours">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="fade_fold_widgets">Fade Fold Widgets</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" id="fade_fold_widgets" checked>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="editor"></div>
|
||||
|
||||
<!--DEVEL-->
|
||||
<script type="text/javascript">
|
||||
var require = {
|
||||
baseUrl: window.location.protocol + "//" + window.location.host + window.location.pathname.split("/").slice(0, -1).join("/"),
|
||||
paths: {
|
||||
ace: "../lib/ace"
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="demo/kitchen-sink/require.js" data-main="../demo/kitchen-sink/demo" type="text/javascript"></script>
|
||||
|
||||
<script>
|
||||
if (!Date.now) {
|
||||
Date.now = function() { return (new Date()).getTime() };
|
||||
}
|
||||
|
||||
|
||||
var scrollTop, startTime;
|
||||
var timeout, speed, next
|
||||
var editor, shouldProfile;
|
||||
|
||||
function start(testName) {
|
||||
editor = env.editor
|
||||
timeout = parseInt(document.getElementById("timeout").value);
|
||||
shouldProfile = document.getElementById("profile").checked;
|
||||
|
||||
startTime = Date.now()
|
||||
shouldProfile && console.profile()
|
||||
|
||||
speed = 10;
|
||||
next = window[testName + "Next"];
|
||||
|
||||
window[testName + "Start"] && window[testName + "Start"]()
|
||||
setTimeout(next, 1);
|
||||
}
|
||||
function end(){
|
||||
shouldProfile && console.profileEnd()
|
||||
console.log(startTime - Date.now())
|
||||
}
|
||||
|
||||
/*editor.renderer.scrollToY(0);
|
||||
editor.navigateFileStart(0);
|
||||
*/
|
||||
|
||||
var scrollNext = function() {
|
||||
var r = editor.renderer
|
||||
for (var i = speed; i--; )
|
||||
r.scrollBy(0, 1)
|
||||
if (r.scrollTop + r.layerConfig.height > r.layerConfig.maxHeight - 20)
|
||||
end()
|
||||
else
|
||||
setTimeout(next, timeout, speed++)
|
||||
}
|
||||
|
||||
var selectNext = function() {
|
||||
var r = editor.renderer
|
||||
for (var i = speed; i-- > 0; )
|
||||
editor.selection.selectDown()
|
||||
if (r.scrollTop + r.layerConfig.height > r.layerConfig.maxHeight - 20)
|
||||
end()
|
||||
else
|
||||
setTimeout(next, timeout, speed+=0.1)
|
||||
}
|
||||
|
||||
var selectHNext = function() {
|
||||
var r = editor.renderer
|
||||
for (var i = speed; i-- > 0; )
|
||||
editor.selection.selectRight()
|
||||
if (r.scrollTop + r.layerConfig.height > r.layerConfig.maxHeight - 20)
|
||||
end()
|
||||
else
|
||||
setTimeout(next, timeout, speed+=0.1)
|
||||
}
|
||||
|
||||
var typeChars = start.toString().split("")
|
||||
var typeNext = function() {
|
||||
var r = editor.renderer
|
||||
for (var i = speed; i--; )
|
||||
editor.insert(typeChars[i % typeChars.length])
|
||||
if (speed == 100)
|
||||
end()
|
||||
else
|
||||
setTimeout(next, timeout, speed++)
|
||||
}
|
||||
|
||||
var tokenizer, state, lines, chunk
|
||||
var tokenizeStart = function() {
|
||||
var b = ace.session.bgTokenizer
|
||||
state = null
|
||||
tokenizer = b.tokenizer
|
||||
lines = b.doc.getAllLines()
|
||||
chunk = 1000
|
||||
}
|
||||
|
||||
var tokenizeNext = function() {
|
||||
var states = []
|
||||
for (var i = 0, l = lines.length; i < l; i++) {
|
||||
state = tokenizer.getLineTokens(lines[i], state).state
|
||||
}
|
||||
states.push(state)
|
||||
if (speed-- > 3)
|
||||
setTimeout(next, timeout)
|
||||
else
|
||||
end()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue