mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 03:06:53 +08:00
UX: Remove loading="lazy"
from avatars for improved UX (#30897)
Lazy loading images naturally causes a slight delay, because the browser only starts to load them after laying out the DOM and checking whether they're in the viewport. Plus, in Safari, re-rendering the DOM of a lazy-loaded image always causes a brief flicker, even if the image is already cached in the browser. Lazy-loading is most beneficial on large one-off images which are often rendered outside the viewport. That's frequently the case for images which users share in topics. Avatars, on the other hand, are very small images, they're very often above-the-fold, and the same avatar often occurs many times on the same page. Therefore, this commit removes `loading="lazy"` from avatars, which should improve avatar load times in all browsers, and stop the flicker in Safari. --- Tapping logo to reload topic-list in Safari. Before: https://github.com/user-attachments/assets/242299f8-aa13-4991-b321-2f143603ed26 After: https://github.com/user-attachments/assets/5e5bfd28-3a78-40fd-af21-3d92e7b3ba8a
This commit is contained in:
@ -78,7 +78,7 @@ export function avatarImg(options, customGetURL) {
|
||||
title = ` title='${escaped}'`;
|
||||
}
|
||||
|
||||
return `<img loading='lazy' alt='' width='${size}' height='${size}' src='${url}' class='${classes}'${title}>`;
|
||||
return `<img alt='' width='${size}' height='${size}' src='${url}' class='${classes}'${title}>`;
|
||||
}
|
||||
|
||||
export function tinyAvatar(avatarTemplate, options) {
|
||||
|
@ -9,14 +9,6 @@ acceptance("Topic Discovery - Mobile", function (needs) {
|
||||
assert.dom(".topic-list").exists("the list of topics is rendered");
|
||||
assert.dom(".topic-list .topic-list-item").exists("has topics");
|
||||
|
||||
assert
|
||||
.dom("a[data-user-card=codinghorror] img.avatar")
|
||||
.hasAttribute(
|
||||
"loading",
|
||||
"lazy",
|
||||
"it adds loading=`lazy` to topic list avatars"
|
||||
);
|
||||
|
||||
await visit("/categories");
|
||||
assert.dom(".category").exists("has a list of categories");
|
||||
});
|
||||
|
@ -39,14 +39,6 @@ acceptance("Topic Discovery", function (needs) {
|
||||
"it shows user's full name in avatar title"
|
||||
);
|
||||
|
||||
assert
|
||||
.dom("a[data-user-card=eviltrout] img.avatar")
|
||||
.hasAttribute(
|
||||
"loading",
|
||||
"lazy",
|
||||
"it adds loading=`lazy` to topic list avatars"
|
||||
);
|
||||
|
||||
await visit("/c/bug");
|
||||
assert.dom(".topic-list").exists("the list of topics was rendered");
|
||||
assert.dom(".topic-list .topic-list-item").exists("has topics");
|
||||
|
@ -59,7 +59,7 @@ module("Unit | Utilities", function (hooks) {
|
||||
let avatarTemplate = "/path/to/avatar/{size}.png";
|
||||
assert.strictEqual(
|
||||
avatarImg({ avatarTemplate, size: "tiny" }),
|
||||
"<img loading='lazy' alt='' width='24' height='24' src='/path/to/avatar/48.png' class='avatar'>",
|
||||
"<img alt='' width='24' height='24' src='/path/to/avatar/48.png' class='avatar'>",
|
||||
"it returns the avatar html"
|
||||
);
|
||||
|
||||
@ -69,7 +69,7 @@ module("Unit | Utilities", function (hooks) {
|
||||
size: "tiny",
|
||||
title: "evilest trout",
|
||||
}),
|
||||
"<img loading='lazy' alt='' width='24' height='24' src='/path/to/avatar/48.png' class='avatar' title='evilest trout'>",
|
||||
"<img alt='' width='24' height='24' src='/path/to/avatar/48.png' class='avatar' title='evilest trout'>",
|
||||
"it adds a title if supplied"
|
||||
);
|
||||
|
||||
@ -79,7 +79,7 @@ module("Unit | Utilities", function (hooks) {
|
||||
size: "tiny",
|
||||
extraClasses: "evil fish",
|
||||
}),
|
||||
"<img loading='lazy' alt='' width='24' height='24' src='/path/to/avatar/48.png' class='avatar evil fish'>",
|
||||
"<img alt='' width='24' height='24' src='/path/to/avatar/48.png' class='avatar evil fish'>",
|
||||
"it adds extra classes if supplied"
|
||||
);
|
||||
|
||||
|
@ -368,7 +368,7 @@ module("Unit | Model | report", function (hooks) {
|
||||
const computedUsernameLabel = usernameLabel.compute(row);
|
||||
assert.strictEqual(
|
||||
computedUsernameLabel.formattedValue,
|
||||
"<a href='/admin/users/1/joffrey'><img loading='lazy' alt='' width='24' height='24' src='/' class='avatar' title='joffrey'><span class='username'>joffrey</span></a>"
|
||||
"<a href='/admin/users/1/joffrey'><img alt='' width='24' height='24' src='/' class='avatar' title='joffrey'><span class='username'>joffrey</span></a>"
|
||||
);
|
||||
assert.strictEqual(computedUsernameLabel.value, "joffrey");
|
||||
|
||||
@ -457,7 +457,7 @@ module("Unit | Model | report", function (hooks) {
|
||||
const userLink = computedLabels[0].compute(row).formattedValue;
|
||||
assert.strictEqual(
|
||||
userLink,
|
||||
"<a href='/forum/admin/users/1/joffrey'><img loading='lazy' alt='' width='24' height='24' src='/forum/' class='avatar' title='joffrey'><span class='username'>joffrey</span></a>"
|
||||
"<a href='/forum/admin/users/1/joffrey'><img alt='' width='24' height='24' src='/forum/' class='avatar' title='joffrey'><span class='username'>joffrey</span></a>"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -218,7 +218,7 @@ martin</div>
|
||||
<div class="chat-transcript" data-message-id="#{message1.id}" data-username="#{message1.user.username}" data-datetime="#{message1.created_at.iso8601}" data-channel-name="#{channel.name}" data-channel-id="#{channel.id}">
|
||||
<div class="chat-transcript-user">
|
||||
<div class="chat-transcript-user-avatar">
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost#{post.user.avatar_template.gsub("{size}", "48")}" class="avatar"></div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost#{post.user.avatar_template.gsub("{size}", "48")}" class="avatar"></div>
|
||||
<div class="chat-transcript-username">
|
||||
#{message1.user.username}</div>
|
||||
<div class="chat-transcript-datetime">
|
||||
@ -229,7 +229,7 @@ martin</div>
|
||||
<div class="chat-transcript" data-message-id="#{message2.id}" data-username="#{message2.user.username}" data-datetime="#{message2.created_at.iso8601}" data-channel-name="#{channel.name}" data-channel-id="#{channel.id}">
|
||||
<div class="chat-transcript-user">
|
||||
<div class="chat-transcript-user-avatar">
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost#{post.user.avatar_template.gsub("{size}", "48")}" class="avatar"></div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost#{post.user.avatar_template.gsub("{size}", "48")}" class="avatar"></div>
|
||||
<div class="chat-transcript-username">
|
||||
#{message2.user.username}</div>
|
||||
<div class="chat-transcript-datetime">
|
||||
|
@ -314,7 +314,7 @@ describe Chat::Message do
|
||||
<aside class="quote no-group" data-username="#{post.user.username}" data-post="#{post.post_number}" data-topic="#{topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_src}" class="avatar"><a href="http://test.localhost/t/some-quotable-topic/#{topic.id}/#{post.post_number}">#{topic.title}</a></div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_src}" class="avatar"><a href="http://test.localhost/t/some-quotable-topic/#{topic.id}/#{post.post_number}">#{topic.title}</a></div>
|
||||
<blockquote>
|
||||
<p>Mark me…this will go down in history.</p>
|
||||
</blockquote>
|
||||
@ -360,7 +360,7 @@ describe Chat::Message do
|
||||
Originally sent in <a href="/chat/c/-/#{chat_channel.id}">testchannel</a></div>
|
||||
<div class="chat-transcript-user">
|
||||
<div class="chat-transcript-user-avatar">
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_src}" class="avatar"></div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_src}" class="avatar"></div>
|
||||
<div class="chat-transcript-username">
|
||||
chatbbcodeuser</div>
|
||||
<div class="chat-transcript-datetime">
|
||||
@ -372,7 +372,7 @@ describe Chat::Message do
|
||||
<div class="chat-transcript chat-transcript-chained" data-message-id="#{msg2.id}" data-username="otherbbcodeuser" data-datetime="#{msg2.created_at.iso8601}">
|
||||
<div class="chat-transcript-user">
|
||||
<div class="chat-transcript-user-avatar">
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_src2}" class="avatar"></div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_src2}" class="avatar"></div>
|
||||
<div class="chat-transcript-username">
|
||||
otherbbcodeuser</div>
|
||||
<div class="chat-transcript-datetime">
|
||||
|
@ -45,7 +45,7 @@ RSpec.describe Jobs::ChangeDisplayName do
|
||||
<aside class="quote no-group" data-username="#{username}" data-post="1" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> #{new_display_name}:</div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> #{new_display_name}:</div>
|
||||
<blockquote>
|
||||
<p>quoted post</p>
|
||||
</blockquote>
|
||||
|
@ -269,7 +269,7 @@ RSpec.describe PrettyText do
|
||||
<aside class="quote no-group" data-username="#{user.username}" data-post="123" data-topic="456" data-full="true">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"> #{user.username}:</div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"> #{user.username}:</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
@ -291,7 +291,7 @@ RSpec.describe PrettyText do
|
||||
<aside class="quote no-group" data-username="#{user.username}" data-post="123" data-topic="456" data-full="true">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"> #{user.username}:</div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"> #{user.username}:</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
@ -312,7 +312,7 @@ RSpec.describe PrettyText do
|
||||
<aside class="quote no-group" data-username="#{user.username}" data-post="555" data-topic="666">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"> #{user.username}:</div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"> #{user.username}:</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
@ -338,7 +338,7 @@ RSpec.describe PrettyText do
|
||||
<aside class="quote group-#{group.name}" data-username="#{user.username}" data-post="2" data-topic="#{topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"><a href="http://test.localhost/t/this-is-a-test-topic/#{topic.id}/2">This is a test topic</a></div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/48.png" class="avatar"><a href="http://test.localhost/t/this-is-a-test-topic/#{topic.id}/2">This is a test topic</a></div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
|
@ -119,7 +119,7 @@ RSpec.describe QuoteRewriter do
|
||||
<aside class="quote no-group" data-username="codinghorror" data-post="1" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> Mr. Atwood:</div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> Mr. Atwood:</div>
|
||||
<blockquote>
|
||||
<p>quoted post</p>
|
||||
</blockquote>
|
||||
|
@ -469,7 +469,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote no-group" data-username="bar" data-post="1" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt='' width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<img alt='' width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<blockquote>
|
||||
<p>quoted post</p>
|
||||
</blockquote>
|
||||
@ -477,7 +477,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote no-group" data-username="bar">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<blockquote>
|
||||
<p>quoted post</p>
|
||||
</blockquote>
|
||||
@ -485,7 +485,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote no-group" data-username="bar" data-post="1" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<blockquote>
|
||||
<p>quoted post</p>
|
||||
</blockquote>
|
||||
@ -520,7 +520,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote no-group" data-username="bar" data-post="1" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="//test.localhost/letter_avatar_proxy/v4/letter/b/b77776/48.png" class="avatar"> Foo Bar:</div>
|
||||
<img alt="" width="24" height="24" src="//test.localhost/letter_avatar_proxy/v4/letter/b/b77776/48.png" class="avatar"> Foo Bar:</div>
|
||||
<blockquote>
|
||||
<p>quoted post</p>
|
||||
</blockquote>
|
||||
@ -551,7 +551,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote no-group" data-username="bar" data-post="1" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt='' width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<img alt='' width="24" height="24" src="#{avatar_url}" class="avatar"> bar:</div>
|
||||
<blockquote>
|
||||
<p>quoted</p>
|
||||
</blockquote>
|
||||
@ -597,7 +597,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote" data-post="#{quoted_post.post_number}" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar">
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar">
|
||||
<a href="#{protocol_relative_url(quoted_post.full_url)}">#{quoted_post.topic.title}</a>
|
||||
</div>
|
||||
<blockquote>
|
||||
@ -608,7 +608,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote" data-post="#{quoted_post.post_number}" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar">
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar">
|
||||
<a href="#{protocol_relative_url(quoted_post.topic.url)}">#{quoted_post.topic.title}</a>
|
||||
</div>
|
||||
<blockquote>
|
||||
@ -627,7 +627,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote" data-post="#{quoted_post.post_number}" data-topic="#{quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{avatar_url}" class="avatar">
|
||||
<img alt="" width="24" height="24" src="#{avatar_url}" class="avatar">
|
||||
<a href="#{protocol_relative_url(quoted_post.full_url)}">#{quoted_post.topic.title}</a>
|
||||
</div>
|
||||
<blockquote>
|
||||
@ -637,7 +637,7 @@ RSpec.describe UsernameChanger do
|
||||
<aside class="quote" data-post="#{another_quoted_post.post_number}" data-topic="#{another_quoted_post.topic.id}">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img loading="lazy" alt="" width="24" height="24" src="#{user_avatar_url(evil_trout)}" class="avatar">
|
||||
<img alt="" width="24" height="24" src="#{user_avatar_url(evil_trout)}" class="avatar">
|
||||
<a href="#{protocol_relative_url(another_quoted_post.full_url)}">#{another_quoted_post.topic.title}</a>
|
||||
</div>
|
||||
<blockquote>
|
||||
|
Reference in New Issue
Block a user