外链论坛

 找回密码
 立即注册
搜索
查看: 1|回复: 0

百度程序员研发避坑指南(前端篇)

[复制链接]

2605

主题

148

回帖

9912万

积分

论坛元老

Rank: 8Rank: 8

积分
99120793
发表于 4 小时前 | 显示全部楼层 |阅读模式

平常工作研发中,遇到那些坑是让你印象深刻且拥有挑战的,它们是怎么产生的,咱们怎样避免?本期咱们带来与前端研发关联的三个问题:一次网页资源加载问题的定位过程;CSS中的z-index层叠覆盖问题;CSS3 transform 属性对 position 的影响,期盼能为你的技术提高助力。

01

一次网页资源加载问题的定位过程今天讨论的专题比较聚焦,便是有用户报Web页面资源或局部区域加载不出来的问题,该怎样查?又该怎样避免?

1.1 问题描述

用户反馈页面内的举荐列表加载不出来,况且能稳定复现。

1.2 分析

第1反应便是自己复现,然则不行啊,团队朋友能复现,没法接触到用户。那样先理清楚此区域的实现逻辑,该区域的HMTL虽然已然下载,但默认不可见,而是依赖c.js(文件名简化了)展现。基于此,咱们可疑

c.js 以及其依赖的a.js, b.js等 加载非常慢或直接失败;

c.js 以及其依赖规律出现JS反常

1.3 监控实现

那样怎样佐证,咱们需要做下监控。做监控需要思虑实质场景,因为Head和Body都有外链请求,因此呢监控代码要置于顶部且内联,且代码要精简,从而能够最大程度拿到信息和减少首屏影响。window.addEventListener(error, event => { if (event.srcElement !== window) { console.log(资源加载失败,加载资源的元素是:, event.srcElement); send(); } else { console.log(JS报错:, event.message); send(); }}, true);window.addEventListener(unhandledrejection, event => { consterror = event.reason || {}; console.log(JS报错:, error); send();});以上能够监控到全局的 资源加载失败 和 JS反常包含捕捉的Promise Rejection。另外,还需定位资源,经过向上遍历获取元素的XPath,XPath上带上id或class属性,避免全都是`div>div>div>div`,而摸不着头脑。上线后发掘,有不少错误都是script error,这是由于外链JS都是CDN域名。浏览器针对脚本执行遵守 same-origin policy ,为避免域名信息泄漏给宿主域名,特意隐匿错误信息。处理方法是给所有外链JS加上响应头。access-control-allow-origin: *JS资源若托管在云上CDN服务,那样其CDN掌控台都会供给增多Header功能。若是自有服务,就需要主动设置Header。这儿假设运用Koa2 框架,设置如下:ctx.set(Access-Control-Allow-Origin, *);

而后给所有该CDN域名的script元素增多crossorigin属性,如:

<script src="https://cdn.a.com/static/a.js" crossorigin="anonymous"></script>发掘其在Chrome浏览器是生效的,能够拿到真实错误堆栈。可惜,Safari浏览器不支持此机制,依然只能拿到script error。为了Safari拿到真实错误,外链需要是同域。因此呢有个办法是在www.a.com的Nginx做一层代理转发,即 https://www.a.com/static/a.js 转发到 https://cdn.a.com/static/a.js  。不外如此一来,就丧失CDN就近拜访优良,不适合常态化。但能够在定位用户问题时,将用户拜访临时切换成 https://www.a.com/static/a.js。怎样监控加载慢,能够在onload事件后获取慢资源。const list = performance.getEntriesByType(resource);const len = list.length;const slowList = [];for (let i = 0; i < len; i++) { const timing = list[i]; // 大于1s if (timing.duration > 1000) {slowList.push(timing); }}send(slowList);上报信息包括每一个请求的TCP、下载等耗时,仔细可见Resource_Timing_API规范(https://developer.mozilla.org/en-US/docs/Web/API/Resource_Timing_API/Using_the_Resource_Timing_API)重视的是,该API信息受到CORS (https://developer.mozilla.org/en-US/docs/Glossary/CORS)影响,必须给资源设置如下响应头才可拿到数据,否则非常多字段取值都是0。Timing-Allow-Origin: *经过分析这些数据,咱们能够晓得资源耗时过程,这儿能够充分参照Chrome研发者工具供给的Timing子面板,认识关键时段耗时。例如同域名6个并发请求限制,若资源请求较多,则可能处在stalled(挂起等待)状态。这些周期可能原由分析参考Chrome说明

因为有些照片在页面内欠好确定位置,因此呢需要获取其XPath,怎样获取呢?针对img标签加载照片能够快速获取:// timing.name便是资源位置,适合const img = document.body.querySelector(img[src=" + timing.name + "]);const xpath = getxpath(img);额外信息获取,其实除了问题信息本身外,用户当时环境信息非常重要,如1. performance.memory:获取内存运用信息;2. navigator.connection:用户连接状况,可惜,此API不怎么准;倘若是APP内页面,能够调用端能力获取到用户网络类型、网速。

1.4 数据分析

上线后,用户依然拜访慢。按照日志发掘,用户未有JS报错,但按照慢资源日志,发掘海量资源加载超过1s,有些资源乃至达到10s,其花费在建连周期耗时很强。看来问题还不是这么简单,那怎样解释用户资源加载如此慢?用户所在局域网环境差?接入运营商质量差?插件影响?CDN问题?这些问题仅有CDN能够去排查,咱们首要拿到用户拜访 https://www.a.com 的服务器端日志,获取到用户IP。联合云CDN服务,按照用户IP,竟然未查到任何CDN拜访日志。但从日志看,用户确实请求了海量JS,并不是所有本地缓存。因此用户IP可能不是拜访CDN的IP,有一种状况运用代理。因此经过其他信息捞取用户的CDN日志,来确定拜访CDN的IP。思路是根据用户UA、请求位置等非精确信息捞取CDN日志,但因为捞取日志量非常大,没法确定那些日志是该用户的;而:1.CDN域名通常是无cookie域名,TRACEID;2.Web页面没法给script/link资源请求头设置Traceid;3.前端日前没法拿到CDN TCP建连IP;综上,除了用户IP,种种精确定位信息都无效。因此呢这一步举步维艰。好在能联系上用户,咨询是不是运用代理,结果:确实运用了代理,且按照用户代理,实测代理非常慢,乃至加载超时,其代理请求走了香港服务器。经过代理出口IP,最后从海外CDN捞取到了用户拜访日志。同期确认,用户将所有 *.a.com 请求配置不使用代理,因此服务端能拿到的IP是用户IP,而CDN拿到的是代理出口IP。

1.5 总结

Web能力终是有限,但经过足够的辅助信息,以及全链路协作,在定位Case过程中会事半功倍。该Case虽然归因于用户不恰当代理配置,但可基于此场景做技术优化。如任何首屏内容不依赖外链展现,减少核心规律JS体积,增多资源缓存率等。

02

CSS中的z-index层叠覆盖问题

2.1 含义

z-index属性指定了元素及其子元素的【z次序】,而【z次序能够决定当元素出现覆盖的时候,哪个元素在上面。一般一个很强的z-index值的元素会覆盖较低的那一个。属性指定两件事:当前元素的堆叠次序当前元素是不是创立新的堆叠上下文

2.2 属性值

默认值:z-index:auto;整数值:z-index:<integer>;继承:z-index:inherit;

2.3 基本特性

在CSS2.1时代,需要和定位元素协同运用倘若定位元素z-index出现嵌套(并列的):后来者居上的准则;哪个大哪个上(z-index体积比较);倘若定位元素z-index出现嵌套:祖先优先原则(前提:z-index是数值,不是auto)以上为z-index的基本介绍。当业务越来越繁杂,多种弹窗、toast、浮层各样组件,多人协同业务研发状况下:老业务写了个z-index:5000;B朋友调用一个全局弹层,本来设置为100,想要覆盖全局,z-index改为10000;C朋友调用一个toast,本来设置为2000,想要覆盖弹层,z-index改为100000;...层层覆盖的状况下,不可无限改下去,为了避免这般状况出现,减少持续覆盖的状况那样应该怎样规定z-index的值呢;
const KEY = _tbv_z_index_;function initZIndex$() { return (window[KEY] = 10000);}// 初始化,只能被调用一次function once(fn) { const flag = true; return function () { if (flag) { flag = false; const args = Array.prototype.slice.call(arguments, 0); fn.apply(args); } };}const initZIndex = once(initZIndex$);// 外边调用&支持重置function zIndex$(zIndex) { if (zIndex) { return (window[KEY] = zIndex); } return (window[KEY] += 1);}// 组件mount时触发+1const zIndex = zIndex$();
重视还是要规范z-index的配置,不要乱用乱用随意赋值,按照依赖规则恰当运用

03

CSS3 transform 属性对 position 的影响

CSS3中引入了transform,定义了在二维或三维空间中元素的旋转、缩放、平移等行径,还能利用合成层原理开启GPU加速,提高页面动画的流畅度。然而transform不是「省油的灯」(并说它欠好的意思,我就很爱好它),加强了页面交互效果的同期有些「副功效」容易让人踩坑。

position: fixed 实现了固定定位的效果,元素不追随滚动条进行滚动,普通元素的overflow属性没法对其进行裁剪,因此呢有些需要固定头部、固定悬浮按钮的场景中非常好用。

但fixed遇上transform时表现的就再也不那样「强硬」,反而退化成为了position: absolute的效果。在外层transform影响时,固定定位元素的包括块是根元素,能够近似认为是<html>元素,因此呢fixed元素能够实现相对视口定位的效果。而当元素设置了transform时,便会创建一个新的包括块(containing block),倘若该元素的内部有元素设置了fixed定位,那样该fixed元素的包括块便再也不是根元素,而变成为了被设置了transform的元素。倘若研发过程中发掘设置了position:fixed的元素随着页面滚动了,就能够看下fixed的元素外层是不是有元素设置了transfrom。

除了包括块之外,transform还会生成新的层叠上下文(stack context),使得元素内部和外边的z-index相互独立,显现低z-index元素层级比高z-index元素还高的状况

举荐阅读:

百度工程师教你快速提高开发效率小技巧

百度一线工程师浅谈日新月异的云原生

【技术加油站】揭秘百度智能测试规模化落地

【技术加油站】浅谈百度智能测试的三个周期

一键三连,好运连连,bug不见
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|外链论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-10-3 17:28 , Processed in 0.070075 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.