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

[Feature][提案]通用化处理懒加载图片 #1108

Open
binsee opened this issue Sep 10, 2020 · 10 comments
Open

[Feature][提案]通用化处理懒加载图片 #1108

binsee opened this issue Sep 10, 2020 · 10 comments

Comments

@binsee
Copy link
Contributor

binsee commented Sep 10, 2020

说明

此issue试图为简悦带来处理页面懒加载图片的通用、更好用的方式。

大致思路为针对多数网站所使用的图片懒加载方式,寻找其共通点,来针对性的解决懒加载图片问题。

实现方式:

  • 纳入解析核心
  • 以独立插件形式发布
  • 适配站点时嵌入处理代码

相关链接

分析

不同站点的图片懒加载

<figure class="ma mb mc md me fo fd fe paragraph-image">
  <div class="fq fr ee fs aj">
    <div class="fd fe ok">
      <div class="fw s ee er">
        <div class="ol fy s">
          <div class="dn abu t u v cy aj bl fu fv">
            <img alt="Image for post" class="t u v cy aj fz ga gb" src="https://miro.medium.com/max/60/1*AC4wPGPzPZPiogJrJ3U26g.png?q=20" width="1003" height="540" />
          </div>
          <img alt="Image for post" class="dd ft t u v cy aj c" width="1003" height="540" />
          <noscript>
            <img
              alt="Image for post"
              class="t u v cy aj"
              src="https://miro.medium.com/max/2006/1*AC4wPGPzPZPiogJrJ3U26g.png"
              width="1003"
              height="540"
              srcset="
                https://miro.medium.com/max/552/1*AC4wPGPzPZPiogJrJ3U26g.png  276w,
                https://miro.medium.com/max/1104/1*AC4wPGPzPZPiogJrJ3U26g.png 552w,
                https://miro.medium.com/max/1280/1*AC4wPGPzPZPiogJrJ3U26g.png 640w,
                https://miro.medium.com/max/1400/1*AC4wPGPzPZPiogJrJ3U26g.png 700w
              "
              sizes="700px"/>
        </noscript>
        </div>
      </div>
    </div>
  </div>
</figure>
<figure data-size="normal">
  <noscript>
    <img 
    src="https://pic1.zhimg.com/50/v2-24142c274a200ca02148e605cbcce592_hd.gif?source=1940ef5c" 
    data-caption="" data-size="normal" data-rawwidth="643" data-rawheight="529" 
    data-thumbnail="https://pic2.zhimg.com/50/v2-24142c274a200ca02148e605cbcce592_hd.jpg?source=1940ef5c" width="643" 
    data-original="https://pic3.zhimg.com/v2-24142c274a200ca02148e605cbcce592_r.jpg?source=1940ef5c" />
  </noscript>
  <div>
    <div data-size="normal" data-za-detail-view-path-module="GifItem">
      <div class="sr-rd-content-center">
        <img class="" 
        src="https://pic2.zhimg.com/50/v2-24142c274a200ca02148e605cbcce592_hd.gif?source=1940ef5c">
      </div>
      </svg> //无用,省略掉
    </div>
  </div>
</figure>
<p>
  <a title="" href="https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1599194548" rel="lightbox" class="droppicssingleimage cboxElement" data-title="" style="">
    <img height="348" width="920" 
    data-speedcachelazy-srcset="
    https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1599194548 320w,
    https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1599194548 768w,
    https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1599194548 920w" 
    sizes="(max-width: 400px) 320px,(max-width: 768px) 768px,920px" alt="图像懒惰加载引擎" 
    class="speedcache-lazy speedcache-lazy-hidden imgInsert" data-click="lightbox" data-droppicscategory="275" data-droppicslightbox="lightbox" data-droppicspicture="3400" data-droppicssource="original" data-title="" 
    src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABI0lEQVQY0yWQy24bQRADye55SAsrCOz//zznlMCCLa+1Mz3NHPZI1IGF4uPxHTFJAti2zcwA/HveL95Leq4VKySY0d2v1ysACc/ns/fOff9ZKwi6u7mDwMmBiMgUAQGluJkDwLkBAIVkRBAEAbLWQvIUyUwgxxiSLpebu48xlOq9A5BUaGyt5UqsOIJzojWv1QCQdPdt2ySQlEQaoMwkLSLOH9tVv+6fW9cerdpYMsN6jGLOTFUOkAtNOsVn99XKKuMYx5jv8/bno43IzEjJLRMGhQQ3AKzGyq+RtXlpTb3X1xYFGcgJ6Lfd2e3gbeVCRias9kiv+IEkuthfdIwIS3BOVPDx8Xcd+9re5pSZkWdpACCBeWB8C4AVXn+RPKkh5jz+A4Xru5GdNOxzAAAAAElFTkSuQmCC" 
    data-speedcachelazy-src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" style="border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;margin: auto ; display: block; " title="">
    
    <noscript>
      <img srcset="
      https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1599194548 320w,
      https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1599194548 768w,
      https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1599194548 920w" 
      sizes="(max-width: 400px) 320px,(max-width: 768px) 768px,920px" alt="&#x56FE;&#x50CF;&#x61D2;&#x60F0;&#x52A0;&#x8F7D;&#x5F15;&#x64CE;" class="imgInsert" data-click="lightbox" data-droppicscategory="275" data-droppicslightbox="lightbox" data-droppicspicture="3400" data-droppicssource="original" data-title 
      src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" 
      style="border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;margin: auto ; display: block; " title>
    </noscript>
  </a>
</p>

共同点

由于以上使用的懒加载都要使用 js 来改变 img 元素内的 src 属性,以加载真实图片,而为了应对 JavaScript 不可用的情况,都使用了 <noscript> 来存放一个 <img> 来加载图片。

因此,我们有个简单的选择真实图片的方式,即使用 <noscript> 元素内的 <img> 放在阅读模式下用来加载图片。

我们通过几个例子可以看到,<noscript> 元素与懒加载图片的容器 <img> 是兄弟元素,或者 <img><noscript> 兄弟元素的子元素。

因此可以用此方式来选择

  • noscript元素 $(figure noscript)
  • 懒加载图片元素 $(figure noscript).parent().find('img')

由于以上站点中,<img> 的上级节点并非总是 <figure>,因此可以以 <noscript> 元素的内容来判断:

$('noscript').each(function(){
  var noscript = $(this).text();
  if(noscript.match(/<img/)) {
    // 说明是懒加载图片,将其父元素内容替换为 <noscript> 中的 img,以加载图片。
    $(this).parent().empty().append(noscript);
  }
});

上面的代码里,$(this).parent().empty().append(noscript); 是清空父元素,然后将 <noscript> 中的元素内容追加到父元素里。若不清空父元素(要确保删除父元素内其他 <img> 元素),则阅读模式中可能出现多余图片(如知乎会出现svg元素),导出的markdown里必然有多余图片。

最后

此思路的执行时间一个在于提取高亮内容前,一个在后,前者需要修改原始页面内容,后者不会修改原始页面内容,但目前存在一个问题,部分页面的 <noscript> 元素会被过滤掉无法进入高亮内容里

如:#1104 (comment) 示例页面:https://towardsdatascience.com/negative-binomial-regression-f99031bb25b4

阅读模式图片元素
image

如果在简悦提取高亮内容代码中,可以确保 <nosccipt> 标签(仅内容匹配到 <img )一定被提取到高亮内容里,则可使用此方法不修改原始页面的情况下让阅读模式能正常显示懒加载图片,且导出的markdown内图片信息也是正常的。

@binsee
Copy link
Contributor Author

binsee commented Sep 10, 2020

后续有其他使用懒加载图片的站点需要适配,也可以将链接附过来,验证是否可以做通用处理。

@Kenshin
Copy link
Owner

Kenshin commented Sep 11, 2020

okay 很棒的方式~

@leyle
Copy link

leyle commented Oct 6, 2020

现在有相关的解决方法发布到公众可用了吗

@binsee
Copy link
Contributor Author

binsee commented Oct 6, 2020

现在有相关的解决方法发布到公众可用了吗

此通用适配提案是对于解析模块的,需要 Kenshin 修改puplugin模块的原始代码(当前库中的js是build后的)。目前可参考 5d3df55 来对特定站点进行适配。

@binsee
Copy link
Contributor Author

binsee commented Oct 6, 2020

已经作为插件(ID: r3TZzVcIEn )提交,等待审核中

仍然存在问题:部分站点原文中的 <noscript> 标签未被提取到高亮内容中,对于此类需要在 puread 中确保 <noscript> 标签能被提取到高亮内容中,再由上述插件进行处理。

问题页面如 :

未能提取的情况示例之一:

// <noscript> 在 <a> 中
<p>
  <a title="" href="https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249" rel="lightbox" class="droppicssingleimage cboxElement" data-title="" style=""><img height="348" width="920" data-speedcachelazy-srcset="https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1601610249 320w,https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1601610249 768w,https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249 920w" sizes="(max-width: 400px) 320px,(max-width: 768px) 768px,920px" alt="图像懒惰加载引擎" class="imgInsert speedcache-lazy-loaded" data-click="lightbox" data-droppicscategory="275" data-droppicslightbox="lightbox" data-droppicspicture="3400" data-droppicssource="original" data-title="" src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" data-speedcachelazy-src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" style="border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;margin: auto ; display: block; " title="" srcset="https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1601610249 320w,https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1601610249 768w,https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249 920w">
    <noscript>
      <img srcset="https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1601610249 320w,https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1601610249 768w,https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249 920w" sizes="(max-width: 400px) 320px,(max-width: 768px) 768px,920px" alt="&#x56FE;&#x50CF;&#x61D2;&#x60F0;&#x52A0;&#x8F7D;&#x5F15;&#x64CE;" class="imgInsert" data-click="lightbox" data-droppicscategory="275" data-droppicslightbox="lightbox" data-droppicspicture="3400" data-droppicssource="original" data-title src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" style="border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;margin: auto ; display: block; " title>
    </noscript>
  </a>
</p>

@Kenshin
Copy link
Owner

Kenshin commented Oct 7, 2020

@binsee

嗨,我这几天用电脑不方便,先 Mark 下,明后天回复你。🙏

@binsee
Copy link
Contributor Author

binsee commented Oct 15, 2020

已经作为插件 (ID: r3TZzVcIEn ) 提交,等待审核中

仍然存在问题:部分站点原文中的 <noscript> 标签未被提取到高亮内容中,对于此类需要在 puread 中确保 <noscript> 标签能被提取到高亮内容中,再由上述插件进行处理。

问题页面如 :

未能提取的情况示例之一:

// <noscript> 在 <a> 中
<p>
  <a title="" href="https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249" rel="lightbox" class="droppicssingleimage cboxElement" data-title="" style=""><img height="348" width="920" data-speedcachelazy-srcset="https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1601610249 320w,https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1601610249 768w,https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249 920w" sizes="(max-width: 400px) 320px,(max-width: 768px) 768px,920px" alt="图像懒惰加载引擎" class="imgInsert speedcache-lazy-loaded" data-click="lightbox" data-droppicscategory="275" data-droppicslightbox="lightbox" data-droppicspicture="3400" data-droppicssource="original" data-title="" src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" data-speedcachelazy-src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" style="border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;margin: auto ; display: block; " title="" srcset="https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1601610249 320w,https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1601610249 768w,https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249 920w">
    <noscript>
      <img srcset="https://www.joomunited.com/images/com_droppics/275/responsive/300_image-lazy-loadin-seo.png?1601610249 320w,https://www.joomunited.com/images/com_droppics/275/responsive/768_image-lazy-loadin-seo.png?1601610249 768w,https://www.joomunited.com/images/com_droppics/275/full/image-lazy-loadin-seo.png?1601610249 920w" sizes="(max-width: 400px) 320px,(max-width: 768px) 768px,920px" alt="&#x56FE;&#x50CF;&#x61D2;&#x60F0;&#x52A0;&#x8F7D;&#x5F15;&#x64CE;" class="imgInsert" data-click="lightbox" data-droppicscategory="275" data-droppicslightbox="lightbox" data-droppicspicture="3400" data-droppicssource="original" data-title src="/images/com_droppics/275/full/image-lazy-loadin-seo.png?1563516562895" style="border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;margin: auto ; display: block; " title>
    </noscript>
  </a>
</p>

link #1215
对于未适配站点,简悦会使用内置分析引擎对页面内容进行智能提取,并缓存提取结果。见 #657 (comment)
但由于分析引擎比页面js先执行,而此时页面懒加载信息并未生成到<noscript>元素中。之后的插件等代码执行时,是从不含<noscript>元素缓存中提取高亮内容,因此本提案的处理懒加载图片的代码会无法生效。

解决方式:

  • 不缓存/清除内置分析引擎缓存的提取内容(推荐)
  • 延后简悦代码的执行时机,即在页面js执行后再执行简悦代码(不同站点的表现可能不一致)

@Kenshin
Copy link
Owner

Kenshin commented Oct 16, 2020

缓存/清除内置分析引擎缓存的提取内容

这么设计的原因是,希望在进入阅读模式时,能有个比较快的动效以及节省性能。

但确实没有考虑到一些诸如动态加载以及你提到的情况,我会考虑如何优化这些地方。(以及包括之前没有回复过你的几个 Issues

@binsee
Copy link
Contributor Author

binsee commented Oct 16, 2020

基于性能考虑使用缓存是必然的,这个能理解。
昨天试了下edge的阅读模式,例如维基百科的页面,微软团队针对性的进行了适配,排版比简悦的好看不少。
但是,edge的阅读模式不能显示懒加载图片,而简悦做到了,哈哈哈

@Kenshin
Copy link
Owner

Kenshin commented Oct 16, 2020

@binsee

我随便找了一页,在 Edge 上的效果如下:
image

感觉并没有太好?

PS:当然简悦的效果也没太好,我一直觉得像维基这类页面是无需适配的。 😌


惰性加载,论坛类页面,Latex 类页面目前都是简悦唯有的功能。 😀

@Kenshin Kenshin changed the title [提案]通用化处理懒加载图片 [Feature][提案]通用化处理懒加载图片 May 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants