mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Lazy-load SimpleMDE dependency in MD card (reduces main bundle by 260KB)
no issue - use broccoli-funnel to avoid polluting the `dist/` dir with unused build artefacts - load codemirror and simplemde CSS up-front to avoid duplicate styles and specificity problems - pull simplemde dependency out into a separate JS file and lazy-load in `{{gh-simplemde}}` component to reduce main bundle size. Before/after: - `vendor.min.js 3.58 MB (795.88 KB gzipped)` - `vendor.min.js 3.32 MB (710.66 KB gzipped)`
This commit is contained in:
parent
cda82cf593
commit
893a010a4f
4 changed files with 72 additions and 23 deletions
|
@ -65,7 +65,6 @@ const CmEditorComponent = Component.extend({
|
||||||
let loader = this.get('lazyLoader');
|
let loader = this.get('lazyLoader');
|
||||||
|
|
||||||
yield RSVP.all([
|
yield RSVP.all([
|
||||||
loader.loadStyle('codemirror', 'assets/codemirror/codemirror.css'),
|
|
||||||
loader.loadScript('codemirror', 'assets/codemirror/codemirror.js')
|
loader.loadScript('codemirror', 'assets/codemirror/codemirror.js')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,11 @@ import config from 'ghost-admin/config/environment';
|
||||||
import {assign} from '@ember/polyfills';
|
import {assign} from '@ember/polyfills';
|
||||||
import {computed} from '@ember/object';
|
import {computed} from '@ember/object';
|
||||||
import {isEmpty} from '@ember/utils';
|
import {isEmpty} from '@ember/utils';
|
||||||
|
import {inject as service} from '@ember/service';
|
||||||
|
import {task} from 'ember-concurrency';
|
||||||
|
|
||||||
export default TextArea.extend({
|
export default TextArea.extend({
|
||||||
|
lazyLoader: service(),
|
||||||
|
|
||||||
// Public attributes
|
// Public attributes
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
|
@ -60,6 +63,18 @@ export default TextArea.extend({
|
||||||
// instantiate the editor with the contents of value
|
// instantiate the editor with the contents of value
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
this.initSimpleMDE.perform();
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
this.onEditorDestroy();
|
||||||
|
this._editor.toTextArea();
|
||||||
|
delete this._editor;
|
||||||
|
this._super(...arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
initSimpleMDE: task(function* () {
|
||||||
|
yield this.lazyLoader.loadScript('simplemde', 'assets/simplemde/simplemde.js');
|
||||||
|
|
||||||
let editorOptions = assign(
|
let editorOptions = assign(
|
||||||
{element: document.getElementById(this.elementId)},
|
{element: document.getElementById(this.elementId)},
|
||||||
|
@ -97,12 +112,5 @@ export default TextArea.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onEditorInit(this._editor);
|
this.onEditorInit(this._editor);
|
||||||
},
|
})
|
||||||
|
|
||||||
willDestroyElement() {
|
|
||||||
this.onEditorDestroy();
|
|
||||||
this._editor.toTextArea();
|
|
||||||
delete this._editor;
|
|
||||||
this._super(...arguments);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -378,6 +378,11 @@
|
||||||
/* SimpleMDE editor
|
/* SimpleMDE editor
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ensure there's no flash of unstyled textarea while initializing */
|
||||||
|
.gh-markdown-editor textarea {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.gh-editor-title {
|
.gh-editor-title {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,20 +6,19 @@ const concat = require('broccoli-concat');
|
||||||
const mergeTrees = require('broccoli-merge-trees');
|
const mergeTrees = require('broccoli-merge-trees');
|
||||||
const uglify = require('broccoli-uglify-sourcemap');
|
const uglify = require('broccoli-uglify-sourcemap');
|
||||||
const CleanCSS = require('broccoli-clean-css');
|
const CleanCSS = require('broccoli-clean-css');
|
||||||
|
const Funnel = require('broccoli-funnel');
|
||||||
const environment = EmberApp.env();
|
const environment = EmberApp.env();
|
||||||
const isProduction = environment === 'production';
|
const isProduction = environment === 'production';
|
||||||
let assetLocation, codemirrorAssets;
|
|
||||||
|
|
||||||
assetLocation = function (fileName) {
|
const assetLocation = function (fileName) {
|
||||||
if (isProduction) {
|
if (isProduction) {
|
||||||
fileName = fileName.replace('.', '.min.');
|
fileName = fileName.replace('.', '.min.');
|
||||||
}
|
}
|
||||||
return `/assets/${fileName}`;
|
return `/assets/${fileName}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
codemirrorAssets = function () {
|
const codemirrorAssets = function () {
|
||||||
let codemirrorFiles = [
|
let codemirrorFiles = [
|
||||||
// 'lib/codemirror.css',
|
|
||||||
'theme/xq-light.css',
|
'theme/xq-light.css',
|
||||||
'lib/codemirror.js',
|
'lib/codemirror.js',
|
||||||
'mode/htmlmixed/htmlmixed.js',
|
'mode/htmlmixed/htmlmixed.js',
|
||||||
|
@ -45,17 +44,12 @@ codemirrorAssets = function () {
|
||||||
sourceMapConfig: {enabled: false}
|
sourceMapConfig: {enabled: false}
|
||||||
});
|
});
|
||||||
|
|
||||||
let cssTree = concat(tree, {
|
|
||||||
outputFile: 'assets/codemirror/codemirror.css',
|
|
||||||
inputFiles: ['**/*.css']
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isProduction) {
|
if (isProduction) {
|
||||||
jsTree = uglify(jsTree);
|
jsTree = uglify(jsTree);
|
||||||
cssTree = new CleanCSS(cssTree);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mergeTrees([tree, jsTree, cssTree]);
|
let mergedTree = mergeTrees([tree, jsTree]);
|
||||||
|
return new Funnel(mergedTree, {include: ['assets/**/*', 'theme/**/*']});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,6 +61,44 @@ codemirrorAssets = function () {
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const simplemdeAssets = function () {
|
||||||
|
let simplemdeFiles = [
|
||||||
|
'debug/simplemde.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (environment === 'test') {
|
||||||
|
return {import: simplemdeFiles};
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = {};
|
||||||
|
|
||||||
|
config.public = {
|
||||||
|
include: simplemdeFiles,
|
||||||
|
destDir: '/',
|
||||||
|
processTree(tree) {
|
||||||
|
let jsTree = concat(tree, {
|
||||||
|
outputFile: 'assets/simplemde/simplemde.js',
|
||||||
|
inputFiles: ['debug/simplemde.js'],
|
||||||
|
sourceMapConfig: {enabled: false}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isProduction) {
|
||||||
|
jsTree = uglify(jsTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mergedTree = mergeTrees([tree, jsTree]);
|
||||||
|
return new Funnel(mergedTree, {include: ['assets/**/*']});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// put the files in vendor ready for importing into the test-support file
|
||||||
|
if (environment === 'development') {
|
||||||
|
config.vendor = simplemdeFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = function (defaults) {
|
module.exports = function (defaults) {
|
||||||
let app = new EmberApp(defaults, {
|
let app = new EmberApp(defaults, {
|
||||||
'ember-cli-babel': {
|
'ember-cli-babel': {
|
||||||
|
@ -103,7 +135,8 @@ module.exports = function (defaults) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nodeAssets: {
|
nodeAssets: {
|
||||||
codemirror: codemirrorAssets()
|
codemirror: codemirrorAssets(),
|
||||||
|
simplemde: simplemdeAssets()
|
||||||
},
|
},
|
||||||
svgJar: {
|
svgJar: {
|
||||||
strategy: 'inline',
|
strategy: 'inline',
|
||||||
|
@ -130,14 +163,17 @@ module.exports = function (defaults) {
|
||||||
|
|
||||||
// Stop: Normalize
|
// Stop: Normalize
|
||||||
app.import('node_modules/normalize.css/normalize.css');
|
app.import('node_modules/normalize.css/normalize.css');
|
||||||
app.import('node_modules/simplemde/debug/simplemde.css');
|
|
||||||
|
// 'dem Styles
|
||||||
|
// import codemirror + simplemde styles rather than lazy-loading so that
|
||||||
|
// our overrides work correctly
|
||||||
|
app.import('node_modules/simplemde/dist/simplemde.min.css');
|
||||||
|
|
||||||
// 'dem Scripts
|
// 'dem Scripts
|
||||||
app.import('node_modules/google-caja-bower/html-css-sanitizer-bundle.js');
|
app.import('node_modules/google-caja-bower/html-css-sanitizer-bundle.js');
|
||||||
app.import('node_modules/keymaster/keymaster.js');
|
app.import('node_modules/keymaster/keymaster.js');
|
||||||
app.import('node_modules/@tryghost/mobiledoc-kit/dist/amd/mobiledoc-kit.js');
|
app.import('node_modules/@tryghost/mobiledoc-kit/dist/amd/mobiledoc-kit.js');
|
||||||
app.import('node_modules/@tryghost/mobiledoc-kit/dist/amd/mobiledoc-kit.map');
|
app.import('node_modules/@tryghost/mobiledoc-kit/dist/amd/mobiledoc-kit.map');
|
||||||
app.import('node_modules/simplemde/debug/simplemde.js');
|
|
||||||
app.import('node_modules/reframe.js/dist/noframe.es.js', {
|
app.import('node_modules/reframe.js/dist/noframe.es.js', {
|
||||||
using: [
|
using: [
|
||||||
{transformation: 'es6', as: 'noframe.js'}
|
{transformation: 'es6', as: 'noframe.js'}
|
||||||
|
@ -148,6 +184,7 @@ module.exports = function (defaults) {
|
||||||
// that tests don't break when running via http://localhost:4200/tests
|
// that tests don't break when running via http://localhost:4200/tests
|
||||||
if (app.env === 'development') {
|
if (app.env === 'development') {
|
||||||
app.import('vendor/codemirror/lib/codemirror.js', {type: 'test'});
|
app.import('vendor/codemirror/lib/codemirror.js', {type: 'test'});
|
||||||
|
app.import('vendor/simplemde/debug/simplemde.js', {type: 'test'});
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.toTree();
|
return app.toTree();
|
||||||
|
|
Loading…
Add table
Reference in a new issue