标签:自己 tin return 产生 决定 开始 服务器 行号 入队
DTD是一系列的语法规则,用来定义XML或HTML的文件类型。浏览器会使用它来判断文档类型,决定使用何种协议来解析,以及切换浏览器模式。
DOCTYPE是用来生命文档类型,一个主要的用途便是文件的合法性验证,。如果文件代码不合法那么浏览器解决便会出现一些差错
<!DOCTYPE html>
定义:
DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow
触发Reflow
定义:
当页面中元素样式的改变并不影响他在文档流中的位置时(例如:color,background-color,visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称之为重绘
回流比重绘的代价要更高
有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。现代浏览器会对频繁的回流或重绘操作进行优化:浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。
当你访问以下属性或方法时,浏览器会立刻清空队列:
clientWidth、clientHeight、clientTop、clientLeftoffsetWidth、offsetHeight、offsetTop、offsetLeftscrollWidth、scrollHeight、scrollTop、scrollLeftwidth、heightgetComputedStyle()getBoundingClientRect()
因为队列中可能会有影响到这些属性或方法返回值的操作,即使你希望获取的信息与队列中操作引发的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。
CSS
Javascript
例题
console.log(1);
setTimeout(function(){
console.log(3)
},0)
console.log(2); //1,3,2
console.log(‘A‘);
while(true){
}
console.log(‘B‘) //A 不会打印B,会在while中一直循环
console.log(‘A‘);
setTimeout(function(){
console.log(‘B‘)
})
while(true){
} //A 不会打印B,会在while中一直循环
进程
进程是CPU资源分配的最小单位。可以理解为一个独立运行且拥有自己的资源空间的任务程序
进程包括运行中的程序和程序所使用到的内存和系统资源
线程
线程是CPU调度的最小单位。线程是建立在进程的基础上的一次程序运行单位,线程是程序中的一个执行流。一个进程可以有多个线程。
一个进程中只有一个执行流称作单线程,即程序执行时,所走的程序按照连续顺序下来,前面的必须处理好,后面的才会执行
一个进程中由于多个执行流成为多线程,即在一个程序中可以同时运行多个不同的进程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
JS的单线程,与它的用途有关,作为浏览器脚本语言,JavaScript的主要用途是于用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时候浏览器无法做出抉择
JS分为同步任务和异步任务
同步任务都在主线程上执行,会形成一个执行栈主线程,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放一个事件回调。
一旦执行栈中所有同步任务执行完毕,系统就会读取任务队列,将可运行的异步任务添加到执行栈中,开始执行
let setTimeoutCallBack = function() {
console.log(‘我是定时器回调‘);
};
let httpCallback = function() {
console.log(‘我是http请求回调‘);
}
// 同步任务
console.log(‘我是同步任务1‘);
// 异步定时任务
setTimeout(setTimeoutCallBack,1000);
// 异步http请求任务
ajax.get(‘/info‘,httpCallback);
// 同步任务
console.log(‘我是同步任务2‘);
JS引擎线程只会执行执行栈中的事件,执行栈中的代码执行完毕,就会读取事件队列中的事件并添加到执行栈中继续执行,这样反反复复就是我们所谓的事件循环(Event Loop)
异步加载的三种方式----async 和defer ,动态脚本创建
<script type="text/javascript" src="xxxx.js" async="async"></script>
<script type="text/javascript" src="xxxx.js" defer></script>
通过window.onload方法确保页面加载完毕再将script标签插入到DOM中
function addScriptTag(src){
var script = document.createElement(‘script‘);
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("js/index.js");
}
异步加载的区别
浏览器缓存类型:
相关的header
Expires: response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。它的值为一个决定时间的GMT格式的时间字符串,比如Expires:thu,21 Jan 2018 23:39:02 GMT
Cache-Control: 这是一个相对时间,在配置缓存的时候,以秒为单位,用数值表示。当值设为max-age=300,则表示在这个请求正确返回时间的5分钟内再次加载资源,就会命中强缓存。比如Cache-Control:max-age=300
相关的header
last-Modified和if-modifed-since:当第一次请求资源时,服务器将资源传递给客户端时,会将资源最后更改的事件以"last-Modified:GTM"的形式加在实体首部上一起返回给客户端
Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
客户端会为资源标记上该信息,下次再请求时,会把该信息附带在请求报文中一并带给服务器去检查,若传递时间值与服务器上该资源最终修改时间是一致的,则说明该资源没有给修改过,直接返回304状态码,内容为空,这样就节省了传输数据量。如果两个时间不一致,则服务器会发回该资源并返回200状态码,和第一次请求时类似。这样保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。一个304响应比一个静态资源通常小的多,这样就节省了网络带宽
但last-modified存在一些缺点:
ETag 和if-none-match:Etag 是上一次加载资源时,服务器返回的response header是对该资源的一种唯一标识,只要资源发生变化浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的if-none-match里,服务器只需要比较客户端传来的if-None-Match跟自己服务器上该资源的Etag是否一致,就能判断资源相对客户端而言是否被修改过了,如果服务器发现ETag匹配不上,那么直接以常规GET200回包形式将新的资源发送给客户端;如果ETag是一致的,则直接返回304
通过将静态资源(例如JavaScript,css,图片等等)缓存到离用户很近的相同网络运营商的CDN节点上,不但能提升用户的访问速度,还能节省服务器的带宽消耗,降低负载。
资源预解析是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。通过DNS预解析来告诉浏览器未来我们可能从某个特定的URL获取资源,当浏览器真正使用到该域中的某个资源时就可以尽快地完成DNS解析
<meta http-equiv="x-dns-prefetch-control" contrent="on">
//在http下,在大多数浏览器都支持a标签预解析,但是在https下,浏览器并不会直接开启a标签预解析
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">
//一个页面中,存在多个域名的情况下,提升DNS预解析可以大大加快页面的性能
该技术对使用第三方资源特别有用,当浏览器真正请求该域中的某个资源时,DNS的解析就已经完成了,从而节省了宝贵的时间
对于JavaScript而言,我们面对的仅仅只是异常,异常的出现不会直接导致JS引擎崩溃,最多只会使当前执行的任务终止。
try-catch处理异常的能力有限,只能捕获到运行时非异步错误,对于语法错误和异步错误就显得无能为力,捕捉不到。
try{
error //未定义变量
}catch(e){
console.log(‘我知道错误了‘);
console.log(e);
}
然而对于语法错误和异步错误就捕捉不到了
try{
var error =‘error‘;//中文分号
}catch(e){
consol.log(‘我感知不到错误‘);
console.log(e)
}
异步错误
try{
setTimeout(()=>{
error //异步错误
})
}catch(e){
console.log(‘我感知不到错误‘);
console.log(e)
}
window.onerror捕获异常能力比try-catch稍微强点,无论是异步还是非异步错误,onerror都能捕获到运行时错误。
/**
* @msg 错误信息
* @url 出错文件
* @row 行号
* @col 列号
* error 错误详细信息
*/
window.onerror = function(msg,url,row,col,error){
console.log(‘我知道错误了‘);
console.log({
msg,url,row,col,error
})
return true
};
error;
异步错误
window.onerror = function (msg, url, row, col, error) {
console.log(‘我知道异步错误了‘);
console.log({
msg, url, row, col, error
})
return true;
};
setTimeout(() => {
error;
});
然而window.onerror对于语法错误还是无能为力,所以我们在写代码的时候要尽可能避免语法错误。
在实例的使用过程中,onerror主要是来捕获预料之外的错误,而try-catch则是用来在可预见情况下监控特定的错误,两者结合使用更为高效
需要注意的是,window.onerror函数只有在返回true的时候,异常才不会向上抛出,否则即使是知道异常的发生控制台还是会显示 Uncaught Error.xxxx
关于window.onerror还有两点需要注意
function report(error){
var reportUrl =‘http://xxxx/report‘;
new Image().src =reportUrl +‘error‘+error;
}
标签:自己 tin return 产生 决定 开始 服务器 行号 入队
原文地址:https://www.cnblogs.com/lrgupup/p/12900252.html