Mobile Development 13 min read

How WeChat Made SVG Resources Faster, Smaller, and Sharper Than PNG on Android

WeChat tackled the trade‑off between image clarity and app size on Android by replacing numerous DPI‑specific PNGs with scalable SVG assets, developing a custom framework and compilation tool that dramatically reduce package volume, improve loading speed, and maintain visual fidelity while keeping developer effort low.

WeChat Client Technology Team
WeChat Client Technology Team
WeChat Client Technology Team
How WeChat Made SVG Resources Faster, Smaller, and Sharper Than PNG on Android

Resource Vectorization

When targeting Android devices with many DPI densities, providing a separate raster image for each density ensures maximum clarity but dramatically inflates the app package size, which is impractical.

Over the years Android has evolved from mdpi to xxxhdpi, and each time a higher‑resolution PNG had to be added while lower‑resolution assets were often removed, leading to a trade‑off between image sharpness and bundle size.

Keeping only one resolution reduces size but causes blurriness when scaled to other DPIs, and developers must decide when to replace images with higher‑resolution versions.

SVG Vector Graphics

Vector graphics avoid the clarity‑size dilemma because they remain crisp at any resolution without increasing file size. SVG can adapt to any DPI without redesign.

We consider SVG the most suitable vector solution for Android because it is mature, well‑supported by tooling, and avoids the limitations of VectorDrawable or TTF‑based approaches, which are harder for UI designers and can suffer performance issues.

Challenges of Using SVG in WeChat

Two main obstacles must be addressed:

1) Performance – SVG rendering may be slower than drawing a hardware‑accelerated bitmap because it requires runtime parsing and software rendering.

2) Developer Cost – Android does not natively support SVG as a resource type, so additional framework changes could increase learning and integration effort.

Results After Our Effort

1) Clarity

The two xxhdpi screenshots on an OPPO R7 Plus show the left image as SVG and the right as PNG, demonstrating comparable visual quality.

2) Size

Replacing 130 resources reduced the package by 211 KB (≈1.6 KB per asset). Scaling this to all vectorizable resources is expected to save about 1.5 MB, a significant reduction from the current ~7 MB of compressed PNGs.

3) Performance

After testing with 100 k users, SVG loading is substantially faster, while drawing is slower due to lack of hardware acceleration. The overall latency, however, is lower because the loading advantage outweighs the rendering penalty.

We measured an average 70 % speedup for SVG compared with PNG when considering both loading and rendering phases.

Trade‑offs

Each SVG adds roughly 280 µs to app startup; replacing 1 000 resources could increase launch time by about 280 ms. This overhead is intentional to keep the framework transparent and to pre‑compute code that avoids reflection during runtime.

Usable Framework

The ideal workflow is to place SVG files in the raw directory and reference them via R.raw.xxx or @raw/xxx, requiring no changes to existing drawable handling.

How We Made SVG Faster

We moved parsing and heavy calculations to a compile‑time step, generating Java code that directly invokes Skia drawing commands. This approach, called WeChatSVGCode , reduces runtime parsing to about 150 µs per asset and keeps the generated code smaller than compressed SVG XML.

WeChatSVGCode Solution

Implementing the solution required two components: a resource framework and a compilation tool.

Resource Framework

The framework intercepts resource loading without developer awareness, allowing SVG assets to be swapped for PNGs transparently.

Step 1: Place the .svg file in the raw folder instead of drawable . Step 2: Replace R.drawable.xxx with R.raw.xxx and @drawable/xxx with @raw/xxx .

Developers can also obtain scaled drawables via SVGCompat.getDrawable(svgResId, scale), which returns an appropriately sized SVGDrawable.

Resource Interception

Because overriding Resources.loadDrawable is no longer viable across Android versions, we hook into the internal sPreloadDrawable array, inserting a ConstantState object that intercepts loading.

Compilation Tool

We ported the Skia library and Android Skia API to Linux and macOS build environments, then used a code‑generation pipeline to read SVG files, render them with Skia, record API calls, and output Java source that reproduces the drawing.

The final generated code looks like this:

In summary, WeChatSVGCode delivers vector resources that are clearer, smaller, and faster than traditional PNGs while remaining transparent to developers.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceAndroidResource OptimizationSVGvector graphics
WeChat Client Technology Team
Written by

WeChat Client Technology Team

Official account of the WeChat mobile client development team, sharing development experience, cutting‑edge tech, and little‑known stories across Android, iOS, macOS, Windows Phone, and Windows.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.