Frontend Development 9 min read

Implementing Chat History Loading in a WeChat Mini‑Program Using Flex Column‑Reverse and a Koa WebSocket Server

This article explains how to solve the common problem of loading historical chat records in a WeChat mini‑program by using a two‑line CSS flex column‑reverse trick, handling edge cases such as limited data and scroll‑view issues, and provides a complete Koa WebSocket backend implementation with full code examples.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Chat History Loading in a WeChat Mini‑Program Using Flex Column‑Reverse and a Koa WebSocket Server

Introduction

I first built a chat feature in 2021 for a WeChat mini‑program and struggled with loading historical messages without the page jumping to the top or flashing.

"Wow, they want me to write a high‑end chat feature?"

After many experiments I found a simple yet elegant solution.

1. Effect Demonstration

Demo GIFs show the visual result.

2. Chat Page

2.1 The Pitfall of Loading Historical Records

When the history is loaded and concatenated to the top of the chat container, the scrollbar returns to the top , causing the user to lose the current position.

Typical fixes involve caching or manually resetting the scroll position, but they still cause flickering on some Android and iOS devices.

The real solution is only two lines of CSS :

2.2 Solution: Flex Magic

Using the flex container’s column-reverse direction reverses the order of child elements, allowing new messages to appear at the bottom while keeping the scroll position stable.

display:flex;
flex-direction: column-reverse

After applying this, loading more data no longer moves the scrollbar; the view stays at the original chat position.

The key CSS rule is flex-direction: column-reverse , which tells the Flex container to arrange items from bottom to top.

2.3 Other Issues

2.3.1 First Screen When Data Is Sparse

With the reversed layout, a small amount of data can cause the first screen to appear incorrectly. Adding .mainArea { height:100% } fixes it.

flex-grow: 1;
flex-shrink: 1;

2.3.2 Problems Caused by scroll-view in UniApp

Using scroll-view together with .mainArea { height:100% } hides the scrollbar. Removing the height restores the scrollbar but prevents the first screen from scrolling to the latest message.

Solution: manually set the scroll position after the first screen loads:

scrollBottom() {
if (this.firstLoad) return;
// first screen after load, do not trigger
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.select("#mainArea").boundingClientRect((data) => {
console.log(data);
if (data.height > this.chatHeight) {
this.scrollTop = data.height; // set a large number
this.firstLoad = true;
}
}).exec();
});
},

3. Server Side

A simple WebSocket server is built with Koa.

3.1 Project Structure

The directory contains package.json and the main server file koa-tcp.js .

{
"name": "websocketapi",
"version": "1.0.0",
"main": "index.js",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"dependencies": { "koa": "^2.14.2", "koa-router": "^12.0.1", "koa-websocket": "^7.0.0" }
}

The server code creates a Koa app with WebSocket support, defines a route /websocket/:id , logs connections, echoes a welcome message, and replies to incoming chat messages.

const koa = require('koa')
const Router = require('koa-router')
const ws = require('koa-websocket')
const app = ws(new koa())
const router = new Router()
router.all('/websocket/:id', async (ctx) => {
console.log(JSON.stringify(ctx.params))
ctx.websocket.send('I am the server, connection successful')
ctx.websocket.on('message', (res) => {
console.log(`Server received: ${res}`)
let data = JSON.parse(res)
if (data.type === 'chat') {
ctx.websocket.send(`I also say ${data.text}`)
}
})
ctx.websocket.on('close', () => { console.log('Server closed') })
})
app.ws.use(router.routes()).use(router.allowedMethods())
app.listen(9001, () => { console.log('socket is connect') })

Run the server with yarn in the server directory and start it using nodemon koa-tcp.js (install nodemon if needed).

Conclusion

The article shares the complete solution, code snippets, and a GitHub link for the full project, hoping to help developers implement smooth chat history loading in mini‑programs.

WebSocketmini-programKoaFlexboxChat
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login 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.