@@ -19,9 +19,10 @@ import wvlet.uni.rx.{Cancelable, Rx}
1919import scala .scalajs .js
2020
2121/**
22- * Reactive window dimensions tracking.
22+ * Reactive window dimensions tracking with built-in throttling .
2323 *
24- * Tracks viewport and window sizes, updating on resize events.
24+ * Tracks viewport and window sizes, updating on resize events. Uses 100ms throttle with leading +
25+ * trailing edge updates for smooth performance.
2526 *
2627 * Usage:
2728 * {{{
@@ -41,18 +42,43 @@ import scala.scalajs.js
4142 */
4243object WindowDimensions :
4344
45+ private val throttleMs = 100 // Suitable interval for resize events
46+
4447 private class DimensionsVar extends Cancelable :
4548 private val innerWidthVar = Rx .variable(dom.window.innerWidth.toInt)
4649 private val innerHeightVar = Rx .variable(dom.window.innerHeight.toInt)
4750 private val outerWidthVar = Rx .variable(dom.window.outerWidth.toInt)
4851 private val outerHeightVar = Rx .variable(dom.window.outerHeight.toInt)
4952
53+ private var lastUpdateTime : Double = 0
54+ private var scheduledUpdate : js.UndefOr [Int ] = js.undefined
55+
56+ private def updateValues (): Unit =
57+ innerWidthVar := dom.window.innerWidth.toInt
58+ innerHeightVar := dom.window.innerHeight.toInt
59+ outerWidthVar := dom.window.outerWidth.toInt
60+ outerHeightVar := dom.window.outerHeight.toInt
61+
5062 private val handler : js.Function1 [dom.Event , Unit ] =
5163 _ =>
52- innerWidthVar := dom.window.innerWidth.toInt
53- innerHeightVar := dom.window.innerHeight.toInt
54- outerWidthVar := dom.window.outerWidth.toInt
55- outerHeightVar := dom.window.outerHeight.toInt
64+ val now = js.Date .now()
65+ if now - lastUpdateTime >= throttleMs then
66+ // Leading edge: update immediately
67+ lastUpdateTime = now
68+ updateValues()
69+ else if scheduledUpdate.isEmpty then
70+ // Trailing edge: schedule final update
71+ val delay = throttleMs - (now - lastUpdateTime).toInt
72+ scheduledUpdate = dom
73+ .window
74+ .setTimeout(
75+ () =>
76+ scheduledUpdate = js.undefined
77+ lastUpdateTime = js.Date .now()
78+ updateValues()
79+ ,
80+ delay
81+ )
5682
5783 dom.window.addEventListener(" resize" , handler)
5884
@@ -66,7 +92,10 @@ object WindowDimensions:
6692 def rxOuterWidth : Rx [Int ] = outerWidthVar
6793 def rxOuterHeight : Rx [Int ] = outerHeightVar
6894
69- override def cancel : Unit = dom.window.removeEventListener(" resize" , handler)
95+ override def cancel : Unit =
96+ dom.window.removeEventListener(" resize" , handler)
97+ scheduledUpdate.foreach(dom.window.clearTimeout)
98+ scheduledUpdate = js.undefined
7099
71100 end DimensionsVar
72101
0 commit comments