Skip to content

Commit

Permalink
feat: support client prerender mipengine#351
Browse files Browse the repository at this point in the history
  • Loading branch information
Ricardo-Li committed Nov 27, 2018
1 parent f74ab66 commit 8160d62
Show file tree
Hide file tree
Showing 9 changed files with 535 additions and 23 deletions.
103 changes: 103 additions & 0 deletions src/clientPrerender.js
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();
});
9 changes: 7 additions & 2 deletions src/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ define(function (require) {
var cssLoader = require('./dom/css-loader');
var layout = require('./layout');
var performance = require('./performance');
var prerender = require('./clientPrerender');

/**
* Storage of custom elements.
Expand Down Expand Up @@ -95,7 +96,9 @@ define(function (require) {
this._layout = layout.applyLayout(this);
this.customElement.attachedCallback();
// Add to resource manager.
this._resources.add(this);
prerender.execute(function() {
this._resources.add(this);
}.bind(this), this);
};

/**
Expand All @@ -112,7 +115,9 @@ define(function (require) {
*/
proto.attributeChangedCallback = function (attributeName, oldValue, newValue, namespace) {
var ele = this.customElement;
ele.attributeChangedCallback.apply(ele, arguments);
prerender.execute(function () {
ele.attributeChangedCallback.apply(ele, arguments);
});
};

/**
Expand Down
52 changes: 52 additions & 0 deletions src/firstScreenLabel.js
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
}
});
18 changes: 17 additions & 1 deletion src/log/logSend.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
* @author schoeu
*/

define(function () {
define(function (require) {
'use strict';

var firstScreenLabel = require('./firstScreenLabel');
var viewer = require('../viewer');
var OUTER_MESSAGE_PERFORMANCE_ANALYSIS_LOG = 'performance-analysis-log';

function MipLog() {
this.data = {};
}
Expand All @@ -25,5 +29,17 @@ define(function () {
window.parent.postMessage(this.data, '*');
}
};

/**
* send first screen label log
*/
MipLog.prototype.sendFirstScreenLabelLog = function () {
var info = firstScreenLabel.getFirstScreenLabelInfo();
viewer.sendMessage(OUTER_MESSAGE_PERFORMANCE_ANALYSIS_LOG, {
type: 'fslabel',
info: info
});
}

return new MipLog();
});
Loading

0 comments on commit 8160d62

Please sign in to comment.