forked from mipengine/mip
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support client prerender mipengine#351
- Loading branch information
1 parent
f74ab66
commit 8160d62
Showing
9 changed files
with
535 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* @file client-prerender.js 在浏览器端预渲染 | ||
* @author liwenqian ([email protected]) | ||
*/ | ||
define(function (require) { | ||
'use strict'; | ||
|
||
var hash = require('./hash'); | ||
var fn = require('./utils/fn'); | ||
var Messager = require('./messager'); | ||
var MESSAGE_PAGE_ACTIVE = 'page-active'; | ||
var MESSAGE_PRERENDER_INTERACTIVE = 'prerender-interactive'; | ||
|
||
/** | ||
* ClientPrerender | ||
* | ||
* @class | ||
*/ | ||
function ClientPrerender() { | ||
// 预渲染环境标记, 是否是预渲染状态 | ||
this.isPrerendering = false; | ||
|
||
// 是否执行过预渲染 | ||
this.isPrerendered = false; | ||
|
||
// 延迟执行的的函数队列 | ||
this.queue = []; | ||
|
||
// 外层通信 | ||
this.messager = new Messager({ | ||
name: fn.getRootName(window.name) | ||
}); | ||
|
||
this.init(); | ||
} | ||
|
||
ClientPrerender.prototype.init = function () { | ||
var self = this; | ||
if (hash.get('prerender') === '1') { | ||
this.isPrerendering = true; | ||
new Promise(function (resolve, reject) { | ||
// set client prerender event | ||
self.messager.on(MESSAGE_PAGE_ACTIVE, function () { | ||
self.isPrerendering = false; | ||
resetPrerenderHash(); | ||
resolve(); | ||
}); | ||
// can interact with container | ||
self.messager.sendMessage(MESSAGE_PRERENDER_INTERACTIVE, { | ||
time: Date.now() | ||
}); | ||
}).then(function () { | ||
self.isPrerendered = true; | ||
// firstscreen show | ||
var performance = require('./performance'); | ||
performance.recordTiming('MIPPageShow'); | ||
performance.lockFirstScreen(); | ||
performance.recordTiming('MIPElementBuildStart'); | ||
var fn; | ||
while ((fn = self.queue.shift())) { | ||
fn(); | ||
} | ||
}).then(function () { | ||
require('./performance').recordTiming('MIPElementBuildEnd'); | ||
}).catch(function (error) { | ||
throw(error); | ||
}) | ||
} | ||
}; | ||
|
||
ClientPrerender.prototype.execute = function (fn, ele) { | ||
if (this.isPrerendering && !parsePrerender(ele)) { | ||
this.queue.push(fn); | ||
} | ||
else { | ||
fn(); | ||
} | ||
}; | ||
|
||
function resetPrerenderHash() { | ||
var location = window.location; | ||
var hash = location.hash.replace(/prerender=1&?/, ''); | ||
window.history.replaceState( | ||
'', document.title, | ||
location.pathname + location.search + hash | ||
); | ||
} | ||
|
||
function parsePrerender(element) { | ||
if (!element || !element.getAttribute) { | ||
return false; | ||
} | ||
var prerender = element.getAttribute('prerender'); | ||
var firstScreen = element.getAttribute('firstscreen'); | ||
if (firstScreen) { | ||
element.viewportCallback && element.viewportCallback(true); | ||
} | ||
|
||
return firstScreen != null || prerender != null && prerender !== 'false'; | ||
} | ||
|
||
return new ClientPrerender(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* @file 首屏标记识别 | ||
* | ||
* @author liwenqian | ||
*/ | ||
define(function() { | ||
var missList = []; | ||
var incorrectList = []; | ||
|
||
function getPathTo(element) { | ||
if (element.tagName === 'HTML') { | ||
return 'html.1'; | ||
} | ||
if (element === document.body) { | ||
return 'html.1/body.1'; | ||
} | ||
|
||
var ix = 0; | ||
var siblings = element.parentNode.childNodes; | ||
for (var i = 0; i < siblings.length; i++) { | ||
var sibling = siblings[i]; | ||
if (sibling === element) { | ||
return getPathTo(element.parentNode) + '/' + element.tagName.toLowerCase() + '.' + (ix + 1) + ''; | ||
} | ||
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) { | ||
ix++; | ||
} | ||
} | ||
} | ||
|
||
function getFirstScreenLabelInfo() { | ||
var allLabelImgs = Array.prototype.slice.call(document.querySelectorAll('mip-img[firstscreen="1"]')); | ||
var allFirstScreenImgs = Array.prototype.slice.call(document.querySelectorAll('mip-img[mip-firstscreen-element]')); | ||
allLabelImgs.forEach(function (element) { | ||
if (!element.hasAttribute('mip-firstscreen-element')) { | ||
incorrectList.push(getPathTo(element)); | ||
} | ||
}); | ||
allFirstScreenImgs.forEach(function (element) { | ||
if (!element.hasAttribute('firstscreen')) { | ||
missList.push(getPathTo(element)); | ||
} | ||
}); | ||
|
||
var info = missList.join(',') + '!!' + incorrectList.join(','); | ||
return info; | ||
} | ||
|
||
return { | ||
getFirstScreenLabelInfo: getFirstScreenLabelInfo | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.