From 14ffcdd1cd72304b81a152a92e0258991ab1222b Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <3998+srid@users.noreply.github.com> Date: Thu, 22 Apr 2021 13:53:22 -0400 Subject: [PATCH] Speed up hot reload using Dom patching (#11) * Speed DOM replace using patch via morphdom * Don't send JS shims when sending HTML down websocket Don't need. * Fix a bug with recursive route switch * Iron out some bugs --- README.md | 10 +++--- src/Ema/Server.hs | 77 ++++++++++++++++++++++++++++++----------------- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 55bd7f0..48b06e3 100644 --- a/README.md +++ b/README.md @@ -28,22 +28,22 @@ Run `bin/run` (or Ctrl+Shift+B in VSCode). This runs the clock exampl - [x] client to server reconnect (on ghcid reload, or accidental client disconnect) - [x] or, investigate https://hackage.haskell.org/package/ghci-websockets - [x] Multi-websocket-client support -- [ ] Refactor Server.hs - [ ] Static site generation mode - [ ] add common examples, - [x] filesystem watcher - [ ] docs site for self (w/ sidebar and possibly even search) pre-announce, -- [ ] plan features / messaging, re: hakyll - - Safer and simpler routes system - - Template system? - [ ] CLI UX (opts, logging, etc.) -- [ ] documentation ([howto](https://documentation.divio.com/)) +- [ ] How to serve non-generated files (css, img, etc.) - [ ] Publish Data.LVar to Hackage +- [ ] documentation ([howto](https://documentation.divio.com/)) doc notes, - use async:race to avoid ghcid ghosts - at most one ws client supported right now - tailwind + blaze-html layout (BlazeWind?) for no-frills getting started - [dealing with errors](https://github.com/srid/memoir/issues/1) +- messaging re: hakyll + - safer/ simpler routes system + - bring your own templates / DSL diff --git a/src/Ema/Server.hs b/src/Ema/Server.hs index 4cb472e..f15520e 100644 --- a/src/Ema/Server.hs +++ b/src/Ema/Server.hs @@ -57,7 +57,7 @@ runServerWithWebSocketHotReload port model render = do Left newHtml -> do -- The page the user is currently viewing has changed. Send -- the new HTML to them. - WS.sendTextData conn $ routeHtml newHtml watchingRoute + WS.sendTextData conn $ renderWithEmaHtmlShims newHtml watchingRoute log $ "[Watch]: ~~> " <> show watchingRoute loop Right nextRoute -> do @@ -67,7 +67,7 @@ runServerWithWebSocketHotReload port model render = do -- request immediately following this). log $ "[Switch]: <~~ " <> show nextRoute html <- LVar.get model - WS.sendTextData conn $ routeHtml html nextRoute + WS.sendTextData conn $ renderWithEmaHtmlShims html nextRoute log $ "[Switch]: ~~> " <> show nextRoute loop try loop >>= \case @@ -81,13 +81,14 @@ runServerWithWebSocketHotReload port model render = do pure (H.status404, "No route") Just r -> do val <- LVar.get model - pure (H.status200, routeHtml val r) + pure (H.status200, renderWithEmaShims val r) f $ Wai.responseLBS status [(H.hContentType, "text/html")] v + renderWithEmaShims m r = + render m r <> emaStatusHtml <> wsClientShim + renderWithEmaHtmlShims m r = + render m r <> emaStatusHtml routeFromPathInfo = fromSlug . fmap (fromString . toString) - routeHtml :: model -> route -> LByteString - routeHtml m r = do - render m r <> emaStatusHtml <> wsClientShim -- | Return the equivalent of WAI's @pathInfo@, from the raw path string -- (`document.location.pathname`) the browser sends us. @@ -100,14 +101,33 @@ wsClientShim :: LByteString wsClientShim = encodeUtf8 [text| + +