optimization: partial render

This commit is contained in:
Jocs 2018-05-14 15:41:26 +08:00
parent 8abdf9bfe9
commit d0b62033bf
5 changed files with 55 additions and 32 deletions

50
package-lock.json generated
View File

@ -3705,6 +3705,11 @@
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44="
},
"browser-split": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz",
"integrity": "sha1-ewl1dPjj6tYG+0Zk5krf3aKYGpM="
},
"browser-stdout": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
@ -12077,6 +12082,11 @@
"lodash._isiterateecall": "^3.0.0"
}
},
"lodash.escape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
"integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg="
},
"lodash.filter": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz",
@ -12092,6 +12102,11 @@
"resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
"integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM="
},
"lodash.forown": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz",
"integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68="
},
"lodash.initial": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.initial/-/lodash.initial-4.1.1.tgz",
@ -12123,6 +12138,11 @@
"resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz",
"integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I="
},
"lodash.kebabcase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
"integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY="
},
"lodash.keys": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
@ -12199,6 +12219,11 @@
"lodash.keys": "^3.0.0"
}
},
"lodash.remove": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.remove/-/lodash.remove-4.7.0.tgz",
"integrity": "sha1-8x0x58OaBpDVB07A02JxYjNO5iY="
},
"lodash.restparam": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
@ -12228,8 +12253,7 @@
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
"dev": true
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
},
"lodash.where": {
"version": "3.1.0",
@ -13964,6 +13988,14 @@
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
},
"parse-sel": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-sel/-/parse-sel-1.0.0.tgz",
"integrity": "sha1-uTANK7lGoGwiyY4gjkeyCIaQy90=",
"requires": {
"browser-split": "0.0.1"
}
},
"parse5": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
@ -16470,6 +16502,20 @@
"resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-0.7.1.tgz",
"integrity": "sha512-uIOCq6rfkBZg2VdSopy9jL0cIOdrkHCcwOjDsLnjef6Z5oPoD8V7nKI8de4gP5GfvyqLY0RBDJP8LVU19Nsw5Q=="
},
"snabbdom-to-html": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/snabbdom-to-html/-/snabbdom-to-html-5.1.0.tgz",
"integrity": "sha512-Fir4/BLW7HRQYAgj2JLOK7BoY3nIfQuwBhCdLdxL/vwgyR+9HRzYWokDcs1IVA7QdDmD84YAdv/8A55NIQEnWQ==",
"requires": {
"lodash.escape": "^4.0.1",
"lodash.forown": "^4.4.0",
"lodash.kebabcase": "^4.1.1",
"lodash.remove": "^4.7.0",
"lodash.uniq": "^4.5.0",
"object-assign": "^4.1.0",
"parse-sel": "^1.0.0"
}
},
"snabbdom-virtualize": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/snabbdom-virtualize/-/snabbdom-virtualize-0.7.0.tgz",

View File

@ -115,6 +115,7 @@
"mousetrap": "^1.6.1",
"parse5": "^3.0.3",
"snabbdom": "^0.7.1",
"snabbdom-to-html": "^5.1.0",
"snabbdom-virtualize": "^0.7.0",
"to": "^0.2.9",
"turndown": "^4.0.1",

View File

@ -113,8 +113,7 @@ export const CLASS_OR_ID = genUpper2LowerKeyHash([
'AG_TIGHT_LIST_ITEM',
'AG_HTML_TAG',
'AG_LINK',
'AG_HARD_LINE_BREAK',
'AG_OFF_SCREEN'
'AG_HARD_LINE_BREAK'
])
export const codeMirrorConfig = {

View File

@ -33,11 +33,6 @@ h6.ag-active::before {
font-weight: 100;
}
.ag-off-screen {
position: absolute;
left: 100vw;
}
.ag-paragraph:empty::after,
.ag-line:empty:after {
content: '\200B'

View File

@ -1,7 +1,7 @@
import virtualize from 'snabbdom-virtualize/strings'
import { CLASS_OR_ID, IMAGE_EXT_REG } from '../config'
import { conflict, isLengthEven, union, isEven, getUniqueId, loadImage, getImageSrc } from '../utils'
import { insertBefore, insertAfter, operateClassName } from '../utils/domManipulate'
import { insertAfter, operateClassName } from '../utils/domManipulate'
import { tokenizer } from './parse'
import { validEmoji } from '../emojis'
@ -13,6 +13,7 @@ const patch = snabbdom.init([ // Init patch function with chosen modules
require('snabbdom/modules/dataset').default
])
const h = require('snabbdom/h').default // helper function for creating vnodes
const toHTML = require('snabbdom-to-html')
const toVNode = require('snabbdom/tovnode').default
class StateRender {
@ -20,18 +21,6 @@ class StateRender {
this.eventCenter = eventCenter
this.loadImageMap = new Map()
this.container = null
this.offScreen = null
this.init()
}
init () {
let section = document.querySelector(`.${CLASS_OR_ID['AG_OFF_SCREEN']}`)
if (!section) {
section = document.createElement('section')
section.classList.add(CLASS_OR_ID['AG_OFF_SCREEN'])
document.body.appendChild(section)
}
this.offScreen = section
}
setContainer (container) {
@ -255,12 +244,9 @@ class StateRender {
const cursorOutMostBlock = activeBlocks[activeBlocks.length - 1]
// If cursor is not in render blocks, need to render cursor block independently
const needRenderCursorBlock = blocks.indexOf(cursorOutMostBlock) === -1
const newVnode = h(`section.${CLASS_OR_ID['AG_OFF_SCREEN']}`, blocks.map(block => this.renderBlock(block, cursor, activeBlocks, matches)))
const { offScreen } = this
const newVnode = h('section', blocks.map(block => this.renderBlock(block, cursor, activeBlocks, matches)))
const html = toHTML(newVnode).replace(/^<section>([\s\S]+?)<\/section>$/, '$1')
patch(offScreen, newVnode)
const renderedDoms = offScreen.children
const needToRemoved = []
const firstOldDom = startKey
? document.querySelector(`#${startKey}`)
@ -273,14 +259,10 @@ class StateRender {
}
nextSibling && needToRemoved.push(nextSibling)
Array.from(renderedDoms).forEach(dom => {
insertBefore(dom, firstOldDom)
})
firstOldDom.insertAdjacentHTML('beforebegin', html)
Array.from(needToRemoved).forEach(dom => dom.remove())
offScreen.textContent = ''
// Render cursor block independently
if (needRenderCursorBlock) {
const { key } = cursorOutMostBlock