Skip to content

Commit

Permalink
Closes #3843 Add Lazyrender Content feature (#6916)
Browse files Browse the repository at this point in the history
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
Co-authored-by: Michael Lee <38788055+jeawhanlee@users.noreply.github.com>
Co-authored-by: Michael Lee <michaelleemichaellee408@gmail.com>
Co-authored-by: Gael Robin <robin.gael@gmail.com>
Co-authored-by: Opeyemi Ibrahim <opeyemi.khadri@gmail.com>
Co-authored-by: Mathieu Lamiot <mathieu.lamiot@free.fr>
Co-authored-by: Rémy Perona <remy@wp-media.me>
Co-authored-by: Rémy Perona <remperona@gmail.com>
Co-authored-by: Mai <76941962+Mai-Saad@users.noreply.github.com>
  • Loading branch information
10 people authored Sep 16, 2024
1 parent 84982f8 commit 4b9193b
Show file tree
Hide file tree
Showing 152 changed files with 9,657 additions and 3,275 deletions.
4 changes: 3 additions & 1 deletion assets/css/wpr-admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,9 @@ div.wpr-upgrade-websites {
font-size: 0.6875rem;
line-height: 1.8181818182;
}
.wpr-button--no-min-width {
min-width: auto !important;
}
.wpr-button--icon {
min-width: 160px;
padding-left: 8px;
Expand Down Expand Up @@ -2015,7 +2018,6 @@ div.wpr-upgrade-websites {
.wpr-radio-buttons {
padding-left: 24px;
}

.wpr-fieldWarning.wpr-radio-warning {
margin-left: -24px;
padding-left: 30px;
Expand Down
2 changes: 1 addition & 1 deletion assets/css/wpr-admin.min.css

Large diffs are not rendered by default.

153 changes: 143 additions & 10 deletions assets/js/wpr-beacon.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
(() => {
// src/Utils.js
var BeaconUtils = class {
static getScreenWidth() {
return window.innerWidth || document.documentElement.clientWidth;
}
static getScreenHeight() {
return window.innerHeight || document.documentElement.clientHeight;
}
static isNotValidScreensize(is_mobile, threshold) {
const screenWidth = window.innerWidth || document.documentElement.clientWidth;
const screenHeight = window.innerHeight || document.documentElement.clientHeight;
const screenWidth = this.getScreenWidth();
const screenHeight = this.getScreenHeight();
const isNotValidForMobile = is_mobile && (screenWidth > threshold.width || screenHeight > threshold.height);
const isNotValidForDesktop = !is_mobile && (screenWidth < threshold.width || screenHeight < threshold.height);
return isNotValidForMobile || isNotValidForDesktop;
Expand Down Expand Up @@ -190,6 +196,119 @@
};
var BeaconLcp_default = BeaconLcp;

// src/BeaconLrc.js
var BeaconLrc = class {
constructor(config, logger) {
this.config = config;
this.logger = logger;
this.lazyRenderElements = [];
}
async run() {
try {
const elementsInView = this._getLazyRenderElements();
if (elementsInView) {
this._processElements(elementsInView);
}
} catch (err) {
this.errorCode = "script_error";
this.logger.logMessage("Script Error: " + err);
}
}
_getLazyRenderElements() {
const elements = document.querySelectorAll("[data-rocket-location-hash]");
if (elements.length <= 0) {
return [];
}
const validElements = Array.from(elements).filter((element) => !this._skipElement(element));
return validElements.map((element) => ({
element,
depth: this._getElementDepth(element),
distance: this._getElementDistance(element),
hash: this._getLocationHash(element)
}));
}
_getElementDepth(element) {
let depth = 0;
let parent = element.parentElement;
while (parent) {
depth++;
parent = parent.parentElement;
}
return depth;
}
_getElementDistance(element) {
const rect = element.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
return Math.max(0, rect.top + scrollTop - Utils_default.getScreenHeight());
}
_skipElement(element) {
const skipStrings = this.config.skipStrings || ["memex"];
if (!element || !element.id) return false;
return skipStrings.some((str) => element.id.toLowerCase().includes(str.toLowerCase()));
}
_shouldSkipElement(element, exclusions) {
if (!element) return false;
for (let i = 0; i < exclusions.length; i++) {
const [attribute, pattern] = exclusions[i];
const attributeValue = element.getAttribute(attribute);
if (attributeValue && new RegExp(pattern, "i").test(attributeValue)) {
return true;
}
}
return false;
}
_processElements(elements) {
elements.forEach(({ element, depth, distance, hash }) => {
if (this._shouldSkipElement(element, this.config.exclusions || [])) {
return;
}
if ("No hash detected" === hash) {
return;
}
const can_push_hash = element.parentElement && this._getElementDistance(element.parentElement) < this.config.lrc_threshold && distance >= this.config.lrc_threshold;
const color = can_push_hash ? "green" : distance === 0 ? "red" : "";
this.logger.logColoredMessage(`${" ".repeat(depth)}${element.tagName} (Depth: ${depth}, Distance from viewport bottom: ${distance}px)`, color);
this.logger.logColoredMessage(`${" ".repeat(depth)}Location hash: ${hash}`, color);
this.logger.logColoredMessage(`${" ".repeat(depth)}Dimensions Client Height: ${element.clientHeight}`, color);
if (can_push_hash) {
this.lazyRenderElements.push(hash);
this.logger.logMessage(`Element pushed with hash: ${hash}`);
}
});
}
_getXPath(element) {
if (element && element.id !== "") {
return `//*[@id="${element.id}"]`;
}
return this._getElementXPath(element);
}
_getElementXPath(element) {
if (element === document.body) {
return "/html/body";
}
const position = this._getElementPosition(element);
return `${this._getElementXPath(element.parentNode)}/${element.nodeName.toLowerCase()}[${position}]`;
}
_getElementPosition(element) {
let pos = 1;
let sibling = element.previousElementSibling;
while (sibling) {
if (sibling.nodeName === element.nodeName) {
pos++;
}
sibling = sibling.previousElementSibling;
}
return pos;
}
_getLocationHash(element) {
return element.hasAttribute("data-rocket-location-hash") ? element.getAttribute("data-rocket-location-hash") : "No hash detected";
}
getResults() {
return this.lazyRenderElements;
}
};
var BeaconLrc_default = BeaconLrc;

// src/Logger.js
var Logger = class {
constructor(enabled) {
Expand All @@ -201,6 +320,12 @@
}
console.log(msg);
}
logColoredMessage(msg, color = "green") {
if (!this.enabled) {
return;
}
console.log(`%c${msg}`, `color: ${color};`);
}
};
var Logger_default = Logger;

Expand All @@ -209,6 +334,7 @@
constructor(config) {
this.config = config;
this.lcpBeacon = null;
this.lrcBeacon = null;
this.infiniteLoopId = null;
this.errorCode = "";
this.logger = new Logger_default(this.config.debug);
Expand All @@ -223,16 +349,21 @@
this._handleInfiniteLoop();
}, 1e4);
const isGeneratedBefore = await this._getGeneratedBefore();
let shouldSaveResultsIntoDB = false;
const shouldGenerateLcp = this.config.status.atf && isGeneratedBefore === false;
const shouldGenerateLcp = this.config.status.atf && (isGeneratedBefore === false || isGeneratedBefore.lcp === false);
const shouldGeneratelrc = this.config.status.lrc && (isGeneratedBefore === false || isGeneratedBefore.lrc === false);
if (shouldGenerateLcp) {
this.lcpBeacon = new BeaconLcp_default(this.config, this.logger);
await this.lcpBeacon.run();
shouldSaveResultsIntoDB = true;
} else {
this.logger.logMessage("Not running BeaconLcp because data is already available");
this.logger.logMessage("Not running BeaconLcp because data is already available or feature is disabled");
}
if (shouldGeneratelrc) {
this.lrcBeacon = new BeaconLrc_default(this.config, this.logger);
await this.lrcBeacon.run();
} else {
this.logger.logMessage("Not running BeaconLrc because data is already available or feature is disabled");
}
if (shouldSaveResultsIntoDB) {
if (shouldGenerateLcp || shouldGeneratelrc) {
this._saveFinalResultIntoDB();
} else {
this.logger.logMessage("Not saving results into DB as no beacon features ran.");
Expand Down Expand Up @@ -264,11 +395,12 @@
credentials: "same-origin",
body: data_check
}).then((data) => data.json());
return beacon_data_response.success;
return beacon_data_response.data;
}
_saveFinalResultIntoDB() {
const results = {
lcp: this.lcpBeacon ? this.lcpBeacon.getResults() : null
lcp: this.lcpBeacon ? this.lcpBeacon.getResults() : null,
lrc: this.lrcBeacon ? this.lrcBeacon.getResults() : null
};
const data = new FormData();
data.append("action", "rocket_beacon");
Expand All @@ -285,7 +417,7 @@
"wpr-saas-no-intercept": true
}
}).then((response) => response.json()).then((data2) => {
this.logger.logMessage(data2);
this.logger.logMessage(data2.data.lcp);
}).catch((error) => {
this.logger.logMessage(error);
}).finally(() => {
Expand Down Expand Up @@ -331,4 +463,5 @@
}, rocket_beacon_data.delay);
});
})(window.rocket_beacon_data);
var BeaconEntryPoint_default = BeaconManager_default;
})();
Loading

0 comments on commit 4b9193b

Please sign in to comment.