网页渲染过程(图解)

2019-03-08  本文已影响0人  zhangjingbibibi

从前端的角度,梳理一下,一团代码是如何渲染到网页上的

image.png

渲染机制


image.png image.png image.png image.png

DOM相当于文档对象模型

image.png image.png image.png image.png image.png

一般情况下导致了reflow都会导致repaint

image.png

如果避免最小程度的repaint?

一次性的向页面中插入节点,不要做一次啊操作从新一次

js运行机制

image.png

js是单线程的,大白话来理解就是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.png

dom事件中的点击什么的事件的 等等。

总结:


image.png

页面性能类

image.png

cdn很重要
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.png

notice: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.png

1.在script标签增加crossorigin属性。这个是在客户端做的。
2.设置js资源响应头Access-Control-Allow-Origin:* 这个是在服务器端做的。在http头上加一个Access-Control-Allow-Origin:* 这后面可以是* 也可以是域名 总之要加这两方面的处理,就可以拿到信息了。

image.png

可以用ajax通信的方式上报,但是一般都不会用这个方式上报。

如何利用image对象上报:

<script type="text/javascript">
            (new Image()).src='http://baidu.com/tesk?r=tksjk'
            //src里面就是错误的地址
        </script>
image.png

这种方法比ajax方便很多。

上一篇 下一篇

猜你喜欢

热点阅读