Authored by yyq

client report

@@ -10,6 +10,15 @@ @@ -10,6 +10,15 @@
10 <meta content="yes" name="apple-mobile-web-app-capable"> 10 <meta content="yes" name="apple-mobile-web-app-capable">
11 <meta content="telephone=no" name="format-detection"> 11 <meta content="telephone=no" name="format-detection">
12 <meta content="email=no" name="format-detection"> 12 <meta content="email=no" name="format-detection">
  13 +
  14 + <script>
  15 + if ({{zk.webperf}}) {
  16 + window._timeStart = new Date().getTime();
  17 + window._yohoAppName = 'yoho-community-web';
  18 + window._router = '{{routeHash}}';
  19 + !function(t){function n(r){if(e[r])return e[r].exports;var i=e[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var e={};n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){var r=e(3),i=e(2),o="_perfLog",a=e(17),c=e(18);({init:function(t){this.debug=t,this.dataList=[],this.isRunning=!1,a.init(this.debug),c.init(this.debug),this.report();var n=this;window.addEventListener&&window.addEventListener("load",function(){setTimeout(function(){n.collect()},0)})},collect:function(){try{var t=c.collect(),n=a.collect();this.chunkWrite(t);for(var e=0;e<n.length;e++)this.chunkWrite(n[e])}catch(t){this.debug&&console.log(t)}},getMeta:function(){return{pt:encodeURIComponent(window.location.href),u:i.getUid(),ud:i.getUdid(),rid:i.getReqId(),r:i.getRoute()}},jsonConcat:function(t,n){for(var e in n)t[e]=n[e];return t},write:function(t){this.jsonConcat(t,this.getMeta());var n=JSON.parse(r(o)||"[]");n.push(t),r(o,JSON.stringify(n)),n.length>=3&&this.report()},report:function(){var t=this,n=JSON.parse(r(o)||"[]"),e=i.stringify(n);i.report(e,function(){t.clear()})},clear:function(){r(o,"[]")},chunkWrite:function(t){function n(){if(0!==e.dataList.length){var t=e.dataList.shift();e.write(t),setTimeout(n,10)}}var e=this;this.dataList.push(t),this.isRunning||(this.isRunning=!0,n())}}).init()},function(t,n){t.exports=function(t,n,e){if(void 0===n){var r=null;if(document.cookie)for(var i=document.cookie.split(";"),o=0;o<i.length;o++){var a=(i[o]||"").trim();if(a.substring(0,t.length+1)==t+"="){r=decodeURIComponent(a.substring(t.length+1));break}}return r}e=e||{},null===n&&(n="",e.expires=-1);var c="";if(e.expires&&("number"==typeof e.expires||e.expires.toUTCString)){var u;"number"==typeof e.expires?(u=new Date,u.setTime(u.getTime()+24*e.expires*60*60*1e3)):u=e.expires,c="; expires="+u.toUTCString()}var s=e.path?"; path="+e.path:"",f=e.domain?"; domain="+e.domain:"",d=e.secure?"; secure":"";document.cookie=[t,"=",encodeURIComponent(n),c,s,f,d].join("")}},function(t,n,e){var r=e(1),i=window._yohoAppName||"unknown",o={config:{reportUrl:"//badjs.yoho.cn/apm/yas2.gif"},stringify:function(t){for(var n=[],e=0;e<t.length;e++){var r=t[e],i=[];for(var o in r)r.hasOwnProperty(o)&&i.push(o+"::"+r[o]);n.push(i.join("$$"))}return n.join("**")},report:function(t,n){if(t){(new Image).src=this.config.reportUrl+"?s="+i+"&l="+t+"&t="+(new Date).getTime(),n&&n()}},getUdid:function(){return r("udid")||""||0},getUid:function(){return(r("_UID")||"").split("::")[1]||0},getReqId:function(){return r("docreqid")||0},getRoute:function(){return window._router||""}};t.exports=o},function(t,n){t.exports=function(t,n){if(void 0===n){var n=null;return window.localStorage&&(n=window.localStorage.getItem(t)),n}window.localStorage&&window.localStorage.setItem(t,n)}},,,,,,,,,,,,,,function(t,n){var e={init:function(t){if(this.enable=!0,this.debug=t,!("performance"in window&&"getEntriesByType"in window.performance&&window.performance.getEntriesByType("resource")instanceof Array))return void(this.enable=!1);this.whiteList=[/\/\/img\d*.static.yhbimg.com/,/\/\/cdn.yoho.cn/]},print:function(){var t=document.getElementById("debug"),n=this.formatDebugInfo();if(t)t.innerHTML+=n;else{var e=document.createElement("div");e.id="debug",e.innerHTML=n,document.body.appendChild(e)}},formatDebugInfo:function(){for(var t="<p>resource object: <br/>",n=this.getData(),e=0;e<n.length;e++)t+=JSON.stringify(n[e],null,2)+"<br/>";return t+="</p>"},filter:function(t){for(var n=0;n<this.whiteList.length;n++)if(this.whiteList[n].test(t))return!0;return!1},getData:function(){var t=window.performance.getEntriesByType("resource"),n=[],e={};for(var r in t){var i=t[r];if(this.filter(i.name)){var o={tp:"resource",mtp:i.initiatorType||"unknown",id:i.name||"unknown",dt:Math.floor(i.domainLookupEnd-i.domainLookupStart||0),tt:Math.floor(i.connectEnd-i.connectStart||0),rt:Math.floor(i.responseEnd-i.responseStart||0),rrt:Math.floor(i.responseEnd-i.fetchStart||0)};i.initiatorType in e?e[i.initiatorType].push(o):e[i.initiatorType]=[o]}}for(var a in e){for(var c=e[a],u=c.length,s={tp:"rs",mtp:a,dt:0,tt:0,rt:0,rrt:0},f=0;f<c.length;f++){var d=c[f];s.dt+=d.dt,s.tt+=d.tt,s.rt+=d.rt,s.rrt+=d.rrt}s.dt=Math.floor(s.dt/u),s.tt=Math.floor(s.tt/u),s.rt=Math.floor(s.rt/u),s.rrt=Math.floor(s.rrt/u),n.push(s)}return n},collect:function(){return this.enable?(this.debug&&this.print(),this.getData()):[]}};t.exports=e},function(t,n){var e=function(){function t(){return{tp:"tm",mtp:"html",dt:Math.floor(n),tt:Math.floor(e),rt:Math.floor(r),domt:Math.floor(o),et:Math.floor(i),ot:Math.floor(a),rtt:Math.floor(c),sw:screen.width||1,sh:screen.height||1,pf:navigator.platform||"unknown"}}var n=performance.timing.domainLookupEnd-(performance.timing.domainLookupStart||0),e=performance.timing.connectEnd-(performance.timing.connectStart||0),r=performance.timing.responseEnd-(performance.timing.responseStart||0),i=performance.timing.responseStart-(performance.timing.navigationStart||0),o=performance.timing.domContentLoadedEventEnd-(performance.timing.domLoading||0),a=performance.timing.domContentLoadedEventEnd-(performance.timing.navigationStart||0),c=(performance.timing.loadEventEnd||performance.timing.domComplete)-(performance.timing.navigationStart||0);return{collect:function(){return t()},print:function(){var t=document.getElementById("debug"),n=this.formatDebugInfo();if(t)t.innerHTML+=n;else{var e=document.createElement("div");e.id="debug",e.innerHTML=n,document.body.appendChild(e)}},formatDebugInfo:function(){var t="<p>";return t+="timing object : "+JSON.stringify(this.collect(),null,2)+"<br/>",t+="url: "+decodeURIComponent(window.location.href)+"<br/>",t+="</p>"}}},r={init:function(t){if(this.enable=!0,this.debug=t,!("performance"in window))return void(this.enable=!1)},collect:function(){if(this.enable){var t=e(),n=t.collect();return this.debug&&t.print(),n}}};t.exports=r}]);
  20 + }
  21 + </script>
13 <script type="text/javascript"> 22 <script type="text/javascript">
14 (function(d,c){var e=d.documentElement,a="orientationchange" in window?"orientationchange":"resize",b=function(){var f=e.clientWidth;if(!f){return}if(f>=750){e.style.fontSize="40px"}else{e.style.fontSize=40*(f/750)+"px"}};if(!d.addEventListener){return}b();c.addEventListener(a,b,false);d.addEventListener("DOMContentLoaded",b,false)})(document,window); 23 (function(d,c){var e=d.documentElement,a="orientationchange" in window?"orientationchange":"resize",b=function(){var f=e.clientWidth;if(!f){return}if(f>=750){e.style.fontSize="40px"}else{e.style.fontSize=40*(f/750)+"px"}};if(!d.addEventListener){return}b();c.addEventListener(a,b,false);d.addEventListener("DOMContentLoaded",b,false)})(document,window);
15 </script> 24 </script>
@@ -12,9 +12,48 @@ module.exports = [ @@ -12,9 +12,48 @@ module.exports = [
12 cache: true 12 cache: true
13 }, 13 },
14 { 14 {
  15 + route: /grass\/article\/share\/\d+/,
  16 + cacheKey: '$url$params',
  17 + cacheTime: 900,
  18 + cache: true
  19 + },
  20 + {
  21 + route: /grass\/article\/detail\/\d+/,
  22 + cacheKey: '$url$params',
  23 + cacheTime: 900,
  24 + cache: true
  25 + },
  26 + {
15 route: /grass\/author\/\d+\/\d+/, 27 route: /grass\/author\/\d+\/\d+/,
16 cacheKey: '$url$params', 28 cacheKey: '$url$params',
17 cacheTime: 900, 29 cacheTime: 900,
18 cache: true 30 cache: true
19 - } 31 + },
  32 + {
  33 + route: /grass\/author\/mine/,
  34 + cacheKey: '$url$params',
  35 + cache: false
  36 + },
  37 + {
  38 + route: /grass\/author\/follow\/\d+\/\d+/,
  39 + cacheKey: '$url$params',
  40 + cacheTime: 900,
  41 + cache: true
  42 + },
  43 + {
  44 + route: /grass\/author\/fans\/\d+\/\d+/,
  45 + cacheKey: '$url$params',
  46 + cacheTime: 900,
  47 + cache: true
  48 + },
  49 + {
  50 + route: /grass\/mine\/follow/,
  51 + cacheKey: '$url$params',
  52 + cache: false
  53 + },
  54 + {
  55 + route: /grass\/mine\/fans/,
  56 + cacheKey: '$url$params',
  57 + cache: false
  58 + },
20 ]; 59 ];
@@ -37,6 +37,9 @@ const getContext = (req) => { @@ -37,6 +37,9 @@ const getContext = (req) => {
37 return { 37 return {
38 url: req.url, 38 url: req.url,
39 title: req.query.share_title || '', 39 title: req.query.share_title || '',
  40 + zk: {
  41 + webperf: process.env.NODE_ENV === 'production' && _.get(req.app.locals.wap, 'open.webperf', false)
  42 + },
40 user: req.user, 43 user: req.user,
41 env: { 44 env: {
42 isApp: req.yoho.isApp, 45 isApp: req.yoho.isApp,
@@ -50,6 +53,7 @@ const getContext = (req) => { @@ -50,6 +53,7 @@ const getContext = (req) => {
50 route: `[${req.method}]${_.get(req, 'route.path', '')}`, // 请求路由 53 route: `[${req.method}]${_.get(req, 'route.path', '')}`, // 请求路由
51 udid: _.get(req, 'cookies.udid', 'yoho'), 54 udid: _.get(req, 'cookies.udid', 'yoho'),
52 path: `[${req.method}]${routeEncode.getRouter(req)}`, 55 path: `[${req.method}]${routeEncode.getRouter(req)}`,
  56 + routeHash: routeEncode.getRouter(req)
53 }; 57 };
54 }; 58 };
55 59
@@ -2,13 +2,7 @@ const _ = require('lodash'); @@ -2,13 +2,7 @@ const _ = require('lodash');
2 const crypto = global.yoho.crypto; 2 const crypto = global.yoho.crypto;
3 3
4 function urlJoin(a, b) { 4 function urlJoin(a, b) {
5 - if (_.endsWith(a, '/') && _.startsWith(b, '/')) {  
6 - return a + b.substring(1, b.length);  
7 - } else if (!_.endsWith(a, '/') && !_.startsWith(b, '/')) {  
8 - return a + '/' + b;  
9 - } else {  
10 - return a + b;  
11 - } 5 + return _.trimEnd(a, '/') + '/' + _.trimStart(b, '/');
12 } 6 }
13 7
14 function _encode(str) { 8 function _encode(str) {
@@ -24,7 +18,6 @@ function getRouter(req) { @@ -24,7 +18,6 @@ function getRouter(req) {
24 if (_.isArray(route) && route.length > 0) { 18 if (_.isArray(route) && route.length > 0) {
25 route = route[0]; 19 route = route[0];
26 } 20 }
27 -  
28 let key = urlJoin(appPath, route.toString()); // route may be a regexp 21 let key = urlJoin(appPath, route.toString()); // route may be a regexp
29 22
30 if (key) { 23 if (key) {