Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid unnecessary rerenders at init #512

Merged
merged 2 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions examples/escaping/dist/escaping/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,4 @@
<script type="module" crossorigin src="/assets/index.HASH.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index.HASH.css">
</head>
<body>
<div data-url="" display="none"></div>
<div><span class="elm-css-style-wrapper" style="display: none;"><style></style></span><label for="note"></label><div><span class="elm-css-style-wrapper" style="display: none;"><style>div > p{font-size:14px;color:rgb(255,0,0);}</style></span><div><p>Hello! 2 &gt; 1</p></div></div>&lt;script&gt;&lt;/script&gt; is unsafe in JSON unless it is escaped properly.&lt;script&gt;&lt;/script&gt; is unsafe in JSON unless it is escaped properly.<ul><li><span class="elm-css-style-wrapper" style="display: none;"><style></style></span>This is number 0</li></ul><ul><div><li><span class="elm-css-style-wrapper" style="display: none;"><style></style></span>This is nested number 0</li></div></ul></div>
</body>
</html>
<body><div data-url="" style="display: none;"></div><div id="elm-pages-announcer" aria-live="assertive" aria-atomic="true" style="position: absolute; top: 0; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); whiteSpace: nowrap; border: 0;"></div><div><span class="elm-css-style-wrapper" style="display: none;"><style></style></span><label for="note"></label><div><span class="elm-css-style-wrapper" style="display: none;"><style>div > p{font-size:14px;color:rgb(255,0,0);}</style></span><div><p>Hello! 2 &gt; 1</p></div></div>&lt;script&gt;&lt;/script&gt; is unsafe in JSON unless it is escaped properly.&lt;script&gt;&lt;/script&gt; is unsafe in JSON unless it is escaped properly.<ul><li><span class="elm-css-style-wrapper" style="display: none;"><style></style></span>This is number 0</li></ul><ul><div><li><span class="elm-css-style-wrapper" style="display: none;"><style></style></span>This is nested number 0</li></div></ul></div></body></html>
10 changes: 5 additions & 5 deletions generator/src/pre-render-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ export function templateHtml(devMode, userHeadTagsTemplate) {
${indent(userHeadTagsTemplate({ cliVersion: packageVersion }))}
<!-- PLACEHOLDER_HEAD_AND_DATA -->
</head>
<body>
<div data-url="" display="none"></div>
<!-- PLACEHOLDER_HTML -->
</body>
</html>`;
<body><div data-url="" style="display: none;"></div><div id="elm-pages-announcer" aria-live="assertive" aria-atomic="true" style="position: absolute; top: 0; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); whiteSpace: nowrap; border: 0;"></div><!-- PLACEHOLDER_HTML --></body></html>`;
// NOTE: The above line needs to:
// - Be in sync with `view` in Platform.elm (render the same elements).
// - Not include any extra whitespace. Even whitespace between </body> and </html> is parsed by browsers as a text node _inside_ <body>.
// This is to avoid unnecessary rerenders on init (when the first `view` call is diffed with the virtualized form of the above HTML).
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/AriaLiveAnnouncer.elm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ view title =

mainView : String -> Html msg
mainView title =
-- NOTE: If you make changes here, also update pre-render-html.js!
Html.div
[ Attr.id "elm-pages-announcer"
, Attr.attribute "aria-live" "assertive"
Expand Down
4 changes: 3 additions & 1 deletion src/Pages/Internal/Platform.elm
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ view config model =
in
{ title = title
, body =
-- NOTE: If you make changes here, also update pre-render-html.js!
[ onViewChangeElement model.url
, AriaLiveAnnouncer.view model.ariaNavigationAnnouncement
]
Expand All @@ -136,9 +137,10 @@ onViewChangeElement currentUrl =
-- it is used from the JS-side to reliably
-- check when Elm has changed pages
-- (and completed rendering the view)
-- NOTE: If you make changes here, also update pre-render-html.js!
Html.div
[ Attr.attribute "data-url" (Url.toString currentUrl)
, Attr.attribute "display" "none"
, Attr.style "display" "none"
]
[]

Expand Down
3 changes: 2 additions & 1 deletion src/Pages/Internal/Platform/Cli.elm
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,8 @@ render404Page config sharedData isDevServer path notFoundReason =

bodyToString : List (Html msg) -> String
bodyToString body =
body |> List.map (HtmlPrinter.htmlToString Nothing) |> String.join "\n"
-- NOTE: Don’t join the strings with a newline here – see pre-render-html.js.
body |> List.map (HtmlPrinter.htmlToString Nothing) |> String.concat


urlToRoute : ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage -> Url -> route
Expand Down
Loading