The end of XTalk / LiveCode for me

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10115
Joined: Fri Feb 19, 2010 10:17 am

Re: The end of XTalk / LiveCode for me

Post by richmond62 » Tue Aug 19, 2025 9:55 am

If this really is the "End" why are you still asking questions?

Probably, because you know LC is not at an "end", it is at its usual endless tortuous way of getting somewhere. 8)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10335
Joined: Wed May 06, 2009 2:28 pm

Re: The end of XTalk / LiveCode for me

Post by dunbarx » Tue Aug 19, 2025 2:57 pm

Mike.

Is Bernd's suggestion simply something you missed, and, what do you know, LC had it all the time? I am not trying to dissuade you from migrating away from LC, but I have often discovered that, what do you know, there was a native solution to a task that I either had to write for myself, or live without.

Craig

MichaelBluejay
Posts: 241
Joined: Thu Jul 01, 2010 11:50 am

Re: The end of XTalk / LiveCode for me

Post by MichaelBluejay » Tue Aug 19, 2025 4:59 pm

Thank you, I didn't know about Metadata for text. The feature set of LiveCode is huge (and growing) and there's a lot I don't know about. (I couldn't find Metadata even when searching for that feature, because I didn't know what it was called.) Knowing about metadata sure would have saved me a lot of trouble when I was reordering lines of a list of note titles, where I needed an invisible ID to be associated with each line.

I'm still not planning to return to LiveCode, for these reasons:

• 9.6.3 doesn't run on my M1 Mac. (Won't launch.)
• I'm not paying $440/year to upgrade to a version that will run, just for some homegrown apps.
• Web apps are better with HTML/JS, because there's no massive LC engine to download every time.
• While I can embed metadata behind text in LC, with HTML I can *see* the metadata as part of the code (e.g., as element attributes or hidden fields).
• HTML tables are easy to work with. DataGrid is a royal pain.
• HTML tables scroll super fast. DataGrid scrolls super slow.

The advantages I can think of for LiveCode are:

• Changes are live as soon as you make them. No save file / switch from text editor to browser / reload page as with HTML/JS.
• Can make standalone apps.

I don't think I'll ever make a standalone app, but if I do, then I'd certainly use LiveCode.

stam
Posts: 3088
Joined: Sun Jun 04, 2006 9:39 pm

Re: The end of XTalk / LiveCode for me

Post by stam » Tue Aug 19, 2025 5:53 pm

MichaelBluejay wrote:
Tue Aug 19, 2025 4:59 pm
Thank you, I didn't know about Metadata for text. The feature set of LiveCode is huge (and growing) and there's a lot I don't know about. (I couldn't find Metadata even when searching for that feature, because I didn't know what it was called.) Knowing about metadata sure would have saved me a lot of trouble when I was reordering lines of a list of note titles, where I needed an invisible ID to be associated with each line.

I'm still not planning to return to LiveCode, for these reasons:

• 9.6.3 doesn't run on my M1 Mac. (Won't launch.)
• I'm not paying $440/year to upgrade to a version that will run, just for some homegrown apps.
• Web apps are better with HTML/JS, because there's no massive LC engine to download every time.
• While I can embed metadata behind text in LC, with HTML I can *see* the metadata as part of the code (e.g., as element attributes or hidden fields).
• HTML tables are easy to work with. DataGrid is a royal pain.
• HTML tables scroll super fast. DataGrid scrolls super slow.

The advantages I can think of for LiveCode are:

• Changes are live as soon as you make them. No save file / switch from text editor to browser / reload page as with HTML/JS.
• Can make standalone apps.

I don't think I'll ever make a standalone app, but if I do, then I'd certainly use LiveCode.
You are greatly underselling LCs capabilities but I hear you on the price aspect. While 9.6.3 may not run on your Mac you should check out the open source Fork maintaining this version - i have not, but I hear it runs OK.

I will have to openly disagree with you about the speed of the datagrid. It’s plenty fast. And it’s much easier to manipulate than html tables - obviously you have to bother to learn it…

But where LC shines is the backend of the app. There is a lot of code that is more laborious to do in JS.

I will agree that the html offering is not great but it’s much better in v10 with faster loading times and that’s being optimised further in the future. My main gripe with the web offering is that they haven’t done enough to make it widely accessible and easy to use… - they’ve only done enough to get it up and running.


But on the note of web development I’d recommend checking out XOJO. Surprisingly good for webapps and they include a library that makes it a doddle to work with usual databases. But it is commercial and is based on object oriented basic. Having said that you can test it for free, you just can’t build. Or check out the YouTube videos.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10335
Joined: Wed May 06, 2009 2:28 pm

Re: The end of XTalk / LiveCode for me

Post by dunbarx » Tue Aug 19, 2025 6:48 pm

@Mike
...a lot I don't know about. (I couldn't find Metadata even when searching for that feature, because I didn't know what it was called
I have been there. Like any dictionary, one has to know how to spell a word before one can find it. With LC, you are not even sure what word you are looking for.

@Everyone. This is a common issue. The dictionary is pretty good, especially when you are close to what you are looking for, and then the "related" section is often a GodSend. ChatGPT almost found "metaData". I wrote:

In the program "LiveCode" is there any feature that can associate additional data with individual words in a text field?

Good question — this goes right to the heart of how fields work in LiveCode.
🔹 Short answer:
LiveCode does not have a built-in way to attach arbitrary “hidden metadata” directly to individual words in a field. A field holds text (plus style attributes like font, color, size, link state). It doesn’t have per-word property slots.

It was factually wrong about metadata, but this was v.3. Maybe v.5 does better?

Craig

MichaelBluejay
Posts: 241
Joined: Thu Jul 01, 2010 11:50 am

Re: The end of XTalk / LiveCode for me

Post by MichaelBluejay » Tue Aug 19, 2025 9:54 pm

stam wrote:
Tue Aug 19, 2025 5:53 pm
You are greatly underselling LCs capabilities...
Okay, I'm listening, what am I missing? To me, if I'm going web-based, I can't see why I'd want the bloat of LiveCode for no discernible benefit when HTML/JS is easy to code, lightweight, and runs fast. If I'm making a standalone app, then sure, LiveCode or one of its competitors.
stam wrote:While 9.6.3 may not run on your Mac you should check out the open source Fork maintaining this version.
Thank you, I didn't know about that. I found OpenXTalk and downloaded it, but it wouldn't launch either. Even if it did, I just don't have a use for it any more, I already ported my apps to HTML/JS.
stam wrote:I will have to openly disagree with you about the speed of the datagrid. It’s plenty fast. And it’s much easier to manipulate than html tables - obviously you have to bother to learn it…
My experience is different. Scrolling a 1000x1200-pixel, 6-column DataGrid on my old Mac (i7/4GHz CPU) is pretty slow. Maybe it would be fast enough on a new Mac, but HTML tables scroll like lightning on my old computer. I can't test DataGrid on my new computer because LC won't launch.

And yeah, I did put some effort into learning DataGrid for my old LC-based accounting app, because I had to, because it was the opposite of intuitive. I I found myself constantly shaking my head at DataGrid's crazy syntax. I felt that DataGrid's difficulty went against the whole "XTalk is easy" idea. HTML/JS was way faster to learn by comparison.
stam wrote:But where LC shines is the backend of the app. There is a lot of code that is more laborious to do in JS.
I'm sure that's true though I haven't run across anything in HTML/JS that I felt was a lot easier in LC. I know, for example, that LC can refer to "words" of text, which is convenient, but I don't really use that feature. What other kinds of things are easier in LC vs. JS?

MichaelBluejay
Posts: 241
Joined: Thu Jul 01, 2010 11:50 am

Re: The end of XTalk / LiveCode for me

Post by MichaelBluejay » Tue Aug 19, 2025 9:56 pm

dunbarx wrote:
Tue Aug 19, 2025 6:48 pm
ChatGPT almost found "metaData". I wrote:

In the program "LiveCode" is there any feature that can associate additional data with individual words in a text field?
I asked something similar of the Google Search AI, but it too didn't come up with an answer.

stam
Posts: 3088
Joined: Sun Jun 04, 2006 9:39 pm

Re: The end of XTalk / LiveCode for me

Post by stam » Tue Aug 19, 2025 10:53 pm

MichaelBluejay wrote:
Tue Aug 19, 2025 9:54 pm
My experience is different. Scrolling a 1000x1200-pixel, 6-column DataGrid on my old Mac (i7/4GHz CPU) is pretty slow. Maybe it would be fast enough on a new Mac, but HTML tables scroll like lightning on my old computer. I can't test DataGrid on my new computer because LC won't launch.
Well that's not been my experience, even on my old Intel Mac (can't check again now as I'm abroad).
I do wonder if in fact you tested tableField rather than datagrid; the former has been proven to be slow when loading thousands of rows, the latter is orders of magnitude faster, and the new polygrid is even faster by an order of magnitude (polygrid comes with example stacks, one of which is a stack that compares tableField/datagrid/polygrid with large datasets). I should clarify that I only have experience of this for desktop apps. I haven't tested on web apps, because the whole web app process in LiveCode is not a great experience, but would not really expect a massive difference.

I have to put up my hand and say that I use different software for web apps. Specifically, I use XOJO - which makes it crazy easy to do decent database driven web apps, and have recently built a multiuser database app with an audience thousands of healthcare providers (already running and going public next month). I use XOJO because it's easy to produce professional looking interfaces coupled with fast and functional backend app - the whole thing took under 3 days to create to create and release this project.


Regarding your question that culminated in a discussion of metadata - metadata is a bad fit, unless you're using tableField (ie a text field), because you're not manipulating text, you're manipulating tables/tabular data, and you should use the right tools for the task.
Consider: With your HTML tables you are essentially adding a hidden key, so why would you not do the same with DataGrid (or PolyGrid/PolyList)?
You would just add as a hidden array key (or to put it simpler, a hidden column) so that data is always associated with the specific row and will always follow it around even if exported to other functions as an array.
In my opinion, metadata would be the wrong approach for what you are wanting to achieve.

MichaelBluejay wrote:
Tue Aug 19, 2025 9:54 pm
And yeah, I did put some effort into learning DataGrid for my old LC-based accounting app, because I had to, because it was the opposite of intuitive. I I found myself constantly shaking my head at DataGrid's crazy syntax. I felt that DataGrid's difficulty went against the whole "XTalk is easy" idea. HTML/JS was way faster to learn by comparison.
I would argue LiveCode is hard - for developers used to other languages. But once you 'grok' it, it's the nicest and easiest language out there.
Until then, it seems really quite arbitrary and illogical (that was my experience when I picked up LC properly during the pandemic but I eventually saw the light ;)).

The same goes for the datagrid. Once you 'grok' the API, it's really easy to do it all... but there is a learning curve to get over. It's not the easiest, but I personally don't think it's that hard and in spite the new flashy table widgets (polyGrid and polyList) I always come back to the datagrid because of its versatility and genuinely useful API - in my mind it's a masterpiece ;)
What I found helpful is a better LiveCode API documentation app - with a (paid) app called Dash (https://kapeli.com/dash). It greatly simplifies searching the datagrid API and is extremely useful for pretty much every possible programming language. I can't recommend highly enough, no matter which language you use.

MichaelBluejay wrote:
Tue Aug 19, 2025 9:54 pm
I'm sure that's true though I haven't run across anything in HTML/JS that I felt was a lot easier in LC. I know, for example, that LC can refer to "words" of text, which is convenient, but I don't really use that feature. What other kinds of things are easier in LC vs. JS?
To use the example from the mothership's site:

LiveCode

Code: Select all

sort lines of theText descending by last item of each
Javascript

Code: Select all

theText = theText.split("\n");
theText = theText.sort(sort_item_3).join("\n");
function sort_item_3(line1, line2){
	line1 = line1.split(",");
	line2 = line2.split(",");
	if(line1[2] == line2[2]) return 0;
	else if(line1[2] > line2[2]) return -1;
	else return 1;
}

A more complex example: Walk a given directory tree and print files matching a given pattern (recursive, so it includes subfolders)

LiveCode

Code: Select all

function pathsForDirectoryAndWildcardPattern pDirectory, pWildcardPattern
 filter files(pDirectory) with pWildcardPattern
   repeat for each line tFile in it
      put pDirectory & slash & tFile & cr after tPaths
   end repeat
   
   filter folders(pDirectory) without ".."
   repeat for each line tFolder in it
      put pathsForDirectoryAndWildcardPattern(pDirectory & slash & tFolder, pWildcardPattern) after tPaths
   end repeat
   
   return tPaths
end pathsForDirectoryAndWildcardPattern
Javascript

Code: Select all

var fso = new ActiveXObject("Scripting.FileSystemObject");

function walkDirectoryTree(folder, folder_name, re_pattern) {
    WScript.Echo("Files in " + folder_name + " matching '" + re_pattern + "':");
    walkDirectoryFilter(folder.files, re_pattern);

    var subfolders = folder.SubFolders;
    WScript.Echo("Folders in " + folder_name + " matching '" + re_pattern + "':");
    walkDirectoryFilter(subfolders, re_pattern);

    WScript.Echo();
    var en = new Enumerator(subfolders);
    while (! en.atEnd()) {
        var subfolder = en.item();
        walkDirectoryTree(subfolder, folder_name + "/" + subfolder.name, re_pattern);
        en.moveNext();
    }
}

function walkDirectoryFilter(items, re_pattern) {
    var e = new Enumerator(items);
    while (! e.atEnd()) {
        var item = e.item();
        if (item.name.match(re_pattern))
            WScript.Echo(item.name);
        e.moveNext();
    }
}

walkDirectoryTree(dir, dir.name, '\\.txt$');
JS is a very functional language, but for me, LiveCode is just easier, more succinct and more pleasant. I just wish their web offering was more like XOJO...

MichaelBluejay
Posts: 241
Joined: Thu Jul 01, 2010 11:50 am

Re: The end of XTalk / LiveCode for me

Post by MichaelBluejay » Wed Aug 20, 2025 1:36 am

I was definitely using Data Grid. My data is only 205 rows. It's about 2.5 screens of information. Scrolling as fast as I can with my Magic Mouse (swiping my finger across the top of the mouse) takes 4 seconds to go from the top to the bottom of the data.

I just made a 2000-row table with JS and I can drag the scroll thumb from the top to the bottom instantly, and scrolling with the mouse gesture scrolls the table as fast as I move my finger. Here's my code for the JS test:

Code: Select all

<div id=output style="height:100vh; overflow:scroll; border:2px solid black"></div>

<script>

charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890!@#$%^&*()[]{}/=\?+|- '
colors = ['gainsboro', 'beige', 'aliceblue', 'lavenderblush', 'mintcream', 'mistyrose', 'antiquewhite']

output = "<table>"

for (row=1; row <= 20000; row++) {

	color = colors[Math.floor(Math.random()*colors.length)]
	output += `<tr bgcolor='${color}'</tr>`

	for (cell = 1; cell <= 6; cell++) {

		str = ''
		for (chars = 1; chars <=7; chars++) {
			str+= charset[Math.floor(Math.random()*charset.length)]
		}
		output += `<td>${str}</td>`
   }
   output +="</tr>"

}

output += "</table>"
document.getElementById('output').innerHTML = output

</script>
For that matter, the LC code editor scrolls glacially for me, too. That's one of the main things I like about switching to JS with a text editor.

Also, I recall having a heck of a time just trying to colorize a row in the DataGrid. With JS it's trivial. And I think I never came up with a good solution to colorize a single cell, the colored cell changed rows as soon as the table was scrolled.
stam wrote:Regarding your question that culminated in a discussion of metadata - metadata is a bad fit...
I erred by using my accounting app in my sample code example in this thread which was misleading. In reality, for my ACCOUNTING app, I did exactly as you describe, use DataGrid with hidden fields. For my NOTES app, I didn't use tables at all; the left-hand pane is a text list of notes, that can be reordered by dragging up and down, and each of those lines needs to be associated with a noteID, so without knowing about MetaData, I was stuck keeping a separate index of noteIDs.
stam wrote:[one line of LC code to reverse-sort a text table by the last item of each line, 8 lines of JS code to do the same]
Okay, first of all, it can be done in JS easier than the example code:

Code: Select all

lines = theText.split("\n")
my2dArray = []
for (i=0; i < lines.length; i++) { 
   items = lines[i].split(' ')
   my2dArray[i] = items
}
my2dArray.sort( function (a,b) { return b[items.length-1] - a[items.length-1]} )
But almost all that code is just setting up the array. In my app, I already had to set up the array anyway for lots of other purposes. The code to actually sort is all of one line—same as with LC.
stam wrote:[shorter code in LC to walk a directory tree than in JS]
ChatGPT's JS code is shorter than LC's, unless you count the lines that have only punctuation, and in that case, it's 12 lines for JS and 11 for LC.

Code: Select all

const fs = require("fs");
const path = require("path");

/**
 * Recursively walk a directory and print files matching a pattern
 * @param {string} dir - Directory to start from
 * @param {RegExp} pattern - Regex pattern to match filenames
 */
function walkDir(dir, pattern) {
  fs.readdirSync(dir, { withFileTypes: true }).forEach((entry) => {
    const fullPath = path.join(dir, entry.name);

    if (entry.isDirectory()) {
      // Recurse into subdirectory
      walkDir(fullPath, pattern);
    } else if (entry.isFile() && pattern.test(entry.name)) {
      console.log(fullPath);
    }
  });
}
Granted, LC's syntax is *way* easier to follow.

Much of JS's terseness comes from using Node.js' "fs" module, which was released in 2017. I'm guessing that the LC code examples were generated before that.

stam
Posts: 3088
Joined: Sun Jun 04, 2006 9:39 pm

Re: The end of XTalk / LiveCode for me

Post by stam » Wed Aug 20, 2025 11:01 am

@MichaelBluejay - dude, if you want to use html/js then that's fine - millions do. Not quite sure why you're here arguing the case. if it suits you, then it's right for you. However, I do object to spouting incorrect information about LiveCode.

I maintain that datagrid is quite performant and polygrid much more so. I fully agree Datagrid is not as fast as html - if tables only render visible rows.
But your experience is not what I would expect and I can't explain why your small number of rows gave you such laggy performance.

For you information I attach a stack that compares the speed of loading a text field, a datagrid and a polygrid with 10,000 rows of 12 columns of random numbers. On average for me, on my M2 Pro, the text field takes 277 ms to load; the datagrid takes 100 ms and the polygrid 6 ms. And there is 0 appreciable lag scrolling the datagrid the full 10,000 rows.

the handler that generates all of this is:

Code: Select all

on mouseup
   local tText, tStart,tEnd
   put empty into tText
   repeat with x=1 to 10000
      repeat with y=1 to 12
         put random(5000) & tab after tText
      end repeat
      put cr after tText
   end repeat
   
   ---lock screen
   
   put the milliseconds into tStart
   set the pgtext of widget  1 to tText
   put the milliseconds into tEnd
   put  tEnd-tStart  & "ms" into field "spdwidget"
   
   put the milliseconds into tStart
   set the text of field "test" to tText
   put the milliseconds into tEnd
   put  tEnd-tStart  & "ms" into field "spdfield"
   
   put the milliseconds into tStart
   set the dgtext of group "test2" to tText
   put the milliseconds into tEnd
   put  tEnd-tStart & "ms" into field "spddg"
   
   --unlock screen
end mouseup
Granted, without LC 10 and the polygrid widget, you probably will not be able to use the polygrid, but you can at least test the text field vs the datagrid.


As a comparator, I used chatGPT to create the fastest possible method for displaying 10,000 records of 12 columns of random numbers and to time the process..
It generates all of the records - as expected - extremely quickly. It 'cheats' as it only ever renders the records visible in the table, not all of the lines, so the 20+ records render in 1 ms. However, if you force it to render all lines, the true speed shows up: 1400 ms (Safari 18.6 on MBP M2 Pro 16 Gb RAM running on MacOS Sequoia 15.6). Make of the numbers as you will.
The HTML/JS code is below:

Code: Select all

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>10,000×12 Table: Virtualized vs Full</title>
  <style>
    body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; margin: 24px; }
    h2 { margin: 0 0 8px; }
    .controls { display: flex; gap: 12px; align-items: center; margin: 12px 0 16px; flex-wrap: wrap; }
    button { padding: 8px 12px; border: 1px solid #ccc; border-radius: 8px; cursor: pointer; background: #fafafa; }
    .metrics { font-family: monospace; margin: 10px 0 16px; }
    .container {
      border: 1px solid #ccc;
      height: 520px;
      overflow: auto;
      position: relative;
      background: #fff;
    }
    table { border-collapse: collapse; width: 100%; table-layout: fixed; }
    th, td { border: 1px solid #ddd; padding: 2px 6px; text-align: right; font-family: monospace; }
    thead th { position: sticky; top: 0; background: #f3f3f3; z-index: 1; }
    /* Virtualized-only spacer (fills the scroll height) */
    .spacer { position: relative; width: 100%; }
    /* Make header + body align in both modes */
    .w-fixed thead, .w-fixed tbody tr { display: table; width: 100%; table-layout: fixed; }
    .w-fixed tbody { display: block; }
  </style>
</head>
<body>
  <h2>10,000×12 Random Number Table</h2>

  <div class="controls">
    <button id="toggleBtn">Mode: Virtualized</button>
    <button id="renderBtn">Render / Re-render</button>
    <span class="metrics" id="metrics">—</span>
  </div>

  <div class="container" id="container"></div>

  <script>
    // ---- Config ----
    const TOTAL_ROWS = 10000;
    const COLS = 12;
    const ROW_HEIGHT = 24;  // px (approx)
    const BUFFER = 20;      // extra rows above/below viewport for virtualization

    // ---- State ----
    let mode = "virtualized"; // "virtualized" | "full"
    let container = document.getElementById("container");
    let metrics = document.getElementById("metrics");
    let toggleBtn = document.getElementById("toggleBtn");
    let renderBtn = document.getElementById("renderBtn");

    // For virtualized mode
    let vElems = { spacer: null, table: null, theadRow: null, tbody: null };
    let onScrollHandler = null;

    // Deterministic "random" so values don't change when scrolling
    function valueAt(row, col) {
      return Math.abs(Math.floor(Math.sin(row * 1000 + col) * 10000));
    }

    function buildHeaderHTML() {
      let h = "";
      for (let c = 1; c <= COLS; c++) h += `<th>Col ${c}</th>`;
      return `<thead><tr>${h}</tr></thead>`;
    }

    // ----- FULL RENDER -----
    function renderFull() {
      teardownVirtualized();

      const start = performance.now();

      let bodyHTML = "";
      for (let r = 0; r < TOTAL_ROWS; r++) {
        bodyHTML += "<tr>";
        for (let c = 0; c < COLS; c++) {
          bodyHTML += `<td>${valueAt(r, c)}</td>`;
        }
        bodyHTML += "</tr>";
      }

      container.innerHTML = `
        <table class="w-fixed">
          ${buildHeaderHTML()}
          <tbody id="fullBody">${bodyHTML}</tbody>
        </table>
      `;

      // Measure after paint
      requestAnimationFrame(() => {
        const end = performance.now();
        const tbody = document.getElementById("fullBody");
        const rowsInDOM = tbody ? tbody.childElementCount : 0;
        updateMetrics(end - start, rowsInDOM, "Full");
      });
    }

    // ----- VIRTUALIZED RENDER -----
    function initVirtualized() {
      // Build static shell
      container.innerHTML = `
        <div class="spacer" id="vSpacer" style="height:${TOTAL_ROWS * ROW_HEIGHT}px"></div>
        <table id="vTable">
          ${buildHeaderHTML()}
          <tbody id="vBody"></tbody>
        </table>
      `;

      vElems.spacer = document.getElementById("vSpacer");
      vElems.table  = document.getElementById("vTable");
      vElems.tbody  = document.getElementById("vBody");

      // Initially render visible slice
      renderVirtualSlice();

      // Scroll handler
      onScrollHandler = () => renderVirtualSlice();
      container.addEventListener("scroll", onScrollHandler, { passive: true });
    }

    function teardownVirtualized() {
      if (onScrollHandler) {
        container.removeEventListener("scroll", onScrollHandler);
        onScrollHandler = null;
      }
    }

    function renderVirtualSlice() {
      const start = performance.now();

      const scrollTop = container.scrollTop;
      const viewportRows = Math.ceil(container.clientHeight / ROW_HEIGHT);
      const startRow = Math.max(0, Math.floor(scrollTop / ROW_HEIGHT) - BUFFER);
      const endRow = Math.min(TOTAL_ROWS, startRow + viewportRows + 2 * BUFFER);

      let html = "";
      for (let r = startRow; r < endRow; r++) {
        html += `<tr style="transform: translateY(${r * ROW_HEIGHT}px)">`;
        for (let c = 0; c < COLS; c++) {
          html += `<td>${valueAt(r, c)}</td>`;
        }
        html += `</tr>`;
      }
      vElems.tbody.innerHTML = html;

      const end = performance.now();
      // Report per-frame render time & current DOM row count
      updateMetrics(end - start, vElems.tbody.childElementCount, "Virtualized");
    }

    // ----- UI Wiring -----
    function updateMetrics(ms, domRows, label) {
      metrics.textContent = `${label} render: ${ms.toFixed(2)} ms · DOM rows: ${domRows}/${TOTAL_ROWS}`;
    }

    function renderCurrentMode() {
      if (mode === "virtualized") {
        initVirtualized();
      } else {
        renderFull();
      }
    }

    toggleBtn.addEventListener("click", () => {
      mode = (mode === "virtualized") ? "full" : "virtualized";
      toggleBtn.textContent = `Mode: ${mode.charAt(0).toUpperCase() + mode.slice(1)}`;
      renderCurrentMode();
    });

    renderBtn.addEventListener("click", renderCurrentMode);

    // Initial render
    renderCurrentMode();
  </script>
</body>
</html>



As for the code editor - we all agree. It's good but it's not the fastest and lacks many conveniences of modern code editors. I personally use VS Code for LiveCodeScript and it works fine as there is a code formatter/colourizer/syntax checker for LiveCode. I've also tested Sublime Text and that works just as well for LiveCode, but I mainly use the former.. Split screen editing is a key feature that I miss in LiveCode's SE - but at least on my current machine (M2 pro) I do not have noticeable lag using LC's script editor.

On that note I'll also point out that almost all Intel Macs are now considered 'vintage' by Apple and are no longer supported. Comparing performance on an unsupported Mac is an unfair comparison - a bit like complaining about Win11 performance on a windows laptop from 2010 with 4 Gb RAM.

At the end of the day I see your mindset is fixed. Feel free not to respond to this as it won't really change anything for anyone.
Attachments
SpeedTest.livecode.zip
(9.78 KiB) Downloaded 9 times
html speed test.html.zip
(2.68 KiB) Downloaded 6 times

Lagi Pittas
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 367
Joined: Mon Jun 10, 2013 1:32 pm

Re: The end of XTalk / LiveCode for me

Post by Lagi Pittas » Wed Aug 20, 2025 2:16 pm

MichaelBluejay wrote:
Tue Aug 19, 2025 4:59 pm

The advantages I can think of for LiveCode are:

• Changes are live as soon as you make them. No save file / switch from text editor to browser / reload page as with HTML/JS.
• Can make standalone apps.

I don't think I'll ever make a standalone app, but if I do, then I'd certainly use LiveCode.
In VS Code you can do this using extensions such as

Live Server (Ritwick Dey) - it launches a local dev server and refreshes the browser automatically when you save a file.

Live Preview (official Microsoft extension) - shows a browser preview right inside VS Code.

For standalone you have a few options

Electron – Node.js + Chromium. Biggest ecosystem, but heavy installs.
Tauri – uses system webview. Tiny binaries, very fast (we are told).
Neutralino.js – Ultra-light, minimal features, and very small footprint.
Nativefier – Easiest option if you just want to wrap an existing site. It creates an electron exe with just one command.
What is Nativefier?
Nativefier is a command-line tool that wraps a website for usage on macOS, Windows and/or Linux. Nativefier uses Electron under the hood to wrap these websites. Lots of companies, from Microsoft and Slack down to new startups use Electron for their web apps.
It's "easy" to get an app up and running with Electron but with Nativefier you can make an app/EXE with Electron using only the command line.

I've only ever used Electron (safety in what's been battle tested) but the exe has an overhead of about 60MB because you get a copy of Node and Chromium. Tauri and Neutralino us the builin Webview (maintained by Microsoft and based on Chromium). If you don't use node I would go with Tauri.

Also creating a PWA is another way to go for mobile - you don't need an app store and the bookmark on the home screen makes it act exactly like a mobile App.

I'm going to be checking this out sometime.
https://www.todesktop.com/guides/nativefier

MichaelBluejay
Posts: 241
Joined: Thu Jul 01, 2010 11:50 am

Re: The end of XTalk / LiveCode for me

Post by MichaelBluejay » Wed Aug 20, 2025 11:53 pm

stam wrote:
Wed Aug 20, 2025 11:01 am
dude, if you want to use html/js then that's fine - millions do. Not quite sure why you're here arguing the case. At the end of the day I see your mindset is fixed. Feel free not to respond to this as it won't really change anything for anyone.
Dude, WTF?! I'm just relaying my actual experience. What, I'm supposed to make decisions based on *your* experience rather than mine?

I downloaded your stack, and resized the Data Grid to be six columns wide and as tall as my screen. I started scrolling down by swiping the mouse, and then after 3 seconds tried to scroll up by swiping up. It took 7 seconds for the direction to reverse. And once it starts scrolling, I can't stop it, not by clicking outside the Data Grid, not by clicking on the scroll thumb.

I changed the script to generate only 200 rows and 6 columns, and set the Data Grid height to 1200px, same as my accounting app. It takes 4 seconds to swipe-scroll from the bottom to the top or vice-versa. That's just glacial. I don't dispute that your performance may be different, but that's my experience.

But, whatever, I see that your mindset is fixed.

stam
Posts: 3088
Joined: Sun Jun 04, 2006 9:39 pm

Re: The end of XTalk / LiveCode for me

Post by stam » Thu Aug 21, 2025 1:45 am

MichaelBluejay wrote:
Wed Aug 20, 2025 11:53 pm
Dude, WTF?! I'm just relaying my actual experience. What, I'm supposed to make decisions based on *your* experience rather than mine?
How "TF" did you get that I'm trying to dictate to you what to do!?!!?!?!?!?!
That comment is not only proof you have not read my post properly, but is also offensive.

In case it's still not clear, I am discussing livecode, not trying to tell you what to do.
I thought that was obvious from my very first sentence:
dude, if you want to use html/js then that's fine - millions do. Not quite sure why you're here arguing the case. if it suits you, then it's right for you. However, I do object to spouting incorrect information about LiveCode.

My comment centres exactly and only on your repeated comments that the datagrid is sooo sloooow, when that is not the case in my experience.
I made the datagrid in the previously attached stack 1160 x 960 and was able to scroll all 10,000 records in the datagrid back and forth without any lag. And datagrid is not the fastest, polygrid is, by an order of magnitude, but it is performant enough on current hardware (not the newest hardware). I cannot replicate your "actual experience" on my hardware.

Is the datagrid the fastest? No, obviously not (and you'll note that I have agreed with you on several of your points - including pricing and the fact that I don't feel LC's web offering is a good experience - but that has all passed you by it seems). But it is performant enough on current hardware and software so that there is no noticeable issue.

When I'm back in the country I will speed test it on my old i7 Intel MBP (2016) for comparison. It may well be that it does not work as well on older Macs, but then a very large percentage of Intel Macs are now designated as 'vintage' by Apple (including models sold as recently as 2019) and most are unable to officially receive OS updates. Running an app on an old Mac, with an old OS and old version of LC would be like complaining I couldn't run Win11 fluidly on a 20 year laptop with 4 Gb RAM.

Running it on my 2016 MBP will be a true test as I've used OpenCore Patcher to install MacOS Sequoia 15.5 on it, even though the last officially supported OS for this is MacOS Sierra - so there will be extra overhead for the unsupported, near-current OS as well (the current 15.6 is not yet fully supported in OpenCore Patcher).

My comment that you need not respond is a recognition that you have found a solution that works better for you and that you are not re-considering LiveCode, so ongoing discussion is moot - it is clear in every single one of your posts that you have already made your decision and more power to you if it works for you. Yet still you respond, and quite offensively at that.

Best of luck in your endeavours.

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10115
Joined: Fri Feb 19, 2010 10:17 am

Re: The end of XTalk / LiveCode for me

Post by richmond62 » Thu Aug 21, 2025 7:55 am

This thread is a bit odd:

1. It started by the OP stating that he was not going to use LiveCode any more (why he had to announce that was a mystery to me).

2. Then it became a sort of "compare and contrast" exercise between LC and various other programming environments.

2.1. This, apparently, contained information that was wrong about LiveCode.

So: as to #1: erm, so what? Should we care?

And: as to #2: well, if you like, but at least get the information correct.

Obviously this is "Polly-Wolly-Doodle" as far as Polygrids are concerned:
-
SShot 2025-08-21 at 9.56.34.png
-
LiveCode 9.6.3, MacOS 15.7, INTEL MacMini 2018

FAST!

keliko
Posts: 95
Joined: Thu Aug 01, 2019 8:15 am

Re: The end of XTalk / LiveCode for me

Post by keliko » Thu Aug 21, 2025 10:56 am

Lagi Pittas wrote:
Wed Aug 20, 2025 2:16 pm
MichaelBluejay wrote:
Tue Aug 19, 2025 4:59 pm

The advantages I can think of for LiveCode are:

• Changes are live as soon as you make them. No save file / switch from text editor to browser / reload page as with HTML/JS.
• Can make standalone apps.

I don't think I'll ever make a standalone app, but if I do, then I'd certainly use LiveCode.
In VS Code you can do this using extensions such as

Live Server (Ritwick Dey) - it launches a local dev server and refreshes the browser automatically when you save a file.

Live Preview (official Microsoft extension) - shows a browser preview right inside VS Code.

For standalone you have a few options

Electron – Node.js + Chromium. Biggest ecosystem, but heavy installs.
Tauri – uses system webview. Tiny binaries, very fast (we are told).
Neutralino.js – Ultra-light, minimal features, and very small footprint.
Nativefier – Easiest option if you just want to wrap an existing site. It creates an electron exe with just one command.
What is Nativefier?
Nativefier is a command-line tool that wraps a website for usage on macOS, Windows and/or Linux. Nativefier uses Electron under the hood to wrap these websites. Lots of companies, from Microsoft and Slack down to new startups use Electron for their web apps.
It's "easy" to get an app up and running with Electron but with Nativefier you can make an app/EXE with Electron using only the command line.

I've only ever used Electron (safety in what's been battle tested) but the exe has an overhead of about 60MB because you get a copy of Node and Chromium. Tauri and Neutralino us the builin Webview (maintained by Microsoft and based on Chromium). If you don't use node I would go with Tauri.

Also creating a PWA is another way to go for mobile - you don't need an app store and the bookmark on the home screen makes it act exactly like a mobile App.

I'm going to be checking this out sometime.
https://www.todesktop.com/guides/nativefier


You should try PureBasic and FreeBasic. If your main goal is performance, PureBasic can have a very small size for a webview compared to Chromium-based frameworks like Electron. Access to the OS API is very easy with PureBasic. I’ve already tried LCB, and it was very difficult for me to do it in LiveCode.

Post Reply