make editor load even faster

* reorder scripts
* make style request earlier
This commit is contained in:
tophf 2020-10-13 21:19:12 +03:00
parent 2e1a903cc7
commit bc6c9c826a
4 changed files with 110 additions and 123 deletions

View File

@ -18,6 +18,22 @@
} }
</style> </style>
<link id="cm-theme" rel="stylesheet">
<script src="js/polyfill.js"></script>
<script src="js/dom.js"></script>
<script src="js/messaging.js"></script>
<script src="js/prefs.js"></script>
<script src="js/localization.js"></script>
<script src="js/script-loader.js"></script>
<script src="js/storage-util.js"></script>
<script src="js/msg.js"></script>
<script src="content/style-injector.js"></script>
<script src="content/apply.js"></script>
<script src="edit/edit.js"></script> <!-- run it ASAP to send a request for the style -->
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet"> <link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
<script src="vendor/codemirror/lib/codemirror.js"></script> <script src="vendor/codemirror/lib/codemirror.js"></script>
@ -63,44 +79,27 @@
<script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script> <script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script>
<script src="js/polyfill.js"></script> <script src="msgbox/msgbox.js" async></script>
<script src="js/dom.js"></script>
<script src="js/messaging.js"></script>
<script src="js/prefs.js"></script>
<script src="js/localization.js"></script>
<script src="js/script-loader.js"></script>
<script src="js/storage-util.js"></script>
<script src="js/msg.js"></script>
<script src="js/worker-util.js"></script>
<script src="content/style-injector.js"></script>
<script src="content/apply.js"></script>
<link href="edit/global-search.css" rel="stylesheet">
<script src="edit/global-search.js"></script>
<link href="edit/codemirror-default.css" rel="stylesheet"> <link href="edit/codemirror-default.css" rel="stylesheet">
<script src="edit/codemirror-default.js"></script> <script src="edit/codemirror-default.js"></script>
<script src="edit/codemirror-factory.js"></script>
<script src="edit/util.js"></script> <script src="edit/util.js"></script>
<script src="edit/regexp-tester.js"></script> <script src="edit/regexp-tester.js"></script>
<script src="edit/live-preview.js"></script> <script src="edit/live-preview.js"></script>
<script src="edit/applies-to-line-widget.js"></script> <script src="edit/applies-to-line-widget.js"></script>
<script src="edit/reroute-hotkeys.js"></script> <script src="edit/reroute-hotkeys.js"></script>
<script src="edit/codemirror-factory.js"></script> <link href="edit/global-search.css" rel="stylesheet">
<script src="edit/global-search.js"></script>
<script src="edit/colorpicker-helper.js"></script> <script src="edit/colorpicker-helper.js"></script>
<script src="edit/beautify.js"></script> <script src="edit/beautify.js"></script>
<script src="edit/show-keymap-help.js"></script> <script src="edit/show-keymap-help.js"></script>
<script src="edit/codemirror-themes.js"></script> <script src="edit/codemirror-themes.js"></script>
<script src="edit/source-editor.js"></script> <script src="edit/source-editor.js"></script>
<script src="edit/sections-editor-section.js"></script> <script src="edit/sections-editor-section.js"></script>
<script src="edit/sections-editor.js"></script> <script src="edit/sections-editor.js"></script>
<script src="edit/edit.js"></script> <script src="js/worker-util.js"></script>
<script src="msgbox/msgbox.js" async></script>
<script src="edit/linter.js"></script> <script src="edit/linter.js"></script>
<script src="edit/linter-defaults.js"></script> <script src="edit/linter-defaults.js"></script>
<script src="edit/linter-engines.js"></script> <script src="edit/linter-engines.js"></script>
@ -109,8 +108,6 @@
<script src="edit/linter-report.js"></script> <script src="edit/linter-report.js"></script>
<script src="edit/linter-config-dialog.js"></script> <script src="edit/linter-config-dialog.js"></script>
<link id="cm-theme" rel="stylesheet">
<template data-id="appliesTo"> <template data-id="appliesTo">
<li class="applies-to-item"> <li class="applies-to-item">
<div class="select-resizer"> <div class="select-resizer">

View File

@ -1,15 +1,11 @@
/* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML /* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML
createSourceEditor sessionStorageHash getOwnTab FIREFOX API tryCatch createSourceEditor sessionStorageHash getOwnTab FIREFOX API tryCatch
closeCurrentTab messageBox debounce workerUtil closeCurrentTab messageBox debounce
initBeautifyButton ignoreChromeError dirtyReporter initBeautifyButton ignoreChromeError dirtyReporter linter
moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */ moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */
/* exported showCodeMirrorPopup editorWorker toggleContextMenuDelete */ /* exported showCodeMirrorPopup editorWorker toggleContextMenuDelete */
'use strict'; 'use strict';
const editorWorker = workerUtil.createWorker({
url: '/edit/editor-worker.js'
});
let saveSizeOnClose; let saveSizeOnClose;
// direct & reverse mapping of @-moz-document keywords and internal property names // direct & reverse mapping of @-moz-document keywords and internal property names
@ -28,27 +24,37 @@ document.addEventListener('visibilitychange', beforeUnload);
window.addEventListener('beforeunload', beforeUnload); window.addEventListener('beforeunload', beforeUnload);
msg.onExtension(onRuntimeMessage); msg.onExtension(onRuntimeMessage);
preinit(); lazyInit();
(async function init() { (async function init() {
const [style] = await Promise.all([ const [style] = await Promise.all([
initStyleData(), initStyleData(),
onDOMready(), onDOMready(),
prefs.initializing, prefs.initializing.then(() => new Promise(resolve => {
const theme = prefs.get('editor.theme');
const el = $('#cm-theme');
if (theme === 'default') {
resolve();
} else {
// preload the theme so CodeMirror can use the correct metrics
el.href = `vendor/codemirror/theme/${theme}.css`;
el.addEventListener('load', resolve, {once: true});
}
})),
]); ]);
const usercss = isUsercss(style); const usercss = isUsercss(style);
const dirty = dirtyReporter(); const dirty = dirtyReporter();
let wasDirty = false; let wasDirty = false;
let nameTarget; let nameTarget;
prefs.subscribe(['editor.linter'], updateLinter);
prefs.subscribe(['editor.keyMap'], showHotkeyInTooltip); prefs.subscribe(['editor.keyMap'], showHotkeyInTooltip);
addEventListener('showHotkeyInTooltip', showHotkeyInTooltip); addEventListener('showHotkeyInTooltip', showHotkeyInTooltip);
showHotkeyInTooltip(); showHotkeyInTooltip();
buildThemeElement(); buildThemeElement();
buildKeymapElement(); buildKeymapElement();
setupLivePrefs(); setupLivePrefs();
initNameArea(style, usercss); initNameArea();
initBeautifyButton($('#beautify'), () => editor.getEditors()); initBeautifyButton($('#beautify'), () => editor.getEditors());
initResizeListener(); initResizeListener();
detectLayout(); detectLayout();
@ -70,7 +76,7 @@ preinit();
$('#name').required = !usercss; $('#name').required = !usercss;
$('#save-button').onclick = editor.save; $('#save-button').onclick = editor.save;
function initNameArea(style, usercss) { function initNameArea() {
const nameEl = $('#name'); const nameEl = $('#name');
const resetEl = $('#reset-name'); const resetEl = $('#reset-name');
const isCustomName = style.updateUrl || usercss; const isCustomName = style.updateUrl || usercss;
@ -116,6 +122,8 @@ preinit();
function buildThemeElement() { function buildThemeElement() {
CODEMIRROR_THEMES.unshift(chrome.i18n.getMessage('defaultTheme')); CODEMIRROR_THEMES.unshift(chrome.i18n.getMessage('defaultTheme'));
$('#editor.theme').append(...CODEMIRROR_THEMES.map(s => $create('option', s))); $('#editor.theme').append(...CODEMIRROR_THEMES.map(s => $create('option', s)));
// move the theme after built-in CSS so that its same-specificity selectors win
document.head.appendChild($('#cm-theme'));
} }
function buildKeymapElement() { function buildKeymapElement() {
@ -216,21 +224,31 @@ preinit();
function updateTitle() { function updateTitle() {
document.title = `${dirty.isDirty() ? '* ' : ''}${style.customName || style.name}`; document.title = `${dirty.isDirty() ? '* ' : ''}${style.customName || style.name}`;
} }
function updateLinter(key, value) {
$('body').classList.toggle('linter-disabled', value === '');
linter.run();
}
})(); })();
function preinit() { /* Stuff not needed for the main init so we can let it run at its own tempo */
// preload the theme so that CodeMirror can calculate its metrics in DOMContentLoaded->setupLivePrefs() async function lazyInit() {
new MutationObserver((mutations, observer) => { const ownTabId = (await getOwnTab()).id;
const themeElement = $('#cm-theme'); // use browser history back when 'back to manage' is clicked
if (themeElement) { if (sessionStorageHash('manageStylesHistory').value[ownTabId] === location.href) {
themeElement.href = prefs.get('editor.theme') === 'default' ? '' onDOMready().then(() => {
: 'vendor/codemirror/theme/' + prefs.get('editor.theme') + '.css'; $('#cancel-button').onclick = event => {
observer.disconnect(); event.stopPropagation();
event.preventDefault();
history.back();
};
});
} }
}).observe(document, {subtree: true, childList: true}); // no windows on android
if (!chrome.windows) {
if (chrome.windows) { return;
browser.tabs.query({currentWindow: true}).then(tabs => { }
const tabs = await browser.tabs.query({currentWindow: true});
const windowId = tabs[0].windowId; const windowId = tabs[0].windowId;
if (prefs.get('openEditInWindow')) { if (prefs.get('openEditInWindow')) {
if ( if (
@ -252,28 +270,6 @@ function preinit() {
saveSizeOnClose = sessionStorageHash('saveSizeOnClose').value[windowId]; saveSizeOnClose = sessionStorageHash('saveSizeOnClose').value[windowId];
} }
} }
});
}
getOwnTab().then(tab => {
const ownTabId = tab.id;
// use browser history back when 'back to manage' is clicked
if (sessionStorageHash('manageStylesHistory').value[ownTabId] === location.href) {
onDOMready().then(() => {
$('#cancel-button').onclick = event => {
event.stopPropagation();
event.preventDefault();
history.back();
};
});
}
// no windows on android
if (!chrome.windows) {
return;
}
// When an edit page gets attached or detached, remember its state
// so we can do the same to the next one to open.
chrome.tabs.onAttached.addListener((tabId, info) => { chrome.tabs.onAttached.addListener((tabId, info) => {
if (tabId !== ownTabId) { if (tabId !== ownTabId) {
return; return;
@ -292,7 +288,6 @@ function preinit() {
prefs.set('openEditInWindow', openEditInWindow); prefs.set('openEditInWindow', openEditInWindow);
}); });
}); });
});
} }
function onRuntimeMessage(request) { function onRuntimeMessage(request) {
@ -507,10 +502,6 @@ function rememberWindowSize() {
} }
} }
prefs.subscribe(['editor.linter'], (key, value) => {
$('body').classList.toggle('linter-disabled', value === '');
});
function fixedHeader() { function fixedHeader() {
const scrollPoint = $('#header').clientHeight - 40; const scrollPoint = $('#header').clientHeight - 40;
const linterEnabled = prefs.get('editor.linter') !== ''; const linterEnabled = prefs.get('editor.linter') !== '';

View File

@ -1,6 +1,11 @@
/* global prefs */ /* global workerUtil */
'use strict'; 'use strict';
/* exported editorWorker */
const editorWorker = workerUtil.createWorker({
url: '/edit/editor-worker.js'
});
/* exported linter */ /* exported linter */
const linter = (() => { const linter = (() => {
const lintingUpdatedListeners = []; const lintingUpdatedListeners = [];
@ -59,8 +64,3 @@ const linter = (() => {
.then(results => [].concat(...results.filter(Boolean))); .then(results => [].concat(...results.filter(Boolean)));
} }
})(); })();
// FIXME: this should be put inside edit.js
prefs.subscribe(['editor.linter'], () => {
linter.run();
});

View File

@ -71,7 +71,7 @@ function createSectionsEditor(editorBase) {
}); });
function fitToContent(section) { function fitToContent(section) {
const {cm, cm: {display: {wrapper, sizer}}} = section; const {el, cm, cm: {display: {wrapper, sizer}}} = section;
if (cm.display.renderedView) { if (cm.display.renderedView) {
resize(); resize();
} else { } else {
@ -84,7 +84,7 @@ function createSectionsEditor(editorBase) {
return; return;
} }
if (headerOffset == null) { if (headerOffset == null) {
headerOffset = wrapper.getBoundingClientRect().top; headerOffset = el.getBoundingClientRect().top;
} }
contentHeight += 9; // border & resize grip contentHeight += 9; // border & resize grip
cm.off('update', resize); cm.off('update', resize);
@ -95,17 +95,16 @@ function createSectionsEditor(editorBase) {
} }
function fitToAvailableSpace() { function fitToAvailableSpace() {
const available = const ch = container.offsetHeight;
Math.floor(container.offsetHeight - sections.reduce((h, s) => h + s.el.offsetHeight, 0)) || let available = ch - sections[sections.length - 1].el.getBoundingClientRect().bottom + headerOffset;
window.innerHeight - container.offsetHeight; if (available <= 1) available = window.innerHeight - ch - headerOffset;
if (available <= 0) { const delta = Math.floor(available / sections.length);
return; if (delta > 1) {
} sections.forEach(({cm}) => {
const cmHeights = sections.map(s => s.cm.getWrapperElement().offsetHeight); cm.setSize(null, cm.display.wrapper.offsetHeight + delta);
sections.forEach((section, i) => {
section.cm.setSize(null, cmHeights[i] + Math.floor(available / sections.length));
}); });
} }
}
function genId() { function genId() {
return INC_ID++; return INC_ID++;