preact icon indicating copy to clipboard operation
preact copied to clipboard

IE11: Fix incorrect node order with conditionals and text nodes

Open deadem opened this issue 10 months ago • 3 comments

There is an issue with using Element.contains in IE11. IE11 only partially supports contains: it works for Element nodes but does not support Text nodes. This can cause incorrect node ordering when conditionally rendering elements that include text nodes.

Minimal Repro:

import { render } from 'preact';
import { useEffect, useState } from 'preact/hooks';

export function App() {
  const [ showFirst, setShowFirst ] = useState(false);

  useEffect(function() {
    setTimeout(() => setShowFirst(true), 100);
  }, []);

  return (
    <div>
      {showFirst && <div>FIRST LINE</div>}
      plain text
      <div>LAST LINE</div>
    </div>
  );
}

Expected output:

FIRST LINE
plain text
LAST LINE

Actual output in IE11:

LAST LINE
FIRST LINE
plain text

deadem avatar Feb 10 '25 14:02 deadem

📊 Tachometer Benchmark Results

Summary

duration

  • create10k: unsure 🔍 -1% - +1% (-10.89ms - +6.97ms)
    preact-local vs preact-main
  • filter-list: unsure 🔍 -1% - +2% (-0.25ms - +0.26ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -2% - +1% (-1.45ms - +0.94ms)
    preact-local vs preact-main
  • many-updates: unsure 🔍 -2% - +1% (-0.42ms - +0.20ms)
    preact-local vs preact-main
  • replace1k: unsure 🔍 -4% - +1% (-2.57ms - +0.40ms)
    preact-local vs preact-main
  • text-update: unsure 🔍 -2% - +5% (-0.03ms - +0.10ms)
    preact-local vs preact-main
  • todo: unsure 🔍 -0% - +3% (-0.13ms - +0.97ms)
    preact-local vs preact-main
  • update10th1k: unsure 🔍 -4% - +4% (-1.31ms - +1.24ms)
    preact-local vs preact-main

usedJSHeapSize

  • create10k: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main
  • filter-list: unsure 🔍 -2% - +2% (-0.02ms - +0.03ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -5% - +1% (-0.54ms - +0.15ms)
    preact-local vs preact-main
  • many-updates: unsure 🔍 -0% - +0% (-0.01ms - +0.01ms)
    preact-local vs preact-main
  • replace1k: unsure 🔍 -0% - +0% (-0.01ms - +0.01ms)
    preact-local vs preact-main
  • text-update: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main
  • todo: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main
  • update10th1k: unsure 🔍 -0% - +0% (-0.01ms - +0.01ms)
    preact-local vs preact-main

Results

create10k
  • Browser: chrome-headless
  • Sample size: 50
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local974.30ms - 988.15ms-unsure 🔍
-1% - +1%
-10.89ms - +6.97ms
preact-main977.54ms - 988.83msunsure 🔍
-1% - +1%
-6.97ms - +10.89ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local19.21ms - 19.21ms-unsure 🔍
+0% - +0%
+0.00ms - +0.00ms
preact-main19.20ms - 19.20msunsure 🔍
-0% - -0%
-0.00ms - -0.00ms
-
filter-list
  • Browser: chrome-headless
  • Sample size: 50
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local16.37ms - 16.83ms-unsure 🔍
-1% - +2%
-0.25ms - +0.26ms
preact-main16.48ms - 16.70msunsure 🔍
-2% - +1%
-0.26ms - +0.25ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.54ms - 1.57ms-unsure 🔍
-2% - +2%
-0.02ms - +0.03ms
preact-main1.54ms - 1.57msunsure 🔍
-2% - +2%
-0.03ms - +0.02ms
-
hydrate1k
  • Browser: chrome-headless
  • Sample size: 80
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local76.92ms - 78.50ms-unsure 🔍
-2% - +1%
-1.45ms - +0.94ms
preact-main77.07ms - 78.86msunsure 🔍
-1% - +2%
-0.94ms - +1.45ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local11.49ms - 11.94ms-unsure 🔍
-5% - +1%
-0.54ms - +0.15ms
preact-main11.65ms - 12.18msunsure 🔍
-1% - +5%
-0.15ms - +0.54ms
-
many-updates
  • Browser: chrome-headless
  • Sample size: 50
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local16.55ms - 16.90ms-unsure 🔍
-2% - +1%
-0.42ms - +0.20ms
preact-main16.58ms - 17.09msunsure 🔍
-1% - +2%
-0.20ms - +0.42ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local3.75ms - 3.77ms-unsure 🔍
-0% - +0%
-0.01ms - +0.01ms
preact-main3.75ms - 3.77msunsure 🔍
-0% - +0%
-0.01ms - +0.01ms
-
replace1k
  • Browser: chrome-headless
  • Sample size: 100
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local68.51ms - 70.25ms-unsure 🔍
-4% - +1%
-2.57ms - +0.40ms
preact-main69.26ms - 71.66msunsure 🔍
-1% - +4%
-0.40ms - +2.57ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local2.97ms - 2.98ms-unsure 🔍
-0% - +0%
-0.01ms - +0.01ms
preact-main2.97ms - 2.99msunsure 🔍
-0% - +0%
-0.01ms - +0.01ms
-

run-warmup-0

VersionAvg timevs preact-localvs preact-main
preact-local30.64ms - 31.23ms-unsure 🔍
-1% - +1%
-0.42ms - +0.39ms
preact-main30.67ms - 31.23msunsure 🔍
-1% - +1%
-0.39ms - +0.42ms
-

run-warmup-1

VersionAvg timevs preact-localvs preact-main
preact-local35.43ms - 36.29ms-unsure 🔍
-3% - +1%
-0.91ms - +0.33ms
preact-main35.71ms - 36.60msunsure 🔍
-1% - +3%
-0.33ms - +0.91ms
-

run-warmup-2

VersionAvg timevs preact-localvs preact-main
preact-local27.20ms - 27.59ms-unsure 🔍
-1% - +1%
-0.36ms - +0.19ms
preact-main27.28ms - 27.67msunsure 🔍
-1% - +1%
-0.19ms - +0.36ms
-

run-warmup-3

VersionAvg timevs preact-localvs preact-main
preact-local27.10ms - 28.28ms-unsure 🔍
-5% - +1%
-1.34ms - +0.40ms
preact-main27.52ms - 28.80msunsure 🔍
-1% - +5%
-0.40ms - +1.34ms
-

run-warmup-4

VersionAvg timevs preact-localvs preact-main
preact-local25.25ms - 26.60ms-unsure 🔍
-2% - +5%
-0.62ms - +1.26ms
preact-main24.95ms - 26.26msunsure 🔍
-5% - +2%
-1.26ms - +0.62ms
-

run-final

VersionAvg timevs preact-localvs preact-main
preact-local21.34ms - 21.75ms-unsure 🔍
-2% - +0%
-0.52ms - +0.10ms
preact-main21.53ms - 21.98msunsure 🔍
-0% - +2%
-0.10ms - +0.52ms
-
text-update
  • Browser: chrome-headless
  • Sample size: 200
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local2.03ms - 2.13ms-unsure 🔍
-2% - +5%
-0.03ms - +0.10ms
preact-main2.00ms - 2.09msunsure 🔍
-5% - +2%
-0.10ms - +0.03ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.12ms - 1.12ms-unsure 🔍
+0% - +0%
+0.00ms - +0.00ms
preact-main1.11ms - 1.11msunsure 🔍
-0% - -0%
-0.00ms - -0.00ms
-
todo
  • Browser: chrome-headless
  • Sample size: 50
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local33.79ms - 34.84ms-unsure 🔍
-0% - +3%
-0.13ms - +0.97ms
preact-main33.72ms - 34.06msunsure 🔍
-3% - +0%
-0.97ms - +0.13ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.22ms - 1.23ms-unsure 🔍
+0% - +0%
+0.00ms - +0.00ms
preact-main1.22ms - 1.22msunsure 🔍
-0% - -0%
-0.00ms - -0.00ms
-
update10th1k
  • Browser: chrome-headless
  • Sample size: 50
  • Built by: CI #4320
  • Commit: 9a06c29

duration

VersionAvg timevs preact-localvs preact-main
preact-local32.35ms - 34.13ms-unsure 🔍
-4% - +4%
-1.31ms - +1.24ms
preact-main32.36ms - 34.18msunsure 🔍
-4% - +4%
-1.24ms - +1.31ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local2.93ms - 2.95ms-unsure 🔍
-0% - +0%
-0.01ms - +0.01ms
preact-main2.93ms - 2.95msunsure 🔍
-0% - +0%
-0.01ms - +0.01ms
-

tachometer-reporter-action v2 for CI

github-actions[bot] avatar Feb 10 '25 14:02 github-actions[bot]

Wow! There is already a hack: https://github.com/preactjs/preact/blob/3ff5f50e18da99ea05ace253740584ca0a97fa47/compat/src/portals.js#L42

deadem avatar Feb 10 '25 14:02 deadem

Coverage Status

coverage: 99.62% (+0.002%) from 99.618% when pulling 9a06c296e3f3160b815bdcbe24241737ab4043dd on deadem:ie-contains-fix into 3ff5f50e18da99ea05ace253740584ca0a97fa47 on preactjs:main.

coveralls avatar Feb 13 '25 02:02 coveralls