summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-08-02 19:57:15 +0200
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-08-02 19:57:15 +0200
commit274c8096e3ccc8ea008c1a038134ffddc302fd0d (patch)
treebec4006e995fa2e25026631b9a686149ae978956
parent6bbf7d51cf19203517b5b0d3ba20b1cc30eb7628 (diff)
Experimental: Removed lazyload.js and use postpone attribute instead
https://github.com/marienfressinaud/FreshRSS/issues/316 The performance of lazyload.js was not good enough, and not really needed anyway. This change mostly affects mainly situations when the content of articles is shown by default, not so much when they are collapsed Using HTML5 lazyload and postpone attributes by default on all img, audio, iframe, video. http://www.w3.org/TR/resource-priorities/#attr-postpone Postpone attribute is removed by JavaScript if the user does not want the lazyload behaviour. In the case when users do want the lazyload behaviour, in normal view with articles hidden, we furthermore use the data-original approach to be sure to support current browsers. +Corrected some bugs with enclosures, and some images not appearing before the first scroll. +Now faster regex processing img and iframe at once (was not practical with lazyload.js)
-rw-r--r--CHANGELOG2
-rw-r--r--README.md1
-rw-r--r--app/FreshRSS.php10
-rw-r--r--app/Models/Feed.php6
-rw-r--r--app/views/configure/reading.phtml2
-rw-r--r--app/views/helpers/javascript_vars.phtml1
-rw-r--r--app/views/helpers/view/normal_view.phtml10
-rw-r--r--app/views/helpers/view/reader_view.phtml18
-rw-r--r--lib/lib_rss.php20
-rw-r--r--p/scripts/jquery.lazyload.min.js15
-rw-r--r--p/scripts/main.js25
11 files changed, 32 insertions, 78 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 33cb810c4..969af92a7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,8 @@
* Improvements
* Security
* Basic protection against XSRF (Cross-Site Request Forgery) based on HTTP Referer (POST requests only)
+* Misc.
+ * Changed lazyload implementation
* Bux fixes in export function, add/remove users, keyboard shortcuts, etc.
diff --git a/README.md b/README.md
index fff08472b..8963e040c 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,6 @@ mysqldump -u utilisateur -p --databases freshrss > freshrss.sql
## Uniquement pour certaines options
* [bcrypt.js](https://github.com/dcodeIO/bcrypt.js)
* [phpQuery](http://code.google.com/p/phpquery/)
-* [Lazy Load](http://www.appelsiini.net/projects/lazyload)
## Si les fonctions natives ne sont pas disponibles
* [Services_JSON](http://pear.php.net/pepr/pepr-proposal-show.php?id=198)
diff --git a/app/FreshRSS.php b/app/FreshRSS.php
index 3443589c6..7c333b090 100644
--- a/app/FreshRSS.php
+++ b/app/FreshRSS.php
@@ -136,13 +136,9 @@ class FreshRSS extends Minz_FrontController {
Minz_View::appendScript('https://login.persona.org/include.js');
break;
}
- $includeLazyLoad = $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param ('output') === 'reader');
- Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')), false, !$includeLazyLoad, !$includeLazyLoad);
- if ($includeLazyLoad) {
- Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.lazyload.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.lazyload.min.js')));
- }
- Minz_View::appendScript (Minz_Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js')));
- Minz_View::appendScript (Minz_Url::display ('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js')));
+ Minz_View::appendScript(Minz_Url::display('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')));
+ Minz_View::appendScript(Minz_Url::display('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js')));
+ Minz_View::appendScript(Minz_Url::display('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js')));
}
private function loadNotifications () {
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 576f37760..fe1e52ea2 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -277,11 +277,11 @@ class FreshRSS_Feed extends Minz_Model {
$elinks[$elink] = '1';
$mime = strtolower($enclosure->get_type());
if (strpos($mime, 'image/') === 0) {
- $content .= '<br /><img src="' . $elink . '" alt="" />';
+ $content .= '<br /><img lazyload="" postpone="" src="' . $elink . '" alt="" />';
} elseif (strpos($mime, 'audio/') === 0) {
- $content .= '<br /><audio src="' . $elink . '" controls="controls" />';
+ $content .= '<br /><audio lazyload="" postpone="" preload="none" src="' . $elink . '" controls="controls" />';
} elseif (strpos($mime, 'video/') === 0) {
- $content .= '<br /><video src="' . $elink . '" controls="controls" />';
+ $content .= '<br /><video lazyload="" postpone="" preload="none" src="' . $elink . '" controls="controls" />';
}
}
}
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml
index 4d439e83d..d56726730 100644
--- a/app/views/configure/reading.phtml
+++ b/app/views/configure/reading.phtml
@@ -9,7 +9,7 @@
<div class="form-group">
<label class="group-name" for="posts_per_page"><?php echo Minz_Translate::t ('articles_per_page'); ?></label>
<div class="group-controls">
- <input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" />
+ <input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" min="5" max="50" />
</div>
</div>
diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml
index 6e0a20de3..a04d3d527 100644
--- a/app/views/helpers/javascript_vars.phtml
+++ b/app/views/helpers/javascript_vars.phtml
@@ -10,7 +10,6 @@ echo 'var ',
',auto_mark_site=', $mark['site'] ? 'true' : 'false',
',auto_mark_scroll=', $mark['scroll'] ? 'true' : 'false',
',auto_load_more=', $this->conf->auto_load_more ? 'true' : 'false',
- ',full_lazyload=', $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param('output') === 'reader') ? 'true' : 'false',
',does_lazyload=', $this->conf->lazyload ? 'true' : 'false',
',sticky_post=', $this->conf->sticky_post ? 'true' : 'false';
diff --git a/app/views/helpers/view/normal_view.phtml b/app/views/helpers/view/normal_view.phtml
index 6f172d579..55ef6bdf6 100644
--- a/app/views/helpers/view/normal_view.phtml
+++ b/app/views/helpers/view/normal_view.phtml
@@ -92,13 +92,9 @@ if (!empty($this->entries)) {
<div class="content <?php echo $content_width; ?>">
<h1 class="title"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo $item->title (); ?></a></h1>
<?php
- $author = $item->author ();
- echo $author != '' ? '<div class="author">' . Minz_Translate::t ('by_author', $author) . '</div>' : '';
- if ($lazyload) {
- echo $hidePosts ? lazyIframe(lazyimg($item->content())) : lazyimg($item->content());
- } else {
- echo $item->content();
- }
+ $author = $item->author();
+ echo $author != '' ? '<div class="author">' . Minz_Translate::t('by_author', $author) . '</div>' : '',
+ $lazyload && $hidePosts ? lazyimg($item->content()) : $item->content();
?>
</div>
<ul class="horizontal-list bottom"><?php
diff --git a/app/views/helpers/view/reader_view.phtml b/app/views/helpers/view/reader_view.phtml
index e37c78cb4..665f72849 100644
--- a/app/views/helpers/view/reader_view.phtml
+++ b/app/views/helpers/view/reader_view.phtml
@@ -21,19 +21,13 @@ if (!empty($this->entries)) {
</a>
<h1 class="title"><?php echo $item->title (); ?></h1>
- <div class="author">
- <?php $author = $item->author (); ?>
- <?php echo $author != '' ? Minz_Translate::t ('by_author', $author) . ' — ' : ''; ?>
- <?php echo $item->date (); ?>
- </div>
+ <div class="author"><?php
+ $author = $item->author();
+ echo $author != '' ? Minz_Translate::t('by_author', $author) . ' — ' : '',
+ $item->date();
+ ?></div>
- <?php
- if ($lazyload) {
- echo lazyimg($item->content ());
- } else {
- echo $item->content();
- }
- ?>
+ <?php echo $item->content(); ?>
</div>
</div>
</div>
diff --git a/lib/lib_rss.php b/lib/lib_rss.php
index 7ca611b04..86c0a4ae4 100644
--- a/lib/lib_rss.php
+++ b/lib/lib_rss.php
@@ -121,10 +121,10 @@ function customSimplePie() {
'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur',
'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless')));
$simplePie->add_attributes(array(
- 'img' => array('lazyload' => ''), //http://www.w3.org/TR/resource-priorities/
- 'audio' => array('preload' => 'none'),
- 'iframe' => array('postpone' => '', 'sandbox' => 'allow-scripts allow-same-origin'),
- 'video' => array('postpone' => '', 'preload' => 'none'),
+ 'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/
+ 'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'),
+ 'iframe' => array('lazyload' => '', 'postpone' => '', 'sandbox' => 'allow-scripts allow-same-origin'),
+ 'video' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'),
));
$simplePie->set_url_replacements(array(
'a' => 'href',
@@ -183,16 +183,8 @@ function get_content_by_parsing ($url, $path) {
*/
function lazyimg($content) {
return preg_replace(
- '/<img([^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i',
- '<img$1src="' . Minz_Url::display('/themes/icons/grey.gif') . '" data-original="$2"$3>',
- $content
- );
-}
-
-function lazyIframe($content) {
- return preg_replace(
- '/<iframe([^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i',
- '<iframe$1src="about:blank" data-original="$2"$3>',
+ '/<((?:img|iframe)[^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i',
+ '<$1src="' . Minz_Url::display('/themes/icons/grey.gif') . '" data-original="$2"$3>',
$content
);
}
diff --git a/p/scripts/jquery.lazyload.min.js b/p/scripts/jquery.lazyload.min.js
deleted file mode 100644
index 8dd097dc3..000000000
--- a/p/scripts/jquery.lazyload.min.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Lazy Load - jQuery plugin for lazy loading images
- *
- * Copyright (c) 2007-2013 Mika Tuupola
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * Project home:
- * http://www.appelsiini.net/projects/lazyload
- *
- * Version: 1.9.0
- *
- */
-!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.data(j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.data(j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/iphone|ipod|ipad.*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); \ No newline at end of file
diff --git a/p/scripts/main.js b/p/scripts/main.js
index b6214e508..acb7bd527 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -421,21 +421,7 @@ function inMarkViewport(flux, box_to_follow, relative_follow) {
return (windowBot >= begin && bot >= windowBot);
}
-function init_lazyload() {
- if ($.fn.lazyload) {
- if (is_global_mode()) {
- $(".flux_content img").lazyload({
- container: $("#panel")
- });
- } else {
- $(".flux_content img").lazyload();
- }
- }
-}
-
function init_posts() {
- init_lazyload();
-
var box_to_follow = $(window),
relative_follow = false;
if (is_global_mode()) {
@@ -827,7 +813,6 @@ function load_more_posts() {
});
init_load_more(box_load_more);
- init_lazyload();
$('#load_more').removeClass('loading');
load_more = false;
@@ -841,6 +826,12 @@ function focus_search() {
function init_load_more(box) {
box_load_more = box;
+ if (!does_lazyload) {
+ $('img[postpone], audio[postpone], iframe[postpone], video[postpone]').each(function () {
+ this.removeAttribute('postpone');
+ });
+ }
+
var $next_link = $("#load_more");
if (!$next_link.length) {
// no more article to load
@@ -1093,7 +1084,7 @@ function faviconNbUnread(n) {
ctx.fillStyle = 'rgba(255, 255, 255, 127)';
ctx.fillRect(0, 8, 1 + ctx.measureText(text).width, 7);
ctx.fillStyle = '#F00';
- ctx.fillText(text, 0, 16);
+ ctx.fillText(text, 0, canvas.height);
}
link.href = canvas.toDataURL('image/png');
$('link[rel~=icon]').remove();
@@ -1104,7 +1095,7 @@ function faviconNbUnread(n) {
}
function init_all() {
- if (!(window.$ && window.url_freshrss && ((!full_lazyload) || $.fn.lazyload))) {
+ if (!(window.$ && window.url_freshrss)) {
if (window.console) {
console.log('FreshRSS waiting for JS…');
}