通过浏览器渲染过程来进行前端优化

开发 前端
我按照最简单的方式进行描述,实际上更复杂,不管是在浏览器端还是服务端,比如dns解析,代理服务器,负载均衡器等等。

介绍

做web开发,我个人觉得必须要弄清楚浏览器的渲染过程,否则我们很难进行前端优化。

我今天就简单说一下页面加载和前端优化。

页面加载

我按照最简单的方式进行描述,实际上更复杂,不管是在浏览器端还是服务端,比如dns解析,代理服务器,负载均衡器等等。

1、用户访问网页,发送一个http请求到网络服务器。

2、网络服务器(应用服务器)解析请求,发送请求给数据库服务器。

3、数据服务器返回数据给网络服务器,网络服务器解析数据,并生成html文件内容放入http response中,返回给浏览器。

4、浏览器解析http response。

5、浏览器创建DOM树。

6、浏览器下载css,并应用在DOM树上,进行渲染。

7、浏览器下载js,并解析执行js。

[[78542]]

缺陷

以上整个流程中,如果其中任何一个流程出现问题,都不能顺利的渲染页面。

服务端:

网络服务器:无法获取到资源文件(404),或者由于并发的原因暂时无法处理你的请求(最常见的500错误),你的浏览器会长时间处于空白状态,直到服务器返回状态,或者进行超时处理。

数据层:如果服务器停止,或忙于处理大数据等等,长时间无法返回数据给网络服务器,那么网络服务器一直处于等待状态中,如果请求量达到最大值,那么后面的请求都被堵塞,从而无法及时返回内容给浏览器。

客户端:

JavaScript:如果你的js写在body中的div里,而且这个js执行非常复杂的逻辑,那么整个页面处于等待状态中。

不论js代码是内联还是包含在一个不相干的外部文件中,页面下载和解析过程肯定会停下,等待脚本执行完成这些处理,然后才能继续进行。——大多数浏览器使用单进程处理JavaScript的多个任务,同一时间只能有一个任务执行。

CSS:可以同时下载多个CSS文件。

如果我们把CSS样式放在页面底部,虽然使页面内容能更快的加载(因为将加载css 文件的时间放在最后,从而使页面内容先显示出来),但这样的内容是没有样式的,在CSS文件加载进来后,浏览器再对DOM使用样式,会出现我们常说的“无样式之闪烁”。

更讨厌的是,上下都放置CSS样式,浏览器会首先按照上面的进行渲染,等到下面的样式上来,再按照下面的样式进行回流和重绘,用户感觉很差。

注意两个词“repaint"和"reflow"。

repaint(重绘)是在一个元素的外观被改变,但没有改变布局的情况下发生。——如果只是改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器repaint。

reflow(回流):浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,这个回退的过程就叫回流。

总结:以上两种严重影响用户体验,会无意识的流失用户。

[[78543]]

#p#

解决方案

服务端:方式比较多,可以从架构上说(这个内容太多了,什么负载均衡了,什么缓存了,什么主从了),但是今天主要讨论语言层面。

我们可以使用逐步返回内容的方式,输送数据给浏览器,如我们可以使用php的flush,把整个head部分,半个body加一部分div返回给浏览器,进行渲染,然后把其他部分逐步输送到浏览器。

我们可以在服务端使用多线程或多进程的方式并发去进行数据处理。如php常见的

  1. do {  
  2.   $mrc = curl_multi_exec($mh, $active);  
  3. }while($mrc==CURLM_CALL_MULTI_PERFORM);  
  4. while ($active && $mrc == CURLM_OK){  
  5.   if (curl_multi_select($mh) != -1){  
  6.     do {  
  7.       $mrc = curl_multi_exec($mh,$active);  
  8.     }while($mrc==CURLM_CALL_MULTI_PERFORM);  
  9.   }  

或者

  1. <?php  
  2. while (count($sockets)) {  
  3.     $read = $write = $sockets;  
  4.     $n = stream_select($read,$write$e$timeout);  
  5.     if ($n > 0) {  
  6.         foreach ($read as $r) {  
  7.             $id = array_search($r$sockets);  
  8.             $data = fread($r, 8192);  
  9.             if (strlen($data) == 0) {  
  10.                 fclose($r);  
  11.                 unset ($sockets[$id]);  
  12.             }else {  
  13.                 $retdata[$id] .= $data;  
  14.             }     
  15.         }     
  16.         $retdata[$id] = preg_replace('/^HTTP(.*?)\r\n\r\n/is',<em>, $retdata[$id]);</em>  
  17.             foreach ($write as $w) {  
  18.                 if (!is_resource($w))continue;  
  19.                 $id = array_search($w$sockets);  
  20.                 fwrite($w"GET /" . $url[$id] . "HTTP/1.0\r\nHost: " . $hosts[$id] ."\r\n\r\n");  
  21.                 $status[$id] = 1;  
  22.             }     
  23.     }else {  
  24.         break;  
  25.     }     

JavaScript:

1、把脚本进行压缩(移除不必要的字符,注释以及空行)。

2、对部分js文件进行合并,以减少http的请求个数,以减少服务器端的压力——但是要量力而行,因为如果你的js文件很大,下载很慢的话,很多功能都不能正常进行,我们可以按照业务进行合并。

3、使用外部js文件。因为现在很多浏览器都有缓存,明显会减少http请求数。

4、将脚本放在页面底部。先让用户看到内容,然后再加载js,这样用户会感觉页面加载速度很快。

CSS:

1、合并多个css文件,以减少http的请求个数,以减少服务器端的压力。

2、使用外部css文件。主要原因是浏览器缓存,以减少http请求。

3、放在页面顶部(head标签处),防止出现“无样式内容的闪烁”。

[[78544]]

原文链接:http://www.cnblogs.com/baochuan/archive/2012/05/29/2524694.html

【编辑推荐】

  1. Win8风格的Web启动界面
  2. MySQL在web应用领域面临NoSQL的挑战
  3. 非响应式设计构建跨端Web App
  4. API正迅速成为Web应用程序粘合剂
  5. 5步响应式Web设计和瀑布模式说拜拜
责任编辑:张伟 来源: 川山甲的博客
相关推荐

2012-06-01 10:28:54

Web

2017-10-09 13:39:26

浏览器渲染服务器

2018-01-19 14:39:53

浏览器页面优化

2022-02-07 21:49:06

浏览器渲染chromium

2020-11-06 15:20:45

浏览器前端架构

2013-11-18 14:42:53

浏览器渲染

2013-06-14 13:56:29

浏览器渲染原理

2020-11-16 08:07:51

浏览器渲染网页

2021-07-26 05:01:55

浏览器渲染流程

2013-05-23 16:01:56

浏览器

2017-03-08 08:31:48

浏览器渲染路径

2013-11-20 13:47:43

浏览器渲染引擎

2022-08-30 09:01:11

浏览器渲染前端

2009-06-29 19:49:11

服务器刀片服务器IBM

2021-04-21 07:12:08

微软Edge浏览器

2012-09-18 09:20:21

2017-03-12 10:15:18

浏览器DOM树CSSOM树

2015-02-28 09:39:24

Windows 10Spartan

2013-11-20 10:47:57

浏览器渲染html

2021-06-01 09:12:47

前端浏览器缓存
点赞
收藏

51CTO技术栈公众号