From 723b70e56866c486002d7800fbfa28deb8ef01d2 Mon Sep 17 00:00:00 2001
From: Alexander Chernyshev
<33011221+AlexanderChernyshev@users.noreply.github.com>
Date: Wed, 21 Feb 2024 12:36:18 -0500
Subject: [PATCH 1/8] copy for skeletal designs
---
src/patterns/skeletal_designs.md | 78 ++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 src/patterns/skeletal_designs.md
diff --git a/src/patterns/skeletal_designs.md b/src/patterns/skeletal_designs.md
new file mode 100644
index 0000000..592cdb0
--- /dev/null
+++ b/src/patterns/skeletal_designs.md
@@ -0,0 +1,78 @@
+---
+layout: layout.njk
+title: Skeletal Designs
+tags: pattern
+thumbnail:
+---
+
+# {{ title }}
+
+Technique introduced by Luke Wroblewsky and used by many sites, including Facebook's and LinkedIn's newsfeeds can be utilized to indicate progress and provide visual cue to what user should expect reducing cognitive load and user's frustration.
+
+## In-Progress State
+
+This technique allows the *in-progress state* of the page to be helpful to user-experience, rather than a hinderance.
+
+Defining the in-progress state should be a delibarate part of the design process.
+
+## Why this is needed
+
+This solves the problem of the empty screen: instead of having to wait for data to show up, the user can see visual cues and information about the page's content before the actual data has arrived.
+
+These cues can be multiple things:
+
+* known headers and titles for sections of the document
+* field names ex: price, amount of items
+* the visual layout of the page
+* zones for different content on the page
+
+@TODO show an animated example that combines these items
+
+Why are zones important?
+They allow users to do a first pass and understand the structure of the page ahead of time, which allows for easier navigation of the data once the page has fully loaded.
+
+This helps reduce cognitive load for users, which reduces the stress of taking in the site. By having the zones establish their dimensions and prupose at the beginning of the loaing process, and the final content filing in to that structure, the strain of the user to take in the whole is spread out over the loading time and thus reduced. As opposed to having to first wait and recieve no information, and then being hit by a large amount of information and struggling to get your bearings when you would want to start navigating already.
+
+### Reduced Perception Time
+It is not just about the technical aspects of loading the page. With this method we reduce the perception time of the user. Without this technique, the user is unable to prepare for navigating the page, and when it finally loads all at once they must spend more time parsing it before they can use it. Whereas with this technique, the user can be prepared to navigate the page once fully loaded, and needs less time to get their bearings and start using the page.
+
+@TODO diagram showing dirstribution of perception over loading time
+
+## Things to avoid
+
+It is critical to avoid layout shift once content loads. You want to make sure that the zones the users see before the page loads match the final layout. Otherwise users would have to make another pass to readjust to the page structure, defeating the purpose of having the zones during loading, and nullifying the advantages this would provide, namely the user having a map of navigation of the page.
+
+@TODO have animated example of layout shift
+
+ [Cumulative Layout Shift](https://web.dev/articles/cls) (CLS) metric that is part of Core Web Vitals is a measure of layout shift and is useful for tracking it for both skeletal designs and during regular page load.
+
+### Wave-ey Gray Boxes
+
+Unfortunately, it became common practice to use a simple to build but not good solution of pulsating gray boxes which occupy the space of the page but do not always set the exact dimensions of the layout.
+
+In some cases the exact dimesnions are in fact unknown, but in many cases we can know the layout up-front. As such, designers should analyze the content of the page to set dimensions that are known, instead of defaulting to generic solutions or placeholders.
+
+One common exception to this are social media feeds, where we cannot know what *type* of content will be in the feed.
+
+This unfortunate technique was popularized by the need to solve this issue on social networks, which then became taken as standard practice when it should have remained an exception.
+
+@TODO image here of social network feed
+
+### Do not delay content!
+Needless to say, that skeleton design should only be used when it is necessary to wait for additional content and there is not technical solution for loading the data faster.
+
+DO NOT artificially create this multi-step process.
+
+Spend time investigating technical solutions to load content faster. Only use skeletal designs if there is no alternative.
+
+## Examples and Solutions
+
+Designers and Engineers need to spend time thinking of the in-progress state of the page.
+
+Using different backround color for zones when using skeletal design loading is a good way to establish zones and their purpose when nothing else, such as textual labels or actual content, is known ahead of time about them.
+
+In particular, this is useful for spaces that will be occupied by images, as image resources inherently take time to load over the network.
+
+## Resources
+
+* [Mobile Design Details: Avoid The Spinner](https://www.lukew.com/ff/entry.asp?1797) by [Luke Wroblewsky](https://lukew.com/)
From 82801269793d99b5d9f703bc12dcc398c4fec2a7 Mon Sep 17 00:00:00 2001
From: Alexander Chernyshev
<33011221+AlexanderChernyshev@users.noreply.github.com>
Date: Fri, 23 Feb 2024 12:15:35 -0500
Subject: [PATCH 2/8] perception time diagram
---
src/assets/skeletal_design_perception_time_diagram.svg | 1 +
src/patterns/skeletal_designs.md | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
create mode 100644 src/assets/skeletal_design_perception_time_diagram.svg
diff --git a/src/assets/skeletal_design_perception_time_diagram.svg b/src/assets/skeletal_design_perception_time_diagram.svg
new file mode 100644
index 0000000..92a9279
--- /dev/null
+++ b/src/assets/skeletal_design_perception_time_diagram.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/patterns/skeletal_designs.md b/src/patterns/skeletal_designs.md
index 592cdb0..152049e 100644
--- a/src/patterns/skeletal_designs.md
+++ b/src/patterns/skeletal_designs.md
@@ -36,7 +36,10 @@ This helps reduce cognitive load for users, which reduces the stress of taking i
### Reduced Perception Time
It is not just about the technical aspects of loading the page. With this method we reduce the perception time of the user. Without this technique, the user is unable to prepare for navigating the page, and when it finally loads all at once they must spend more time parsing it before they can use it. Whereas with this technique, the user can be prepared to navigate the page once fully loaded, and needs less time to get their bearings and start using the page.
-@TODO diagram showing dirstribution of perception over loading time
+
+
+Diagram showing dirstribution of perception over loading time
+
## Things to avoid
From 1ffeb7d695b8c8018449a888cc0ea917682968a2 Mon Sep 17 00:00:00 2001
From: Alexander Chernyshev
<33011221+AlexanderChernyshev@users.noreply.github.com>
Date: Fri, 1 Mar 2024 11:36:00 -0500
Subject: [PATCH 3/8] callout and excerpt
---
package.json | 1 -
src/patterns/skeletal_designs.md | 10 +++++++---
src/style.css | 8 ++++++++
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index 4149c63..fb55ef9 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,6 @@
"description": "",
"main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
"start": "npx @11ty/eleventy --serve",
"build": "npx @11ty/eleventy"
},
diff --git a/src/patterns/skeletal_designs.md b/src/patterns/skeletal_designs.md
index 152049e..3d10843 100644
--- a/src/patterns/skeletal_designs.md
+++ b/src/patterns/skeletal_designs.md
@@ -4,6 +4,8 @@ title: Skeletal Designs
tags: pattern
thumbnail:
---
+Technique introduced by Luke Wroblewsky and used by many sites, including Facebook's and LinkedIn's newsfeeds can be utilized to indicate progress and provide visual cue to what user should expect reducing cognitive load and user's frustration.
+
# {{ title }}
@@ -26,7 +28,7 @@ These cues can be multiple things:
* the visual layout of the page
* zones for different content on the page
-@TODO show an animated example that combines these items
+@TODO show an animated example that combines these items, or follow https://www.lukew.com/ff/entry.asp?1797 example.
Why are zones important?
They allow users to do a first pass and understand the structure of the page ahead of time, which allows for easier navigation of the data once the page has fully loaded.
@@ -37,7 +39,7 @@ This helps reduce cognitive load for users, which reduces the stress of taking i
It is not just about the technical aspects of loading the page. With this method we reduce the perception time of the user. Without this technique, the user is unable to prepare for navigating the page, and when it finally loads all at once they must spend more time parsing it before they can use it. Whereas with this technique, the user can be prepared to navigate the page once fully loaded, and needs less time to get their bearings and start using the page.
-
+Diagram showing dirstribution of perception over loading time
@@ -47,7 +49,9 @@ It is critical to avoid layout shift once content loads. You want to make sure t
@TODO have animated example of layout shift
- [Cumulative Layout Shift](https://web.dev/articles/cls) (CLS) metric that is part of Core Web Vitals is a measure of layout shift and is useful for tracking it for both skeletal designs and during regular page load.
+
+Cumulative Layout Shift (CLS) metric that is part of Core Web Vitals is a measure of layout shift and is useful for tracking it for both skeletal designs and during regular page load.
+
### Wave-ey Gray Boxes
diff --git a/src/style.css b/src/style.css
index 55643ea..84c37cb 100644
--- a/src/style.css
+++ b/src/style.css
@@ -6,6 +6,14 @@
margin-right: 0.5em;
}
+.callout {
+ background-color: rgb(255, 241, 185);
+ border: solid 0.1em rgb(255, 223, 96);
+ border-left-width: 1em;
+ padding: 1.5em;
+ border-radius: 5px;
+}
+
header span {
display: flex;
align-items: center;
From e460df284af0cdddcd00b87ad3d8c609f406570d Mon Sep 17 00:00:00 2001
From: Alexander Chernyshev
<33011221+AlexanderChernyshev@users.noreply.github.com>
Date: Fri, 1 Mar 2024 12:07:45 -0500
Subject: [PATCH 4/8] explanation of progresseive load alternative
---
src/patterns/skeletal_designs.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/patterns/skeletal_designs.md b/src/patterns/skeletal_designs.md
index 3d10843..4b6fed3 100644
--- a/src/patterns/skeletal_designs.md
+++ b/src/patterns/skeletal_designs.md
@@ -65,6 +65,8 @@ This unfortunate technique was popularized by the need to solve this issue on so
@TODO image here of social network feed
+An alternative solution to the gray boxes in this particular case might be to progressively load content without having any skeleton structure. This will show the progress of the page loading by the content appearing on the screen in order, and will not require additional cognitive load to redo the users understanding of the page structure.
+
### Do not delay content!
Needless to say, that skeleton design should only be used when it is necessary to wait for additional content and there is not technical solution for loading the data faster.
From f5eda72824a6bd8a4047d45945e09f6eaf0c79b4 Mon Sep 17 00:00:00 2001
From: Alexander Chernyshev
<33011221+AlexanderChernyshev@users.noreply.github.com>
Date: Thu, 7 Mar 2024 19:03:27 -0500
Subject: [PATCH 5/8] layout shift example
---
.eleventy.js | 2 +-
...s_skeletal_design_layout_shift_example.mp4 | Bin 0 -> 361171 bytes
src/patterns/skeletal_designs.md | 15 ++++++++++++--
src/style.css | 19 ++++++++++++++++++
4 files changed, 33 insertions(+), 3 deletions(-)
create mode 100644 src/assets/skeletal_designs_diagrams/speedpatterns_skeletal_design_layout_shift_example.mp4
diff --git a/.eleventy.js b/.eleventy.js
index d28a840..3fae35b 100644
--- a/.eleventy.js
+++ b/.eleventy.js
@@ -1,7 +1,7 @@
module.exports = function (eleventyConfig) {
// Set custom directories for input, output, includes, and data
eleventyConfig.addPassthroughCopy("src/style.css");
- eleventyConfig.addPassthroughCopy("src/assets/*");
+ eleventyConfig.addPassthroughCopy("src/assets/**");
eleventyConfig.setFrontMatterParsingOptions({
excerpt: true,
// Optional, default is "---"
diff --git a/src/assets/skeletal_designs_diagrams/speedpatterns_skeletal_design_layout_shift_example.mp4 b/src/assets/skeletal_designs_diagrams/speedpatterns_skeletal_design_layout_shift_example.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..4ee8a1190c2f2b6cd5d1cdef7b0f81af1d7fb715
GIT binary patch
literal 361171
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