Skip to Content

Deutsche Version ist in der Mitte des Artikel

中文版位于文章底部

————————————————————————————————————————————–

Jin hates Twitter.

Jin is my friend when I studied in Germany. He loved literary creation when he was still in China. But he never registered any Blog or similar things and only write his artikels with Long Weibo. For him, this is “the future of literature”. After coming to Germany he found that everybody here uses Twitter but not Weibo, but Twitter has no similar function like Long Weibo. 140 charaters are always not enought. Therefore, Jin uninstalled Twitter and he believed that european literature has no future.

I told him that Long Weibo is not something complicated, just converting text into pictures. Maybe I can write an app for you, and the name will be  “Big Twitter”, and the icon will look like this:

 

Then it took me two evenings to finish this app. It can convert text into images and instantly send it to Twitter.

 

But only after half a day Jin came back to me. His picture was blurred and he swears that he had written nothing illegal. I believed in Jin, but why was the picture blurred? It turns out that Jin has written over 8400 words and the image was too big, Twitter has to compress it. So the picture was unreadable. This event completely discouraged Jin, he even removed his Twitter account.

I don’t use Twitter often, neither. But as a developer I really interested in it. Twitter has a lot of interesting mechanisms. Today we use Debugger to study the lazy loading mechanism of Twitter.

Some basic concepts

Timeline, the most important module inTwitter. Many tweets combine together to form a long timeline.

Position, the identifier of a tweet. Position of a new tweet is greater than it of an older tweet, therefore I guess position 10000 possibly means “This tweet is the 10000th tweet in the history of Twitter”.

 

Everything starts with “Network”

First we catch a request in Network from Developer Tools. It looks like the following pictures.

Here we can find some thing:

  • max_position: We can find a position in the request. And it’s the only thing in the request which related to the response content.
  • has_more_items: Are there any more tweets in the server or not.
  • items_html: content of tweets in HTML format. Twitter uses “Bachend Rendering” mechanism.
  • min_postion: Something that has relationship with max_position.
  • new_latent_count: How many tweets are there in the response.

Deeper exploration

To explain all these thing, we dive into the code from initiator of the request. And we can find an XMLHttpRequest is sent here. And we believe that there must be some processing function of the response. We can search in call stack and finally we could find the processing function.

Then we keep diving and in the end we find the items_html are added into the timeline.

 

But how about the min_position and max_position? In the call stack we could find a function called getOldItems. When user scroll down in Timeline for older tweets, this function will be called. And in this function the max_postion in the request will be set with the min_position in the last response.

Then we could summarize the whole process:

  1. The user scroll down in the timeline. A request will be sent to tell the server: “I have finished reading tweet A, please send me more.”
  2. The server send 20 tweets before A and tell the user: “Here are 20 tweets until tweet B, enjoy!”
  3. When user these 20 tweets finished reading and scroll down in the timeline, a request will send to the server: “Tweets until B are also finished, please send me more!”

Now always 20?

During the research I found a very strange phenomenen, that the new_latent_count is not always 20. Occasionally it can be a little less than 20. Since in the request there is only the information of max_position, I believe that this number is decided from the server side.

At the beginning I suspect that this number is decided with the size of the response. (If the response will be too large then less tweets will be sent). But in some examples I found that the response size is very small but the new_latent_count is still less than 20. So I guess there might be a magical algorithm. With this algorithm, the server can know how long it takes the user to read a tweet. If the tweets will take a lot of time then fewer tweets will be sent. But this is just my guess. If you know the mechanism please tell me. Thank you!

————————————————————————————————————————————–

Deutsch Version

Hallo ich bin Cong. Jetzt bin ich ein Developer an Hybris Revenue Cloud in Chengdu, China. Ich möchte Programmierkenntnisse hier teilen und mein Deutsch verbessern. Deshalb schreibe ich Blogs in Deutsch und Enghlish. Wenn Sie Syntaxfehler finden, oder mein Deutsch ist zu schwer zu verstehen, bitte lesen Sie die English Version und sagen Sie mir den richtigen Ausdruck. Herzlich Dank und ich hoffe, dass Sie meinen Blog genießen. Prost!

————————————————————————————————————————————–

Jin hasst Twitter.

Jin ist mein Freund wenn ich in Deutschland studierte. Er liebte literarische Schöpfung wenn er in China war. Aber er hat nie einen Blog oder so etwas geöffnet und nur mit Long Weibo um Artikel zu schreiben. Für ihn bedeutet es “Zukunft der Literatur”. Nachdem er nach Deutschland kam findte er, dass alles hier Twitter aber nicht Weibo benutzen, und Twitter hat keine Funktion wie Long Weibo. 140 Schriftzeichen sind immer nich genug. Deshalb deinstalierte Jin Twitter and glaubte er, dass European Literatur hat keine Zukunft.

Ich sagte ihm, dass Long Weibo ist nicht etwas Kompliziert, nur umwandelt Text in Bild. Da kann ich für dich ein App machen, und der Name is “Groß Twitter”, und das Symbol sieht wie diese aus:

Dann habe ich zwei Abende gebraucht um dieses App zu machen. Es kann Text in Bild umwandeln und sofort ein Tweet senden.

Aber nur nach halber Tag kam Jin mich zurück. Sein Bild wurde verwischt und er schwört, dass er nichts Illegales geschrieben hatte. Ich glaubte Jin, aber warum wurde das Bild verwischt? Es stellt sich heraus, dass Jin hat über 8400 wörter geschrieben und das Bild war zu groß, Twitter hat es komprimiert. Dann war das Bild nicht lesbar. Dieses Event machte Jin völlig entmutigt, sogar kündigte er seinen Twitter Konto.

Ich benutze Twitter nich häufig, aber als ein Developer habe ich viel Lust zu er. Twitter hat viele interesant Mechanismus. Heute erforschen wir das “Lazy-Loading” Mechanismus von Twitter mit Debugger.

Einige grundlegende Konzepte

Timeline, das wichtigste Modul von Twitter. Viele Tweets kombinieren zusammen um ein langes Timeline zu bilden.

Position, die Kennung eines Tweet. Position eines neues Tweet ist größer als Position eines altes Tweet, deshalb errate ich, dass Position 10000 bedeutet “Dieses Tweet ist das 10000. Tweet  in Geschichte von Twitter”.

Alles beginnt mit “Network”

Zum erst nehmen wir ein Request in Network von Developer Tools. Es sieht wie folgendes Bilder aus.


Hier können wir einige Sache finden:
  • max_position: Eine Position, da können wir im Request finden.
  • has_more_items: Gibt es weiter Tweets im Server oder nicht.
  • items_html: Inhalt der Tweets in HTML Format. Twitter benutzt “Bachend-Rendering” Mechanismus.
  • min_postion: Etwas hat Beziehung mit max_position.
  • new_latent_count: Wie viel Tweets gibt es in dem Response.

Tiefere Exploration

Um diese Sache zu erklären, wir tauchen in die Code von Initiator des Request. Und wir können hier ein XMLHttpRequest finden. Und es muss einige Verarbeitungsfunktions des Response geben. Wir suchen in Call Stack und finden die Verarbeigungsfunktion.

Dann tauchen wir weiter und können wir finden, dass items_html in Timeline hinzufügt wird.
Wo sind min_position und max_position? In Call Stack finden wir ein Funktion nennt getOldItems. Wenn man in Timeline runterscrollen, wird diese Funktion geruft. Es setzt max_position des Request mit min_postion des letztes Response.

Dann wissen wir den Prozess von Lazy-Loading:

  1. Man runterscrollt in Timeline, ein Request wird gesendet und sagt dem Server: “Ich habe Tweet A gelesen, geben mir die weitere”.
  2. Der Server sendet 20 Tweets und sagt dem Benutzer: “Hier sind Tweets bis B, bitte lesen Sie”.
  3. Wenn man diese 20 Tweet fertig liest und runterscrollt, sagt dem Server: “Alles fertig! Bitte senden mir Tweets bevor B”.

Nicht immer 20?

Aber hier gibe es ein seltsames Phänomen, dass new_latent_count ist nicht immer 20. Gelegentlich ist es weniger als 20. Weil in dem Request gibt es nur max_position, glaube ich diese Nummer wird im Server entschieden.

Am anfang vermute ich, diese Nummer wird mit Größe des Response entschieden. Aber in einige Beispiels sind die Größe ziemlich klein und ist die Nummer kleiner als 20. Ich vermute, da gibt es vielleicht ein magischer Algorithmus. Mit diesem Algorithmus kann der Server wissen, wie lange braucht man um ein Tweet zu lesen. Wenn die Tweets braucht sehr viel Zeit dann wenige Tweets werden gesendet. Aber sie ist  nur meine Vermutung. Wenn Sie den Mechanismus wissen bitte sagen mir. Danke!

 

————————————————————————————————————————————–

中文版

————————————————————————————————————————————–

老金痛恨Twitter。

老金是我在德国读书时的好基友,在国内时就酷爱文学创作。但他却从未开通个博客什么的,坚持使用新浪“长微博”功能写文章。用他的话说,这代表新锐文学的姿态。到了德国之后,老金发现人家老外不用微博,人家用Twitter。新锐的他自然要入乡随俗,可正准备舞文弄墨,却发现Twitter里并没有个东西叫“Long Twitter”,140个字符啥也干不了。于是老金愤而卸载Twitter,逢人便感慨西方文学这下是要彻底完了。

看着老金整天闷闷不乐,我便安慰他说什么长微博,不就是文字变图片嘛。Twitter没这东西,看小爷我的本事啊。我给你写个App,名字就叫“大Twitter”,图标我都给你设计好了。

然后我用了两个晚上搞了个小工具,把大段文字转成图片,然后直接发到Twitter上。

可没曾想,老金刚用了半天就找到我,说自己写的东西不知道为什么全被打上了马赛克,并信誓旦旦对“秦老师”发誓说自己没写什么大尺度的东西。我问他秦老师是谁?他说是印度著名诗人秦戈尔老师啊!善良的我并没有当面给他指出那位老师不姓秦这件事,只想着好好的图片怎么会被打码了呢?

我拿来一看,原来是老金实在憋了太久,这一次足足写了8400多个字,生成的图片尺寸过大,被鸡贼的Twitter给压缩了,于是便模糊得像打了码一样。心灰意冷的老金决定与Twitter恩断义绝,连账户都注销了。

虽然我也不怎么用Twitter,但作为一个程序员我对它还是很有兴趣的。作为同类产品中的佼佼者,Twitter自然是有它的优势。其中比较有特色的一点就是其懒加载的机制。今天我们就通过Debug的方式来对其探究一番。

一些你需要知道的概念

时间轴(Time Line),Twitter中最最重要的部分。一条条的推文组合在一起,就成了页面上中间那条长长的时间轴。

位(Position),一条推文的标识符,说白了就是推文的ID。新推文的Position比老推文的要大,所以我觉得Position很有可能代表着“这是Twitter有史以来的第xxx条推文”。可我随便找到的一个Position却着实大得让我怀疑自己的猜测。

千里之行,始于Network

首先我们在开发者工具的Network工具中截取一条当用户滚动加载时发出的请求。结果发现它长下面这个样子。

在这里我们可以发现几个有意义的信息:

  • max_position:翻遍Header信息以及请求参数,这是唯一一个跟所要请求的内容相关的东西。具体含义后面再讲。
  • has_more_items:顾名思义,服务器通过这个字段告诉前端是否还有更早的内容。
  • items_html:格式化之后发现,这个部分就是我们所请求到的推文内容。显然Twitter使用到的是后端渲染的技术,将推文内容渲染好直接发给前端进行展示。
  • min_position:恰好对应了请求当中的max_position。
  • new_latent_count:这一次所请求到的推文的条数。

深入探究

为了搞清楚这些信息到底是怎么回事,我们通过寻找请求的发起者来深入到代码当中。原来Twitter在这里发送了一个XMLHttpRequest。无论是什么请求,总归要有一个处理的方法,我们在Call Stack中层层向上追溯,然后找到了请求的定义位置。

这里我们进入到请求成功的方法中继续探索。最终到达终点,items_html被添加到了时间轴当中。

那min_position和max_position呢?我们回到刚才定义请求的位置继续向上追溯,找到了getOldItems的方法。当用户在时间轴上向下滚动鼠标到最后时,就会调用到这个方法,而在其中会把上一次响应当中的min_position赋值给这一次请求当中的max_postion。

至此我们可以将整个Twitter的懒加载流程串接起来:

  1. 用户向下滚动时间轴,发出请求,通知服务器“我已经把第A条看完啦,快让我看更之前的内容”。
  2. 服务器返回从A再往前的20条内容,并告诉用户“喏,现在发给你直到第B条的所有内容了,慢慢看吧”。
  3. 用户再次看完这些内容,向下滚动时间轴,告诉服务器“到第B条的我也看完啦,B之前的你再发给我吧”。

每次不一定20条?

在研究的过程中,我发现了一个有趣的现象,就是new_latent_count绝大多数都是20,而偶尔会略小于20。由于前端请求中并不存在所要请求的条数,所以这个决策是在后端完成的。

起初我以为后端会根据需要即将响应的内容大小决定发多少条,可分析了一些例子之后发现有的时候响应明明很小,却还是发了不到20条。所以我的猜测是后端这个神奇的算法可能会判断返回的内容用户大概会浏览多久,如果比较耗时,则少返回一些。例如如果推文中有长视频,则判断为阅读耗时较长,可以少返回几条。但这只是我瞎猜的,有知道其中原理的朋友可以留言告诉我,非常感谢。

Debug之痛

坦率讲整个Debug过程花费了我很多时间,一方面是对于其代码结构的不熟悉,另一方面是minify过的js代码实在是让人头疼啊。所有的变量都长成abcd不说,到处都是用逻辑运算符写的条件判断语句,看得人口吐白沫。不过从学习的角度讲,整个过程跑下来无论是debug能力还是代码阅读能力都会有所提升,推荐大家也试一试。

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply