【问题标题】:Javascript Retina / HD display detection and blocking page render during reloadJavascript Retina / HD显示检测和重新加载期间阻止页面呈现
【发布时间】:2015-09-06 02:15:15
【问题描述】:

我的问题主要是关于页面重新加载而不是视网膜检测。我在 head 标签中使用下面的代码进行视网膜显示:

<script type="text/javascript">
               if( document.cookie.indexOf('device_pixel_ratio') == -1
                  && 'devicePixelRatio' in window
                  && window.devicePixelRatio == 2 ){

                var date = new Date();
                date.setTime( date.getTime() + 3600000000 );

                document.cookie = 'device_pixel_ratio=' + window.devicePixelRatio;
                //if cookies are not blocked, reload the page
                if(document.cookie.indexOf('device_pixel_ratio') != -1) {
                    window.location.reload(true);
                }
              }
</script>

它会检测访问者的屏幕类型,然后存储 cookie 并重新加载(如果是视网膜显示器)。它的工作没有问题,除了一个。

重新加载功能不会停止页面渲染。因此,您会在第一次访问时看到无样式的页面(半载),然后刷新。之后,由于存储了 cookie,网站的其余部分一切都很好。

很明显,PHP 没有提供检测屏幕类型的功能。必须通过JS来完成。但是 JS 没有合适的工具在不加载页面的情况下重新加载/重定向,甚至在 head 中使用了代码。

简而言之,我被困在两者之间。我希望有人可能会建议在首次加载时不显示任何内容的情况下重新加载(它甚至会显示我放在头部的内联样式)。还是在第一次加载时显示标准图像并让 Retina 用于其余的浏览体验是最佳选择?

顺便说一下,我尝试了 reload(true) 和 reload(false)。它没有帮助。


更新:请参阅下面 Marat Tanalin 的回答,了解可能的变通方法和更好的解决方案,以使用视网膜/高清显示图像,而不是存储 cookie + 重新加载。

在我对此进行深入研究之后,我意识到由于 *缓存方法,生成视网膜图像和标准图像可能并不是所有时间的答案。换句话说,在第一次访问时向访问者显示低质量图像并在刷新后显示高质量图像可能不起作用,因为低质量图像(和脚本)已经缓存。

我决定使用 1.5 倍的单张图片大小并支持 SVG 上传。虽然它不是各个方面的 100% 最佳答案,但比失去可靠性更好的选择。

*我是 Wordpress 开发人员,我参考了 WP Super Cache 和类似的缓存方法,但请注意,这也可能是其他缓存方法的问题。

【问题讨论】:

  • 你把这个脚本块放在哪里了?
  • 将此脚本移动到外部 JS 文件中。它会起作用的。
  • 哇,好电话!您能否将此作为回复发布,以便我接受您的回答。谢谢!
  • 我稍微修正了标题,我想这会有所帮助。再次感谢您的建议和帮助。
  • 没问题,现在可以了。

标签: javascript cookies retina


【解决方案1】:

本质上,您希望在运行此脚本之前停止页面呈现。

这可以使用外部 JS 文件来完成。当浏览器找到一个外部文件时,它会等到它运行。另一方面,如果你有一个内联的&lt;script&gt; 标签,那么浏览器就不会等待。

实际上,建议从不阻止页面呈现,以缩短页面加载时间,但为此目的是必要的。更多信息可以咨询https://developers.google.com/speed/docs/insights/BlockingJS

【讨论】:

  • 一个问题。页面加载时间问题仅影响客户端,但不影响 Google 或我认为的其他机器人?否则这个解决方案(我的意思是重新加载)可能会导致搜索引擎混乱,对吗?
  • 我不认为谷歌对脚本块有任何关注,但我不确定。我认为谷歌只查看原始 HTML,不解析任何 javascript,但我再次不确定。如果你愿意,你可以问另一个关于 SO 的问题。
  • @Mertafor 原来 Google 确实执行了 Javascript,但我不知道它如何处理 Javascript 的重定向。避免 Googlebot 造成混乱的一种潜在解决方案是将此脚本文件添加到您的 robots.txt 中,以便 Google 无法访问它。
  • 显然我应该调查一下。再次感谢您跟进此事。
【解决方案2】:

与使用纯 JS 解决方案相比,通常更好的做法是使用 CSS 进行样式设置、使用原生 HTML 元素作为内容图像,并在需要时使用不显眼的 JavaScript。不显眼的 JavaScript 意味着即使 JS 被禁用,网页也能正常工作。

在 CSS 中,只需使用媒体查询。

对于 HTML 中的响应式图像,有标准的 PICTURE 元素,但尚未得到广泛支持,因此可以使用像 picturefill 这样的 polyfill。

响应式图像的另一种可能方法:

  • 始终使用高分辨率图像(无论实际像素密度如何;会在一定程度上浪费流量并为低像素密度显示器的用户提供较低的图像质量);

  • 或使用 JavaScript 在页面加载时将低分辨率图像替换为高分辨率版本。为了防止在高分辨率版本之前加载低分辨率版本,可以将低分辨率版本放入NOSCRIPT元素中,然后动态读取内容并提取、修改图像源,并将NOSCRIPT元素替换为雇用图像通过 JS。

对于摄影图像,可接受的折衷方案是使用 1.5 倍图像。但要小心线稿图像(如徽标或方案):它们通常在 1:1 比例下看起来最好(当一个图像像素与一个物理显示像素完全对应时),并且在使用模糊缩放时可能会出现明显的质量损失。

此外,尽可能考虑使用 SVG 格式的矢量图像 - 无论实际像素密度如何,它们都可以在不损失质量的情况下进行缩放;但是,在具有常规像素密度的显示器上(例如,与 4K 显示器相比,流行的全高清显示器),与像素完美的 1:1 光栅图像相比,它们的视觉质量可能会明显降低。

【讨论】:

  • 我没有在问题中提到它,因为它可能无关紧要,但我正在研究一个 Wordpress 主题,它给全新的技术带来了一些限制。您建议的选项看起来非常流畅,虽然我对 NOSCRIPT 方法有点怀疑,但重新加载页面仍然是一个更好的选择。我正在研究一种在 img 标签上使用 data-retina 和 src 的方法(如上所述)来克服这个问题。但是很高兴知道图片和图片填充技术,谢谢。
  • 最让我困扰的一件事。与其创建低分辨率和高分辨率图像,不如只创建高分辨率图像?我的意思是它会影响您提到的页面加载时间,但它也会影响 Google 机器人、页面速度等。我想。由于图片较大,Chrome 的 Page Speed 会立即降低 20-40% 的页面得分。另一方面,我看到一些网络服务直接使用全尺寸图像,甚至不关心。我的问题很简单,我是通过使用 2 个版本作为高分辨率/低分辨率做正确的事情,还是使用一个高分辨率版本也是一种可接受的方法?
  • @Mertafor NOSCRIPT 方法(可能是我发明的 :-) 确实工作得很好:如果禁用 JS,用户至少会收到低分辨率图像,而如果启用 JS,用户将收到高分辨率图像,而无需在高分辨率图像之前下载低分辨率图像。
  • @Mertafor 至于哪种方法最好,实际上取决于每个具体情况。有时只使用高分辨率图像是合理的(例如,如果项目预算不足以同时考虑低分辨率和高分辨率变体),有时两者都使用是合理的(这样低分辨率显示器的用户会看到以 1:1 比例显示的更清晰的低分辨率图像,而不是由浏览器缩放的稍微模糊的高分辨率图像,但质量会有所损失)。由您决定在您的情况下,特定方法是否比另一种方法更合理。
  • 感谢@Marat 的详细解释。在我度过了一整夜之后,我意识到“还没有”最好的方法。虽然 Picturefill JS 看起来嵌入图像的工作量太大,但 Picture 尚未得到广泛支持。我几乎要提出一个新问题(也许我应该),但是您如何看待 1.5 倍而不是 2 倍?我进行了几次测试,但我看不到质量差异和“一张图片”,所有看起来都可以接受,虽然这不是最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 2013-08-18
  • 2012-09-06
  • 1970-01-01
相关资源
最近更新 更多