当前位置: 首页 > news >正文

制作网页网站教程服务器和域名大概需要多少钱

制作网页网站教程,服务器和域名大概需要多少钱,免费自己制作app手机软件,杭州做网站价格前言 页面白屏,绝对是让前端开发者最为胆寒的事情,特别是随着 SPA 项目的盛行,前端白屏的情况变得更为复杂且棘手起来( 这里的白屏是指页面一直处于白屏状态 ) 要是能检测到页面白屏就太棒了,开发者谁都不…

前言

页面白屏,绝对是让前端开发者最为胆寒的事情,特别是随着 SPA 项目的盛行,前端白屏的情况变得更为复杂且棘手起来( 这里的白屏是指页面一直处于白屏状态 )
要是能检测到页面白屏就太棒了,开发者谁都不想成为最后一个知道自己页面白的人😥
web-see 前端监控方案,提供了 采样对比+白屏修正机制 的检测方案,兼容有骨架屏、无骨架屏这两种情况,来解决开发者的白屏之忧

知道页面白了,然后呢?

web-see 前端监控,会给每次页面访问生成一个唯一的uuid,当上报页面白屏后,开发者可以根据白屏的uuid,去监控后台查询该id下对应的代码报错、资源报错等信息,定位到具体的源码,帮助开发者快速解决白屏问题

白屏检测方案的实现流程

采样对比+白屏修正机制的主要流程:
1、页面中间取17个采样点(如下图),利用 elementsFromPoint api 获取该坐标点下的 HTML 元素
2、定义属于容器元素的集合,如

[‘html’, ‘body’, ‘#app’, ‘#root’]

3、判断17这个采样点是否在该容器集合中。说白了,就是判断采样点有没有内容;如果没有内容,该点的 dom 元素还是容器元素,若17个采样点都没有内容则算作白屏
4、若初次判断是白屏,开启轮询检测,来确保白屏检测结果的正确性,直到页面的正常渲染
采样点分布图(蓝色为采样点):
在这里插入图片描述

如何使用

import webSee from 'web-see';Vue.use(webSee, {dsn: 'http://localhost:8083/reportData', // 上报的地址apikey: 'project1', // 项目唯一的iduserId: '89757', // 用户idsilentWhiteScreen: true, // 开启白屏检测skeletonProject: true, // 项目是否有骨架屏whiteBoxElements: ['html', 'body', '#app', '#root'] // 白屏检测的容器列表
});

下面聊一聊具体的分析与实现

白屏检测的难点

1) 白屏原因的不确定

从问题推导现象虽然能成功,但从现象去推导问题却走不通。白屏发生时,无法和具体某个报错联系起来,也可能根本没有报错,比如关键资源还没有加载完成
导致白屏的原因,大致分两种:资源加载错误、代码执行错误
2) 前端渲染方式的多样性
前端页面渲染方式有多种,比如 客户端渲染 CSR 、服务端渲染 SSR 、静态页面生成 SSG 等,每种模式各不相同,白屏发生的情况也不尽相同
很难用一种统一的标准去判断页面是否白了

技术方案调研

如何设计出一种,在准确性、通用型、易用性等方面均表现良好的检测方案呢?
本文主要讨论 SPA 项目的白屏检测方案,包括有无骨架屏的两种情况
方案一:检测根节点是否渲染
原理很简单,在当前主流 SPA 框架下,DOM 一般挂载在一个根节点之下(比如 <div id="app"></div> ),发生白屏后通常是根节点下所有 DOM 被卸载,该方法通过检测根节点下是否挂载 DOM,若无则证明白屏
这是简单明了且有效的方案,但缺点也很明显:其一切建立在 白屏 === 根节点下 DOM 被卸载 成立的前提下,缺点是通用性较差,对于有骨架屏的情况束手无策
方案二:Mutation Observer 监听 DOM 变化
通过此 API 监听页面 DOM 变化,并告诉我们每次变化的 DOM 是被增加还是删除
但这个方案有几个缺陷
1)白屏不一定是 DOM 被卸载,也有可能是压根没渲染,且正常情况也有可能大量 DOM 被卸载
2)遇到有骨架屏的项目,若页面从始至终就没变化,一直显示骨架屏,这种情况 Mutation Observer 也束手无策
方案三:页面截图检测
这种方式是基于原生图片对比算法处理白屏检测的 web 实现
整体流程:对页面进行截图,将截图与一张纯白的图片做对比,判断两者是否足够相似
但这个方案有几个缺陷:
1、方案较为复杂,性能不高;一方面需要借助 canvas 实现前端截屏,同时需要借助复杂的算法对图片进行对比
2、通用性较差,对于有骨架屏的项目,对比的样张要由纯白的图片替换成骨架屏的截图
方案四:采样对比
该方法是对页面取关键点,进行采样对比,在准确性、易用性等方面均表现良好,也是最终采用的方案

对于有骨架屏的项目,通过对比前后获取的 dom 元素是否一致,来判断页面是否变化(这块后面专门讲解)

采样对比代码:

// 监听页面白屏
function whiteScreen() {// 页面加载完毕function onload(callback) {if (document.readyState === 'complete') {callback();} else {window.addEventListener('load', callback);}}// 定义外层容器元素的集合let containerElements = ['html', 'body', '#app', '#root'];// 容器元素个数let emptyPoints = 0;// 选中dom的名称function getSelector(element) {if (element.id) {return "#" + element.id;} else if (element.className) {// div home => div.homereturn "." + element.className.split(' ').filter(item => !!item).join('.');} else {return element.nodeName.toLowerCase();}}// 是否为容器节点function isContainer(element) {let selector = getSelector(element);if (containerElements.indexOf(selector) != -1) {emptyPoints++;}}onload(() => {// 页面加载完毕初始化for (let i = 1; i <= 9; i++) {let xElements = document.elementsFromPoint(window.innerWidth * i / 10, window.innerHeight / 2);let yElements = document.elementsFromPoint(window.innerWidth / 2, window.innerHeight * i / 10);isContainer(xElements[0]);// 中心点只计算一次if (i != 5) {isContainer(yElements[0]);}}// 17个点都是容器节点算作白屏if (emptyPoints == 17) {// 获取白屏信息console.log({status: 'error'});}}
}

白屏修正机制
若首次检测页面为白屏后,任务还没有完成,特别是手机端的项目,有可能是用户网络环境不好,关键的JS资源或接口请求还没有返回,导致的页面白屏
需要使用轮询检测,来确保白屏检测结果的正确性,直到页面的正常渲染,这就是白屏修正机制
白屏修正机制图例:
在这里插入图片描述
轮询代码:

// 采样对比
function sampling() {let emptyPoints = 0;……// 页面正常渲染,停止轮询if (emptyPoints != 17) {if (window.whiteLoopTimer) {clearTimeout(window.whiteLoopTimer)window.whiteLoopTimer = null}} else {// 开启轮询if (!window.whiteLoopTimer) {whiteLoop()}}// 通过轮询不断修改之前的检测结果,直到页面正常渲染console.log({status: emptyPoints == 17 ? 'error' : 'ok'});
}
// 白屏轮询
function whiteLoop() {window.whiteLoopTimer = setInterval(() => {sampling()}, 1000)
}

骨架屏

对于有骨架屏的页面,用户打开页面后,先看到骨架屏,然后再显示正常的页面,来提升用户体验;但如果页面从始至终都显示骨架屏,也算是白屏的一种

骨架屏示例:
在这里插入图片描述
骨架屏的原理
无论 vue 还是 react,页面内容都是挂载到根节点上。常见的骨架屏插件,就是基于这种原理,在项目打包时将骨架屏的内容直接放到 html 文件的根节点中

有骨架屏的html文件:
在这里插入图片描述
骨架屏的白屏检测
上面的白屏检测方案对有骨架屏的项目失灵了,虽然页面一直显示骨架屏,但判断结果页面不是白屏,不符合我们的预期
需要通过外部传参明确的告诉 SDK,该页面是不是有骨架屏,如果有骨架屏,通过对比前后获取的 dom 元素是否一致,来实现骨架屏的白屏检测
完整代码:

/*** 检测页面是否白屏* @param {function} callback - 回到函数获取检测结果* @param {boolean} skeletonProject - 页面是否有骨架屏* @param {array} whiteBoxElements - 容器列表,默认值为['html', 'body', '#app', '#root']*/
export function openWhiteScreen(callback, { skeletonProject, whiteBoxElements }) {let _whiteLoopNum = 0;let _skeletonInitList = []; // 存储初次采样点let _skeletonNowList = []; // 存储当前采样点// 项目有骨架屏if (skeletonProject) {if (document.readyState != 'complete') {sampling();}} else {// 页面加载完毕if (document.readyState === 'complete') {sampling();} else {window.addEventListener('load', sampling);}}// 选中dom点的名称function getSelector(element) {if (element.id) {return '#' + element.id;} else if (element.className) {// div home => div.homereturn ('.' + element.className.split(' ').filter(item => !!item).join('.'));} else {return element.nodeName.toLowerCase();}}// 判断采样点是否为容器节点function isContainer(element) {let selector = getSelector(element);if (skeletonProject) {_whiteLoopNum ? _skeletonNowList.push(selector) : _skeletonInitList.push(selector);}return whiteBoxElements.indexOf(selector) != -1;}// 采样对比function sampling() {let emptyPoints = 0;for (let i = 1; i <= 9; i++) {let xElements = document.elementsFromPoint((window.innerWidth * i) / 10,window.innerHeight / 2);let yElements = document.elementsFromPoint(window.innerWidth / 2,(window.innerHeight * i) / 10);if (isContainer(xElements[0])) emptyPoints++;// 中心点只计算一次if (i != 5) {if (isContainer(yElements[0])) emptyPoints++;}}// 页面正常渲染,停止轮训if (emptyPoints != 17) {if (skeletonProject) {// 第一次不比较if (!_whiteLoopNum) return openWhiteLoop();// 比较前后dom是否一致if (_skeletonNowList.join() == _skeletonInitList.join())return callback({status: 'error'});}if (window._loopTimer) {clearTimeout(window._loopTimer);window._loopTimer = null;}} else {// 开启轮训if (!window._loopTimer) {openWhiteLoop();}}// 17个点都是容器节点算作白屏callback({status: emptyPoints == 17 ? 'error' : 'ok',});}// 开启白屏轮训function openWhiteLoop() {if (window._loopTimer) return;window._loopTimer = setInterval(() => {if (skeletonProject) {_whiteLoopNum++;_skeletonNowList = [];}sampling();}, 1000);}
}

如果不通过外部传参,SDK 能否自己判断是否有骨架屏呢? 比如在页面初始的时候,根据根节点上有没有子节点来判断
因为这套检测方案需要兼容 SSR 服务端渲染的项目,对于 SSR 项目来说,浏览器获取 html 文件的根节点上已经有了 dom 元素,所以最终采用外部传参的方式来区分

总结

这套白屏检测方案是从现象推导本质,可以覆盖绝大多数 SPA 项目的应用场景
小伙们若有其他检测方案,欢迎多多讨论与交流 💕

http://www.yayakq.cn/news/248449/

相关文章:

  • 建设银行成都市第九支行 网站如何建设网站24小时接单
  • wordpress公司网站模板网站结构分析怎么做
  • 中小网站建设都有哪些方案人事代理网站建设
  • 江西建设厅官方网站workpress做静态网站
  • 做企业网站需要多少钱seo营销
  • 建设部施工安全管理网站网站名称图标如何做才能显示
  • 江苏省工程建设协会网站wordpress文章自动标签
  • 网站的运行环境万网关键词优化是什么意思
  • 安远做网站盗qq的钓鱼网站怎么做
  • 东莞樟木头网站建设seo技术团队
  • 阜阳城乡建设档案馆网站什么是网络营销企业
  • 用c 做网站网站解析加速
  • 网站做好了 怎么做解析如今做哪个网站致富
  • 设计公司一般多少人潍坊百度搜索优化
  • 长沙网站建站html5 手机网站 模版
  • 江永网站建设夜月直播下载直播
  • wordpress後台建站电商软件开发平台
  • 网站建设需要投资多少网站建设维护人员
  • 建网站建网站的公司wordpress 企业网站制作
  • 牡丹江网站建设公司网站为什么需要备案号
  • 网站开发求职信网站建设xm37
  • 网站制作论文优帮云写作网站的文风
  • 泰州城乡建设网站wordpress的安装包
  • 网站建设 深度网平面图在线设计
  • python做网站验证码百度站长平台网址
  • 中国备案查询网站石岩做网站哪家好
  • 东莞网上商城网站建设旅游攻略网站
  • 打开网站自动弹出qq品牌建设是什么意思
  • jsp网站开发的环境要求注册网站费用
  • 免费做网站网站有人哪些广州建站代运营公司有哪些