Hacker News new | ask | show | jobs
by lotw_dot_site 1417 days ago
One of my proudest moments during the development of "Linux on the Web" had to be the creation of a Terminal application (try it at https://lotw.site/shell) that can render its output with near-native efficiency. My initial attempt was based on placing character images, one-by-one, onto a canvas element, but it was horribly sluggish. Then I started playing around with a "Virtual Dom" (React-like) approach, wherein I convert the underlying data structure into an html string, and then set the innerHTML property of a div element, for every time the screen has to be redrawn. (Source code: https://github.com/linuxontheweb/LOTW/blob/main/root/code/ap..., the relevant code is the "render" function starting on line 569, and the innerHTML is set on line 940).

I don't know how many years its been that I started working on the Terminal application, but it was only within the past week or so that I "bit the bullet" and figured out how to do finger pad/mouse wheel scrolling of the output buffer (See the 'main.onwheel' function in the source code for that little tidbit!). Since I required fine-grained control over the rendering process, I could not rely on the "naive" way of doing scrolling on the web (which is to simply let the browser take care of the entire process).

2 comments

> My initial attempt was based on placing character images, one-by-one, onto a canvas element, but it was horribly sluggish.

I've done web-based terminal-style renders in a number of different ways for my roguelike [1]. I've done both DOM and canvas renderers. I found that the fastest approach to be:

1. Render each glyph to a canvas.

2. Only re-render glyphs that actually changed.

Doing that was much faster than using the DOM. I imagine I could go even faster using WebGL but at this point, I considered the performance good enough.

For anyone interested, my terminal library is written in Dart and is open source:

https://github.com/munificent/malison

[1]: http://munificent.github.io/hauberk/

If I would have continued my original approach, I probably would have been able to get something like that working pretty well, but since it is pretty hard to beat Virtual DOM types of approaches, I had no need to try anything else when rendering full screens of text could keep up with key repeat rate.

But of course, the idea of developing a terminal using a standard DOM-centric approach is usually not going to turn out very well... though Google is an exception here with the hterm js library that underlies the terminal output for Chromebooks: https://chromium.googlesource.com/apps/libapps/+/master/hter.... Most Chromebook users will never have the opportunity to put this to use, though people like me who put their Chromebooks in developer mode the first chance they get use it all the time.

Same experience here. Canvas rendering is much faster for terminal apps if done well. I think also VS code uses a canvas for its terminal because its superior performance.
It's been 357 years, and Dart still can't go full screen without a hack like this: https://github.com/munificent/hauberk/blob/master/web/main.d...

https://github.com/dart-lang/sdk/issues/11506 (Jun 25, 2013)

That code is seven years old: https://github.com/munificent/hauberk/commit/2ba2f260baa7004...

I should fix it to use: https://api.dart.dev/stable/2.17.6/dart-html/Element/request...

I just never noticed because it wasn't causing any problems.

I think that must have changed recently (this year, maybe). I know something changed for sure because the method was always there, but it did not return a Future, like it should have, and did not have the optional Map. I don't recall seeing anything in the changelog.

I'll give it a try.

Didn't look through GitHub to see if someone else has already mentioned the issue but it just shows a blank black screen when opened in Safari

> Unhandled Promise Rejection: ReferenceError: Can't find variable: webkitResolveLocalFileSystemURL

Yeah, I don't personally mess with anything but Chrome, and I consider supporting browsers that are not Chromium-based to be a fork of the entire project.

Per the Disclaimer in the Github README (https://github.com/linuxontheweb/LOTW/):

---------------

LOTW is developed in the crouton environment, which involves ChromeOS in developer mode. All development and testing is currently done on a Chromebook, using an up-to-date Chrome browser.

The system should basically work in any modern browser and host OS, but there are likely many tiny glitches that degrade the user experience in other browsers and/or operating systems.

---------------

The crucial fact of LOTW is that it is based around the concept of a full-featured, sandboxed file system in your browser. Only Chromium-based browsers natively support that kind of thing via 'webkitRequestFileSystem'.

That being said, there is a shim/polyfill that is supposed to load and take care of that (https://github.com/linuxontheweb/LOTW/blob/main/www/js/fs-sh..., created by Eric Bidelman when he was at Google). Last I knew, Firefox seemed to work with it.

> I don't personally mess with anything but Chrome, and I consider supporting browsers that are not Chromium-based to be a fork of the entire project

I see the ie6 world is coming back

Funny, that, seeing how M$ themselves are perhaps the biggest contributors to the current browser codebase monoculture issue.

Anytime a software project develops enough complexity, there is no shame in targeting a specific platform. Given enough eyes on a thing, though, those kinds of "supported" issues always take care of themselves.

But I'm just a lone developer trying to do something never before done. I'm still trying to prove a concept...

It doesn't work on Firefox.

I too am a lone developer but (not to judge) I consider any website I work on to only be complete if it works on Chrome and Firefox and maybe Edge. I mean, it's easily thousands of times easier to do this now than it was in the early 2000's when we were all forced to do IE5/6/7/8 compatibility, and the tooling wasn't remotely as good... so I won't have any sympathy for you LOL

Gotta love how cross platform the web is...