`
chennanfei
  • 浏览: 41665 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

网页重构——bigpipe中的页面构建优化

 
阅读更多

题记:搞互联网的同学也许都知道一个数字——4秒,有研究表明,如果一个网站没有在4秒之内加载完成,用户就会感到焦躁不愉快,并离开这个网站(数据来自性能测试网站http://gtmetrix.com/)。网站的内容、SEO优化、用户体验?哪个更重要呢?在速度面前,也许这些都相对更次要。所以提高网页效率,是我们在新版微博的第一目标。从四个方面来浅谈我们新版微博的优化。

一、HTTP请求数的权衡

1.为什么要关心http请求?

当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息。在用户打开一个页面的初初,包括等待时间、请求时间、建立响应时间、渲染时间……,都是消耗在前端的。比如下载图片、下载样式表、JavaScript脚本、flash等文件。大家应该都经历过那个“多图杀猫”的时代,加载那样一个网页会花费大量的时间。减少这些资源文件的请求数将是提高网页显示效率的重点。

假设用户家的网速是10Mbps,10Mbps=10/8=1.25MB/s,那么他打开一个网页时,如果网页文件小于1.25MB,理论上他可以在一秒之内打开网页。下载网页的快慢在显示速度上占了很大比重,所以,网页本身体积越小,浏览速度就会越快。这就需要产品、交互、设计,从最初就遵循尽量精简的原则。

现在,就揭开新版微博的面纱,看看微博3.0和新版微博的区别吧。

微博3.0截图

新版微博截图

微博3.0是大家熟悉的两栏结构,总宽为800px,有一级导航和二级导航、发布框、feed区、个人简介区。新版微博是现在最流行的三栏式布局,总宽950px,除以前的内容一个都不少之外,还整合出了左侧导航和右侧各种引导和公告。所以从理论上讲,虽然内容更丰富了,但新版微博着实比微博3.0的页面体积大了很多。

2.什么是bigpipe?

网上有个例子举得好:在饭馆点菜吃的时候,如果点了四个菜,厨师没有必要把四个菜一起炒好再上来。微博3.0就是这种把所有菜都炒好再上桌的网页加载模式。所以用户吃上菜的时候,已经是第5秒了。现在新版微博的bigpipe网页加载模式,是炒好一个菜先一个菜,用户可以先吃着,厨师再炒第二个菜。甚至可以几个菜并发同时炒。所以用户吃上第一口菜的时间可能是第1秒,比之前提前了很多。

bigpipe模式示意图

JS工程师把页面分割成若干个小块(pagelet),模块彼此独立,把html语言转变为JS语言,再把CSS通过style的方式加载进这段代码,而不需要用以往的头部link css地址的方式取样式。每个模块有自己对应的html、CSS、JS,一旦开始运行模块,就会寻找到对应的CSS,并显示对应innerHTML内容插入到对应的html元素中,同时渲染出本模块效果。比如执行到feed区域的id="pl_content_homeFeed"时,样式表只调用了feed.css。

3.为什么新版微博CSS的HTTP请求数不降反增?

通过上面说的这种模式,css被全部link到头部,是为了给后台代码提供出pagelet所需要的样式列表。以前微博3.0头部只link了3个CSS,新版微博首页头部却需要link10多个css。虽然加载文件多了,新版微博CSS加载请求数反而高于v3,看似yslow降级了(这个数据已经不能说明任何问题了)。但实际上新版微博CSS没有像以往一样合并起来,而是用一个加载一个,CSS和JS被分配到不同流水线中,模块的加载变成并行的,先执行完的模块先显示出来。所以新版微博CSS渲染的总时间并不超过V3CSS渲染的总时间,速度反而快了很多,减少了视觉等待。

上面这张表格,来自yslow的分析。我们通过把页面切成细小模块写样式的做法,虽然请求数比以前大了8倍,但总大小上直降20K。

将多个CSS合并的做法固然可以减少请求,但对上亿用户的微博页面来说,完成合并也许会带来5%速度的提升。但是如果按bigpipe模式,即使http请求数提高了,但是整体的速度也许是之前的50%。

二、对CSS的优化处理

1.提取公用模块或公用元素,并反复调用

如果用户每次访问微博首页时,就重新下载读取CSS文件。这就会造成给服务器带来额外压力且用户重复读取耗时。新版微博的做法是,把模块分为全局级模块和页面级模块,首页是全站的核心,所有模块都是重要且重复性高的,所以首页的所以模块都是全局级模块。首页所需要的CSS被整理成一个pl列表反馈给工程师,等待处理。而一些非公共的css模块样式被单独写在属于本页面的文件里,这样就最大化的节省了文件大小及利用率。这么做还有一个好处,就是公共模块样式被调用过后,会在浏览器里留下缓存。调用最频繁的模块,反而样式被最快的加载进来。

举个简单的例子:

.clearfix:after{content: ".";display: block;height: 0;clear: both;visibility: hidden;}

.clearfix {display: inline-block;}

这是一段全局代码,基本上每个页面都会用到这个类,我们就没必要把这句写在每个网页的CSS里面,只把它提取到base.css里,并方便进行皮肤管理。

又比如,首页右侧栏有个“可能感兴趣的活动”类似的模块都是采用独立的div容器,这个段落的详细代码,如果写在公用CSS文件里,肯定就浪费了。

2.尽可能少的使用css images

能通过代码或字符实现的,就不用图片去解决。比如“可能感兴趣的人”展开气泡上下三角、返回顶部的箭头、“更多”后面的»符号等。既减小CSS图片请求,又不会面临若干套皮肤升级困难的问题,仅通过对CSS的color、backgroud等属性的控制,就可以换色了。

可以看看按这个做法之后明显的优势,下图来自yslow的statistics。微博3.0的css image总大小为970.1K,新版微博的css image总大小为693.9K,总量直降30%。

微博3.0 statistics

新版微博statistics

3.尽量使用CSS3等新技术

在新版微博里,我们制定了使用CSS3的原则,即非图片类的元素效果图,如圆角、阴影、渐变、半透等效果,可以通过样式控制,而无需切图的元素,在得到设计师认可后,不用图片,只做样式控制。满足高级浏览器的视觉,ie系列不能显示的,有原则的放弃。不仅为速度助力,还在放弃低级浏览器的大方向前进一步。

4.鼠标滑上效果改用伪类实现

在逐步放弃ie6的事情上,新版微博已经尽最大的努力做了。为了保证各浏览器的完全兼容,微博3.0以前我们曾经放弃让CSS实现鼠标滑上效果,而由JS控制。随着ie6使用率的日益降低,新版微博又一大革新就是重新使用伪类,仅通过CSS就实现的浏览器原生效果,不仅计算速度比计算一个JS快得多,也终于放弃了低端的ie6。

举个评论页feed区的例子:

CSS代码如下:

每个单条feed在鼠标滑上时,都会显示举报和删除链接。这是交互设计出于对页面呈现内容的视觉舒适感所做的设计,我们通过对块元素直接写伪类,实现这个效果,不需要再通过JS了。ie6呢?就让它一直摆着去吧。

三、对dom结构的优化处理

1.bigpipe模式重构并优化垃圾代码

v2从v1来,v3从v2来,在v3不堪重负的时候,新版微博的代码优化誓在必行了。所以我们并没有沿用之前的结构和CSS,而是直接推翻v3,重构新版微博。和JS工程师一起搭建的bigpipe模式,把页面分成细小的块,每一个模块对应一个CSS。代码写到最优,结构和样式完全分离,并杜绝内联调用的方式。下图示意了我们用模块配页面的最终效果,模块可以被细分为如此程度。模块拆的细,复用性被提高。

2.尽量减少代码体积

由于代码行数越少体积就越小,所以我们这次想办法减少网页代码的行数。相同或类似的模块,说服设计师把视觉规范统一。我们只通过对CSS补丁,覆盖原样式,并不改变页面的dom结构,直接降低重复代码率。举个例子,“我的首页”和“我的profile页”,同样是有feed区域的,区别是但一个有头像,一个没有头像。只需要一套feed.css代码,然后在“我的profile页”独立的页面级CSS中,打个去掉头像的补丁即可。

3.首页中杜绝Table布局和iframe

杜绝首页中出现Table布局。因为传统的table布局,是把内容全部加载完成后,才渲染样式,延迟效果严重。而iframe页面框架,是非语义的,即使为空也会有较大资源消耗,还会阻止页面的onload。

四、对图片的优化处理

1.图片的存储格式

我们改变了v3的做法,把icon类小图片或背景类图片,由以前的gif存储尽可能多的转为png8的存储,这是个减小图片体积的好办法。Png8有gif的所有特点,但是相比gif,png8的优势是alpha透明和更优的压缩。png24全透明的图片,只给支持的浏览器使用,ie6在不影响视觉的前提下,改为gif呈现。我们还会利用的图片优化工具处理图片,保证效果但却降低文件大小。下图是主键类页面的images文件夹示意图,除必须独立的icon外,png类型的图片比重大得多。这在之前的V3并没有做到。

2.css sprites

在图片的拼合方面,我们是持之以恒这么做的。在v3里,我们把所有首页和profile页里出现的背景类图片都拼合到一张大图上,新版微博比之前高明在,我们把放置文件夹细分。假设我们把公用型放入common,页面类放入index,换肤类放入skin。把sprites拆分的更细,尽可能在加载首页时,减少图片请求数。

3.大图片、小图片

对于大背景图,我们的做法是不分割成小区块儿的。首先的因为,原本一个图片的请求数会变成多个。另外,大约80%以上调用图片所消耗的时间,是用来检索缓存和确定链接是否有效的阻塞时间。也就是说,如果把一个大图片,切成若干小图片,虽然解决了图片的加载时间,却花费了更多的阻塞时间。

4.在已知宽高的图片标签内,直接指定宽高

Feed区域里头像需求是50*50的,所以后台直接吐出这个尺寸的图片。在已知宽高的情况的,我们在img标签中直接指定了height和width参数。因为如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,首页有多少条feed就有多少个头像,浏览器需要不断地调整计算。当浏览器知道了height和width参数后,即使图片暂时无法显示,页面上也会预留空位,继续加载后面的内容。

新版上线后,不少公测用户的反馈速度变快了,微博浏览起来更顺畅了。这不是我们页面重构组的功劳,是整个微博团队,或者说是bigpipe思想的功劳。但“速度快了”这句话本身,就是对我们团队工作最好的褒奖,对我们参与开发的团队成员的最好的鼓励。抓住产品改版的机会,就是自己对优化的研究和经验的积累落实到细节的机会。虽然还任重道远。

文章出自:小秦的博客

分享到:
评论

相关推荐

    bigPipe Net

    总结来说,"bigPipe Net"是一个.NET实现的高性能网页加载优化技术,它通过模仿微博的BIGPIPE模式,实现了页面的分块加载和异步渲染,从而提升了网页的加载速度和用户体验。"BigPipe_Net" 和 "BigPipe" 文件提供了...

    BigPipe技术java源代码

    BigPipe是由Facebook开发的一种页面加载优化技术,它的主要目的是为了提高网页的加载速度,提升用户体验。在传统的网页加载过程中,浏览器会一次性下载整个页面的所有资源,这往往导致用户需要等待较长的时间才能...

    C#实现仿新浪微博BigPipe

    【C#实现仿新浪微博BigPipe】是一个针对网页加载性能优化的技术实践,主要目的是通过C#编程语言模仿新浪微博的高效数据加载策略——BigPipe。BigPipe是Facebook提出的一种页面加载技术,它通过将一个网页拆分成多个...

    java实现bigpipe(上)

    在 Java 中,我们可以利用 Spring MVC 或者其他 Web 框架来构建 BigPipe 系统。首先,我们需要创建一个 Controller,该 Controller 将处理来自客户端的请求,并返回各个页面组件。例如: ```java @Controller @...

    前端页面加载优化

    前端页面加载优化是提升用户体验的关键环节,特别是在网页内容丰富的现代应用中。Struts2 是一个流行的 Java Web 框架,而 BigPipe 技术则是 Facebook 提出的一种优化页面加载速度的方法,它借鉴了服务器端渲染的...

    bigpipe 基于struts2标签实现

    在Web开发中,优化页面加载速度和用户体验是一项重要的任务。`BigPipe`是一种技术,最初由Facebook提出,用于提高网页加载效率,通过分割页面为多个部分并异步加载,达到类似流式传输的效果。它使得用户可以更快地...

    高性能页面加载技术--BigPipe设计原理及Java简单实现

    BigPipe是一种由Facebook提出的高效页面加载策略,它通过将一个页面拆分成多个部分(或称为“管道”),并逐个异步加载这些部分,来显著加快网页的初始展现速度。在本文中,我们将探讨BigPipe的设计原理以及如何使用...

    Asp.net MVC2.0 BigPipe假想

    通过这种方式,ASP.NET MVC 2.0中的BigPipe实现可以显著提高页面加载速度,尤其是在内容丰富的动态页面中。然而,需要注意的是,过度使用可能会增加服务器负担,因此需要权衡优化效果与资源消耗。 总结起来,ASP...

    NET BIGPIPE vs2010

    .NET BIGPIPE是一个优化Web应用程序性能的技术,特别是在ASP.NET框架下,它通过分块传输页面响应来减少页面加载时间。此技术灵感来源于Facebook的BigPipe,旨在改善用户在浏览网页时的感知速度。在.NET中实现BigPipe...

    BigPipe技术后端实现分享 新浪微博新版中的Bigpipe Server端的php实现 共39页.ppt

    BigPipe技术是一种优化网页加载速度的方法,最初由Facebook提出,其核心思想是将一个完整的网页分割成多个小的、独立的模块,称为Pagelet,然后逐个加载这些模块,就像流水线作业一样,从而显著减少用户等待整个页面...

    net bigPipe

    "net bigPipe" 是一种优化网页性能的技术,最初由Facebook提出,后来被广泛应用于许多大型社交网络,如微博等。它借鉴了操作系统中的管道(pipe)概念,将一个完整的页面拆分成多个小的部分(称为流或管道),然后...

    facebook bigpipe Java版本实现

    Facebook的BigPipe是一种高效网页加载技术,旨在提升用户体验,通过分块加载页面内容来显著减少网页的加载时间。它最初由Facebook开发,并已开源。在这个Java版本的实现中,我们有机会深入理解BigPipe如何在非PHP...

    webx之bigpipe

    Webx之BigPipe技术是一种优化Web页面加载性能的方法,它借鉴了Facebook的BigPipe理念,旨在提高用户体验,尤其是在处理大量动态内容的Web应用中。Webx是一个基于Java的开源Web框架,而BigPipe则是Webx框架中的一个...

    Bigpipe命令_V45

    在 Dell PowerApp.BIG-IP 参考指南中提到的 Bigpipe 命令_V45 是一系列用于管理和配置 PowerApp.BIG-IP 设备的工具集。这些命令可以帮助管理员执行各种任务,包括但不限于网络配置、负载均衡设置、故障转移管理等。 ...

    nodejs实现bigpipe异步加载页面方案

    Node.js 实现 BigPipe 异步加载页面方案 在当今的 Web 开发中,提高页面加载速度和用户体验已经成为一个至关重要的任务。BigPipe 技术,最初由 Facebook 提出,是一种有效的页面异步加载策略,它能显著降低页面加载...

    bigpipe-demo1:简单的 bigpipe 演示

    大管道(BigPipe)是一种优化网页加载速度的技术,最初由Facebook开发并应用于其动态新闻feed的渲染。它的核心思想是将一个完整的网页拆分成多个部分,或者称为“页面片段”(Pagelets),然后并行地、逐个加载这些...

    第三章:页面渲染架构设计与性能优化.pdf

    页面渲染架构设计与性能优化是前端开发中一个重要的领域,它直接关系到用户对网站的体验。优化页面渲染架构可以减少页面加载时间、提升响应速度、提高用户的交互体验。本章节将介绍页面渲染过程中的关键环节、技术...

    网站设计分析:模块化–高效重构

    网站设计中的模块化是一种高效的重构方法,它借鉴了编程中的模块设计思想,即将功能块作为基本单位进行设计,然后通过组合这些模块构建出最终产品。在网页构建领域,这一思想经历了从简单的样式堆砌到逐步提取公用...

    node.js实现BigPipe详解

    BigPipe是由Facebook开发的一种网页加载优化技术,旨在显著提升用户在浏览网页时的加载速度。它通过将页面分割为多个独立的部分(称为Pagelets),并利用HTTP的流式传输特性,允许浏览器逐步接收和渲染页面内容,而...

Global site tag (gtag.js) - Google Analytics