首屏加载时间计算

发布时间:2022-06-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了首屏加载时间计算脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

文章:https://cloud.tencent.COM/develoPEr/article/1850013

 

function getFirstScreenTime() { const details = []; return new Promise(function (resolve, reject) { // 5s之内先收集所有的dom变化,并以key(时间戳)、value(dom list)的结构存起来。

const observeDom = observeDoc(details);

setTimeout(function () { observeDom.disconnect(); console.LOG('details', details); resolve(details); }, 5000); }).then(function (details) { return compareTime(details); });}

// 监听文档function observeDoc(details) { VAR observeDom = new MutationObserver(function (mutations) { if (!mutations || !mutations.foreach) return; var detail = { time: performance.now(), roots: [], imgs: [], };

mutations.forEach(function (mutation) { if (!mutation || !mutation.addedNodes || !mutation.addedNodes.forEach) { return; } mutation.addedNodes.forEach(function (ele) { const nodeName = ele.nodeName.toLocaleLowerCase(); const isImg = nodeName === 'img'; const isValidEle = isEleValid(ele, detail.roots); if (isValidEle) { detail.roots.push(ele); if (isImg) { detail.imgs.push(ele); } } }); }); if (detail.roots.length) { details.push(detail); } }); observeDom.observe(document, { childList: true, suBTree: true, }); return observeDom;}

// 比较首屏内DOM时间function compareTime(details) { // 分析上面收集到的数据,返回最终的结果 const domRenderTime = []; const allImgs = []; const allImgLoadTimes = [];

details.forEach(function (detail) { // 拿到所有首屏DOM 的 渲染时间 for (var i = 0; i < detail.roots.length; i++) { const ele = detail.roots[i]; if (isInFSAndVisible(ele)) { domRenderTime.push(detail.time); // 同一个 detail 的 节点,时间一样,不用继续收集了 break; } }

// 拿到所有首屏中的图片 for (var i = 0; i < detail.imgs.length; i++) { const ele = detail.imgs[i]; if (isInFSAndVisible(ele)) { allImgs.push(ele.src); } } });

// 遍历当前请求的图片中,如果有开始请求时间在首屏dom渲染期间的,则表明该图片是首屏渲染中的一部分, // 所以dom渲染时间和图片返回时间中大的为首屏渲染时间 window.performance.getEntriesByType('resource').forEach(function (resource) { const url = resource.name; if (resource.inITiatorType === 'img' && allImgs.indexOf(url) > -1) { allImgLoadTimes.push(resource.responseEnd); } });

console.log('allImgs', allImgs); console.log('domRenderTime', domRenderTime); console.log('allImgLoadTimes', allImgLoadTimes);

const resultTime = Math.max(...domRenderTime, ...allImgLoadTimes);

return resultTime;}

// 节点是否有效function isEleValid(ele, arr) { const ignoreEleList = ['script', 'style', 'link', 'br']; const nodeName = ele.nodeName.toLocaleLowerCase(); const isEleNode = ele.nodeType === 1; const isRenderNode = ignoreEleList.indexOf(nodeName) !== -1; if (isEleNode && isRenderNode) { if (isInFS(ele)) { if (!isElderOrExitEle(ele, arr)) { return true; } } } return false;}

// dom 是否有效,过滤function isEleValid(ele, arr) { const ignoreEleList = ['script', 'style', 'link', 'br']; const nodeName = ele.nodeName.toLocaleLowerCase(); const isEleNode = ele.nodeType === 1; const isRenderNode = ignoreEleList.indexOf(nodeName) === -1; if (isEleNode && isRenderNode) { if (isInFS(ele)) { if (!isElderOrExitEle(ele, arr)) { return true; } // 图片另算 else if (nodeName === 'img') { return true; } } } return false;}

// 是否已经存在节点,或者是长辈节点function isElderOrExitEle(target, arr) { if (!target || target === document.documentElement) { return false;

// 说明数组已经存在这个节点 } else if (arr.indexOf(target) !== -1) { return true;

// 不要长辈节点 } else { return isElderOrExitEle(target.parentElement, arr); }}

// 位置是否首屏中function isInFS(target) { if (!target || !target.getBoundingClientRect) return false; var rect = target.getBoundingClientRect(), screenHeight = window.innerHeight, screenWidth = window.innerWidth; return ( rect.left >= 0 && rect.left < screenWidth && rect.top >= 0 && rect.top < screenHeight );}

// 首屏中,并且可见function isInFSAndVisible(target) { if (!target || !target.getBoundingClientRect) return false; var rect = target.getBoundingClientRect(); const isvisible = isVisible(target); const hasArea = rect.width > 0 && rect.height > 0;

return isInFS(target) && hasArea && isvisible;}

// 是否可见function isVisible(target) { target.style.opacity = 'inherit'; var rawOpacity = getStyle(target, 'opacity'); var visibility = getStyle(target, 'visibility');

var opacity = +rawOpacity; if (opacity != rawOpacity) { opacity = 1; // can not check old browser } if (opacity > 0.09 || visibility === 'visible') { return true; } return false;}

// 获取样式function getStyle(el, name) { if (window.getComputedStyle) { return getComputedStyle(el, null)[name]; } if (el.currentStyle) { return el.currentStyle[name]; }}

脚本宝典总结

以上是脚本宝典为你收集整理的首屏加载时间计算全部内容,希望文章能够帮你解决首屏加载时间计算所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。