从前端的角度,梳理一下,一团代码是如何渲染到网页上的
image.png渲染机制
image.png image.png image.png
- <!DOCTYPE> 声明位于文档中的最前面,处于 <html> 标签之前。告知浏览器的解析器, 用什么文档类型 规范来解析这个文档
- 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行
- 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。 DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现
DOM相当于文档对象模型
image.png image.png image.png image.png image.png一般情况下导致了reflow都会导致repaint
image.png如果避免最小程度的repaint?
一次性的向页面中插入节点,不要做一次啊操作从新一次
js运行机制
image.pngjs是单线程的,大白话来理解就是js在同一时间只能做一件事。
任务队列:
同步任务,异步任务。settimeout setInterval 异步任务。console.log -->同步任务。
js任务队列是有优先级的,同步任务优先于异步任务。先处理完同步,再处理异步。
eg:
<script type="text/javascript">
console.log(1);
setTimeout(function(){
console.log(2);
},0);
console.log(3);
</script>
输出:
image.png image.png
console.log('A');
while(true){}
console.log('B');
输出结果:
image.png
打印了A之后,会在while(true){} 那里一直无限循环 进入不了下一步
console.log('A);
setTimeout(function(){
console.log('B');
},0)
while(true){}
这个输出结果跟上面相同。
上面这2个例子是说明 同步任务和异步任务的优先顺序
这个例子是为了说明 异步任务的放入时间和执行时间
image.png
输出
image.png
我用大白话来解释一下这个原理:for语句是一个同步的任务,当执行i=0的时候,遇到了延时(setTimeout) 延时 等定时器时间到了 才会把它放在异步任务队列中,然后等待同步执行完,再执行异步。
IMG_1782.JPG image.png
JS单线程 我再啰嗦一遍 一个时间之内 JS只能干一件事情
任务队列 如上
image.png运行栈里面放的是同步任务 异步任务是没法放在里面的 让浏览器识别到settimeout或者setinterval这些异步任务的时候,是不会把它放在运行栈里面的,如果有延时,就等到延时时间到了,把它放入任务队列中。特别注意一点settimeout中的0,一般是4ms,小于4ms的都会按照4ms,这是浏览器的规定。
如果任务栈空了,就会去执行异步任务中的任务队列。
image.pngdom事件中的点击什么的事件的 等等。
总结:
image.png
页面性能类
image.pngcdn很重要
cdn加速
cdn加速是实现加速访问速度。特点是有助于减轻源站压力,提高访问速度,隐藏源服务器等。
DNS预解析:
<meta http-equiv="x-dns=prefetch-control" content="on">这句话的意思:
页面中a标签在高级浏览器中默认 打开了dns预解析。可以就这句话也不错。
但是在http4协议开头 都是默认关闭
这篇博客讲解的比较详细:https://blog.csdn.net/guoqingcun/article/details/52142076
异步加载
image.png动态脚本加载,就是用documentcrateelement一个scrip标签,已经就是用js创建这么个标签,然后把它加在head或者body里面都可以。就是动态创建节点嘛
defer和async怎么用呢?就是在加载的scrip的标签上,加上这2个属性 就可以了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>性能优化</title>
<script src="./deferl.js" charset="UTF-8" defer="defer"></script>
<script src="defer2.js" charset="UTF-8" defer="defer"></script>
</head>
<body>
<div class="">
test
<script type="text/javascript">
console.log('write');
document.write('<span>write</span>')
</script>
<script type="text/javascript">
for(var i=0;i<20000;i++){
if(i%2000===0){
console.log(i);
}
}
</script>
</div>
</body>
</html>
输出:
image.png
<script src="./async1.js" charset="UTF-8" async></script>
<script src="./async2.js" charset="UTF-8" async></script>
image.png
image.png
1 和 2的顺序 不一定
浏览器缓存
image.png强缓存是指 强制缓存,问都不问,就直接缓存。
协商缓存,和服务器协商这个文件能不能用。就是浏览器发现本地有这个副本,但是不确定用不用它,就去跟服务器进行协商,问一下,我这个文件要不要用。
接下来将HTTP协议的头,我请求一个文件的时候,http的响应头上会携带1个或2个东西(这个数量主要看服务器的配置).一个是expires(过期时间),zhe
这里相当一个key value,这里的value值表示的是绝对时间,所以这个时间一般是由服务器下发的,服务器的绝对时间。客服端的时间有可能跟服务器的不一样,这也就是为什么新增加了一个:cache-control。
cache-control是相对时间,相对于客户端时间,只要在3600s之内,都不会再去服务器拿,直接在浏览器本地拿缓存。
如果2者都有,以后者为准。
接下来说说协商缓存 。
与协商缓存相关的有这四个,一个是last-modified:上次修改的时间,当强缓存失效,过期了,请求的时候会以“if-modified-since”这个字段,并且携带这个字段的时间 image.png去给服务器。
Etag是hash值,就是出现这么个情况,假如只是强缓存的时间过期了,但是内容没变,这个时候就用到了etag,可以进行match。
这个回答说的很准确。https://zhuanlan.zhihu.com/p/33232074
错误监控
image.png image.png image.pngnotice:window.onerror只能捕获及时运行错误
资源加载错误 不会冒泡 object.onerror,不会触发到window.onerror上。
performance.getEntries()这个方法用于间接获得资源加载错误。
在这里举一个例子:
这次都是成功加载 的资源。
比如我们判断哪个图片没有加载成功,先取到所有的标签节点
image.png
然后再相减,就可以得到哪些没有加载成功。
Error事件捕获,是在捕获阶段拿到错误。
下面演示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>错误捕获</title>
<script type="text/javascript">
window.addEventListener('error',function(e){
console.log('捕获',e);
},true);
</script>
</head>
<body>
<script src="/baidu.com/test.js" charset="UTF-8"></script>
</body>
</html>
页面:
如果不是true,即不是捕获,就不能找到Error
image.png1.在script标签增加crossorigin属性。这个是在客户端做的。
2.设置js资源响应头Access-Control-Allow-Origin:* 这个是在服务器端做的。在http头上加一个Access-Control-Allow-Origin:* 这后面可以是* 也可以是域名 总之要加这两方面的处理,就可以拿到信息了。
可以用ajax通信的方式上报,但是一般都不会用这个方式上报。
如何利用image对象上报:
<script type="text/javascript">
(new Image()).src='http://baidu.com/tesk?r=tksjk'
//src里面就是错误的地址
</script>
image.png
这种方法比ajax方便很多。
网友评论