[译]工程师揭秘在Quora缩短页面加载时间用到了哪些技术(上)


原文:ENGINEERING AT QUORA Faster Paint Times

译者:杰微刊兼职译者张迪


Quora的使命是分享和拓展世界的知识,所以最为关键的,是我们要创造出一种产品,能让任何人在所有平台上快速的读取和贡献内容。为此,如何提升我们的网站和移动产品的速度,是我们的工程师团队的首要任务。研究一再发现,更快的页面加载速度可以有更好的用户体验,能带来更多的用户,所以重要的是减少我们的用户在一个空白页面等操作环节等待的时间。页面加载时间会受到诸多不同因素的影响,时间范围由服务器所采取的响应的大小决定,在这篇文章中,我们将特别关注一点——“绘制”(paint)一个页面所需要的时间。


“绘制”时长代表了网页上的元素在浏览器上呈现,并出现在最终用户面前之前所用的时间量。在Quora,我们使用的度量标准被称为Speed Index,并用它来追踪paint次数。而不是在浏览器完成第一次的paint时使用单一的时间戳,Speed Index被定义为可见部分页面显示(以毫秒计)的平均时间;另一方面,一个“n”的Speed Index通常意味着N毫秒以后,页面上被“绘制”的平均像素。


为了优化绘制次数,我们采取以下方法:
1、尽可能快地开始发送字节;
2、尽可能把一些渲染blocking字节减少;
3、尽量并行化。


总的来说,这三种技术已经将我们的页面的Speed Index提高了20%以上。在这篇文章中,我们将详细讨论每项技术。


尽可能快地开始发送字节
在一个典型的HTTP响应中,服务器在将任何数据传动到到客户端之前,将缓存响应的完整内容。然而,随着分块传输编码的出现(HTTP 1.1有过首次介绍),服务器可以将单一的反应分解为多个数据块,这意味着,服务器可以将数据发送到客户端,同时又不需要缓冲整个响应数据。分块传输编码,因为服务器可以日益增多地发送部分页面给客户端,只要他们准备好了。所以,使用了分块传输编码,页面慢的组件将不是瓶颈(因为他们可以通过独立的组块发送),这意味着用户看到内容的速度更迅速。例如脸谱网(facebook),就是通过他们的BigPipe框架使用的这种方式。


在Quora,我们的页面使用类似下面的建筑模块来建造:

# Render method of an example piece of UI.
def render():
    subtree = []
    with h.Div().into(subtree):
        with h.Span().into(subtree):
            subtree += h.text('Hello World')
    return subtree
 
# The render method returns a list of pairs which consists of a
# directive and a UI element.
subtree = [
    ('topen', Div()),
    ('topen', Span()),
    ('text', 'Hello World'),
    ('tclose', Span()),
    ('tclose', Div()),
]
 
# Each directive tells the renderer how to transform the UI Element
# into a html string.
Hello World



采取这一步骤,我们组成逻辑UI组件对象:

class FeedStoryItem(object):
    def render(self):
        ...
 
class Feed(object):
    def render(self):
        subtree = []
        with h.Div(class_=['wrapper']).into(subtree):
            subtree += FeedStoryItem(answer_id=5)
            subtree += FeedStoryItem(answer_id=6)
            ...
        return subtree



你可以看到,每个组件负责定义自己的子树。所以,渲染一个页面,我们简单的递归为渲染页面上的根组件。

for directive, data in page.render():
    # Render data (and recurse if directive is component)
    yield data.render()



有了这个设置,我们可以将每个组件的内容在它完成渲染的同时刷新到客户端。这使我们能够把部分网页尽快发送给用户,不用被封锁在网页上的一个特定的慢的组件。只要以上的组件渲染速度快,用户就可以看到一个完整的页面呈现,而无需等待所有的组件都进行渲染。


以下两个幻灯片用行动演示了这一变化。


在上述时间轴中,整个页面在服务器缓存和刷新一次用1.07s。所以,在那单一的刷新之前,用户只能看到一个空白页。



在这第二个时间轴中,页面是组块渲染和发送的。你可以看到,页面是逐步被“绘制”的,这意味着用户可以更早一些看到内容(即标头和侧边栏),用时659毫秒。即使提要部分页面是大约在同一时间被加载完成并显示的,也是在第二方用户可以更早地看到部分页面。所以,第二例的Speed Index较低,因为比第一个例子的平均像素完成得更早。

 

。。。

 

欢迎移步解放号论坛,更多活动邀您参加~ 

 

------------好久不见的分隔线------------ 


 杰微刊旨在分享优质的内容。
我们水平有限,但理想高远。
也同样期待有理想的您对这个世界的贡献。
欢迎任何目的的联系。

 

欢迎关注我们




分享到:
赚钱
喜欢
精品汇 精品汇总

手机应用大起底:APP如何让用户习惯成瘾?

随着手机APP应用的全面开花,如何让越来越多的用户上钩、让用户形成一种习惯,已经成为科技公司们最痴迷的一件事情。而手机的小小屏幕,用户的注意力只放在几个常用的APP上,在排队、喝咖啡、吃饭时,情不自禁地打开这些APP,究竟这些APP应该具有怎样的魔力?让我们从开发者的角度来一一探究

评论
*

还可以输入140个字符

提交
全部评论(条)

点击这里,查看赚钱机会