Why it feels that smooth — read from the source.
A from-the-source handbook on how Telegram for Android renders, grounded in a pinned clone of
DrKLO/Telegram @ release-11.4.2-5469 (commit fb2e5451).
Every claim cites an exact file:line. Every performance claim is one you measure yourself.
Bilingual: English at the site root, Vietnamese in parallel at /vi/.
Telegram feels smoother than apps that do less — the UI, the emoji, the stickers, the scrolling. That is not taste. It is architecture, it is readable, and it is measurable.
The answer is one principle, applied everywhere with uncomfortable discipline:
Everything expensive happens outside the frame. By the time
onDrawruns, there is no work left — only blit and lerp.
And it is worth stating up front what that costs, because this book is not a fan letter:
| The mechanism | The bill |
|---|---|
One View draws every message |
24,903 lines in one class; hit-testing by hand, forever |
Their own RecyclerView |
36,697 lines of AndroidX vendored and permanently un-upgradable |
| Emoji animate off-thread | 49 call sites that must remember a manual second pass, or content silently vanishes |
| Animation without animators | a getter deprecated to stop you reading a value outside onDraw |
You will finish able to explain both columns, and to judge which ideas belong in your own app.
An Android engineer who has shipped lists, felt them jank, and wants to know what the ceiling actually
looks like. You should be comfortable with View, Canvas, RecyclerView, and reading Java you did not
write. You do not need to know anything about Telegram.
It also assumes you have a device and are willing to measure. Half the value here is in the labs.
Every chapter is the same shape:
- Why it matters — the problem this layer solves
- Mental model + an ASCII diagram — a picture to hold in your head
- A guided source read — exact
file:lineinto the local clone - A lab — commands you run, with a stated expected result, recorded into
labs/ - Checkpoint — 4–6 questions, with pointers back to the section if one is shaky
Two rules the book holds itself to:
- You never build Telegram. It is 1,653 native source files and a pinned 2020 NDK, and building it teaches you nothing. You read Telegram and you measure your own code. Chapter 0 explains this properly.
- Every number is checkable. Where the book quotes a count, it gives you the command. It also shows
its own corrected mistakes — see §1.4 on why
2,599is the wrong answer to "how many Java files did Telegram write?"
Depth is deliberately weighted toward Chapter 3, the flagship.
| # | Chapter | What you get |
|---|---|---|
| 0 | Environment & Android Refresher | The pinned clone; why we never build Telegram; a baseline app you can measure; the four idioms this codebase lives on |
| 1 | Mental Model & Repo Map | The five-layer model; the 22 XML layouts that turn out to be zero; one message traced from a C++ socket to a pixel |
| 2 | The Frame Budget & AnimatedFloat | The 219-line class that replaces Android's animation framework — and the event bus that makes the frame sacred by contract |
| 3 | ★ ChatMessageCell: One View Draws Everything | 24,903 lines, a 14-line onMeasure, addView( = 0. Four case studies through the cell that carries every message |
| 4 | RecyclerListView & the Scroll Path | They didn't fork RecyclerView — they replaced it. Plus the one-line change you should steal today |
| 5 | Emoji: Assets, Spans & Two Passes | 3,585 PNGs instead of the system font, and the span that deliberately draws nothing |
| 6 | rlottie, TGS & Animated Stickers | Zero-copy rasterization into a locked Bitmap, and the cache that turns vector work into a bounded decompress |
| 7 | ImageLoader & the Media Pipeline | The ~100-byte placeholder that arrives free with the message — and a real shipped bug you can see on your own 120 Hz phone |
| 8 | Capstone & Staying Current | Read a real commit unaided; face the drift from the pinned tag; port three techniques with before/after numbers |
Roughly two weeks at an evening a night, or a focused long weekend. Chapter 3 is worth a session of its own; it is the one to slow down on.
The labs compound — Lab 0 builds the baseline app that Labs 2–7 measure against, so do them in order and keep your numbers.
- Ch 0 — clone verified at
release-11.4.2-5469; baseline app builds; Lab 0 numbers recorded - Ch 1 — can name which layer owns any given concept; the §1.5 trace verified line by line
- Ch 2 —
AnimatedFloatported and measured against aValueAnimator(Lab 2) - Ch 3 ★ — one-View row built and profiled against the conventional one (Lab 3)
- Ch 4 — listeners collapsed to one
GestureDetector; animator nulled for invisible updates (Lab 4) - Ch 5 — two-pass span built, including reproducing the invisible-content bug on purpose (Lab 5)
- Ch 6 — pre-rendered frames vs live rasterization; the 99th percentile compared (Lab 6)
- Ch 7 — free placeholder built; layout shifts counted; the 120 Hz crossfade bug observed (Lab 7)
- Ch 8 — a real
mastercommit read unaided; drift diffed; ≥1 technique shipped to your own app
telegram-book/
├── README.md # this file (English only)
├── 00..08-*.md # 9 chapters, English — canonical
├── 00..08-*.vi.md # 9 chapters, Vietnamese siblings
├── labs/ # lab notes + the baseline app you build
├── reference/
│ ├── glossary.md # terms by category + the "Key files" source index
│ └── glossary.vi.md # Vietnamese (term column stays English)
├── diagrams/
├── site_src/
│ ├── engine.py # the static-site generator (shared across RumitX books)
│ ├── book.py # the only per-book file
│ └── build_site.py
└── site/ # built output: site/ (EN) + site/vi/ (VI)
The upstream clone is expected as a sibling:
cd ~/Documents/learning
git clone --depth 1 --branch release-11.4.2-5469 https://github.com/DrKLO/Telegram.git telegramRead-only. It exists to be cited, never compiled.
python3 site_src/build_site.py # → 22 pages (11 EN + 11 VI) + 2 handbook.htmlNeeds markdown and pygments.
The prose, diagrams, and labs of this handbook are original work.
labs/AnimatedFloat.java is different, and you should know before you use it. It is a port of
TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedFloat.java from
DrKLO/Telegram, which is licensed GPL-2.0. A port is a
derivative work, so that file is offered under GPL-2.0 as well — not under whatever licence you apply
to the rest of this repo.
Practically, for the Chapter 2 lab: copying it into a personal or internal project to measure is fine.
Shipping it inside a closed-source app is a GPL question you should take seriously. The idea it teaches —
a float that lerps from a clock inside onDraw and self-invalidates — is not copyrightable; the 219
lines are. Chapter 2 §2.3 explains the mechanism fully, so you can reimplement it from the description
without touching the port at all.
Code quoted inline throughout the chapters is short excerpts cited for commentary and criticism, with
file:line provenance for every one.
release-11.4.2-5469 was published 2024-11-20 and is the newest release tag that exists — DrKLO
stopped tagging on GitHub after it while continuing to push master. A book must cite lines that do not
move, so it pins a real, reproducible, stable release rather than a master commit corresponding to no
shipped version.
The line numbers here are exact for 11.4.2 and drift on master. The architecture does not. Chapter 8
makes you prove that yourself.
A RumitX publication · rumitx.com