Проверить Тесты UX:
- Android – 6 секунд
https://imgur.com/a/FlC0Apn
< li>Windows — 6 секунд
https://imgur.com/TivxVVB - Mac — 1 минута + (скорость в 1,5 раза из-за ограничений imgur)
https: //imgur.com/gUUua4i - iPhone — 1 минута + (скорость в 2 раза из-за ограничений imgur)
https://imgur.com/uULsPae
Все наши веб-компоненты разработаны так же, как и этот:
Код: Выделить всё
class Topic extends HTMLElement{
constructor(){
super();
this.attachShadow({ mode: 'open' });
this.classList.add('skeleton');
}
render(){
this.shadowRoot.innerHTML = `
@import url('./asset/chunk/style.min.css');
@import url('./asset/~external/bootstrap-icons/font/bootstrap-icons.min.css');
:host([skeleton]){ height: ${this.getAttribute('height') ?? 'var(--height-input)'}; }
:host([skeleton]){ display: none; }
:host{
display: flex;
width: ${this.getAttribute('width') ?? '100%'};
height: auto;
border-radius: 5px;
}
:host([disable]) .topicHeader{
cursor: not-allowed;
}
:host([disable]) .topicBase{
background-color: var(--color-disable-0);
color: var(--color-disable-1);
}
:host([disable]) .topicHeader{
background-color: unset;
color: unset;
}
:host([disable]) #startIcon{ color: var(--color-disable-1); }
:host([disable]) .headerText{ --text-color: var(--color-disable-1); }
:host([disable]) #endIcon{ color: var(--color-disable-1); }
.topicBase{
display: flex;
border-radius: 5px;
width: ${this.getAttribute('width') ?? '100%'};
min-height: ${this.getAttribute('height') ?? 'var(--height-input)'};
}
.topicBase.displayed .drawIn{
padding: ${this.hasAttribute('void') ? '10px 0 0 0' : '15px 5px 5px 5px'};
}
.topicBase.displayed{ box-shadow: var(--box-shadow-0); }
.topicBase.displayed:hover{ box-shadow: var(--box-shadow-1); }
#startIcon{
font-size: ${this.getAttribute('startIconSize') ?? '24px'};
color: var(--color-contrast);
}
#endIcon{
font-size: ${this.getAttribute('endIconSize') ?? '20px'};
color: var(--color-contrast);
}
.topicHeader{
position: absolute;
top: 0;
width: fit-content;
cursor: pointer;
border-radius: 5px;
background: ${this.hasAttribute('color') ? 'var(--color-1)' : 'var(--color-soft-5)'};
box-shadow: var(--box-shadow-0);
height: ${this.getAttribute('height') ?? 'var(--height-input)'};
width: 100%;
}
.topicHeader:hover{
background: ${this.hasAttribute('color') ? 'var(--color-3)' : 'var(--color-soft-10)'};
box-shadow: var(--box-shadow-1);
}
.topicHeader.color{ background: var(--color-1); }
.topicHeader.color:hover{ background: var(--color-3); }
.drawIn{
position: relative;
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.1s linear, transform 0.1s linear;
transform: translateY(14px);
border-radius: 5px;
margin-top: 24px;
/* z-index: 2; */
width: 100%;
}
.drawIn.displayed{ grid-template-rows: 1fr; transform: translateY(0); }
.drawIn.shorten{ margin-top: 0; z-index: 0;}
.drawInContent{
overflow: hidden;
}
.drawInContent.displayed{ overflow: visible; }
.drawIn.displayed .contentWidth, .drawInContent.displayed .contentWidth{ visibility: visible; }
.contentWidth{
visibility: invisible;
width: 100%;
max-width: ${this.getAttribute('max-width-inner') ?? '100%'};
}
.loadingIcon{
position:absolute;
min-width: 100%;
min-height: 100%;
overflow:hidden;
inset: 0;
}
[i][/i]
${this.getAttribute('placeholder') ?? ''}
[i][/i]
`;
// Get component inner elements
this.topic = this.shadowRoot.querySelector('.topicBase');
this.header = this.shadowRoot.querySelector('.topicHeader');
this.drawIn = this.shadowRoot.querySelector('.drawIn');
this.startHeader = this.shadowRoot.querySelector('.startHeader');
this.startIcon = this.shadowRoot.querySelector('#startIcon');
this.endIcon = this.shadowRoot.querySelector('#endIcon');
this.drawInContent = this.shadowRoot.querySelector('.drawInContent');
this.headerText = this.shadowRoot.querySelector('s-span');
this.headerSpace = this.shadowRoot.querySelector('.headerSpace');
this.msg = this.shadowRoot.querySelector('.msg');
this.loading = this.shadowRoot.querySelector('.loadingIcon');
this.contentWidth = this.shadowRoot.querySelector('.contentWidth');
// Set component inner elements
if(this.hasAttribute('displayed')){ this.show(); }
if(this.hasAttribute('shorten')){ this.drawIn.classList.add('shorten'); }
// s-topic events
this.header.addEventListener('click', e =>{
if(this.hasAttribute('disable')){ return; }
if(this.drawIn.classList.contains('displayed')){ this.hide(); }
else{ this.show(); }
});
}
draw(){
this.classList.remove('skeleton');
this.dispatchEvent(new Event('render'));
}
connectedCallback(){
this.render();
setTimeout(e =>{ requestAnimationFrame(e =>{ this.draw(); }); }, 0);
}
disable(disableMessage = 0){
this.setAttribute('disable', '');
if(disableMessage){
this.onclick = e =>{
if(this.hasAttribute('disable')){
msgBox({ title: 'Desabilitado', inner: disableMessage });
}
}
}
}
enable(){ this.removeAttribute('disable'); }
show(){
if(this.hasAttribute('disable')){ return; }
if(this.hasAttribute('shorten')){ this.header.style.width = 'fit-content'; }
this.drawIn.style.willChange = 'grid-template-rows, transform';
this.topic.style.willChange = 'box-shadow';
requestAnimationFrame(e =>{
this.drawIn.classList.add('displayed');
this.endIcon.classList = this.swapTopicIcon(this.endIcon.classList.value, 0);
setTimeout(e => {
this.drawInContent.classList.add('displayed');
this.drawIn.style.willChange = 'auto';
this.topic.style.willChange = 'auto';
}, 100);
this.topic.classList.add('displayed');
});
// Add event on show
this.dispatchEvent(new Event('show'));
}
hide(){
this.drawIn.style.willChange = 'grid-template-rows, transform';
this.topic.style.willChange = 'box-shadow';
requestAnimationFrame(e =>{
this.drawIn.classList.remove('displayed');
this.endIcon.classList = this.swapTopicIcon(this.endIcon.classList.value, 1);
this.drawInContent.classList.remove('displayed');
setTimeout(e => {
this.drawInContent.classList.remove('displayed');
this.drawIn.style.willChange = 'auto';
this.topic.style.willChange = 'auto';
}, 100); // just in case call show and hide in less the 100ms
this.topic.classList.remove('displayed');
});
}
color(color){
if(!color){ color = ''; } // black
this.endIcon.style.color = `${color}`;
this.headerText.style.color = `${color}`;
}
setHeader(header){ this.headerText.innerHTML = header; }
showLoading(){
this.headerText.innerHTML = '';
this.endIcon.classList = 'bi-arrow-repeat';
}
showLoading(xsize = 35, ysize = 35){
this.loading.innerHTML = ''
this.msg.style.opacity = '0';
}
hideLoading(){
this.loading.innerHTML = '';
this.msg.style.opacity = '1';
}
swapTopicIcon = (actualIcon, origin) =>{
if(this.hasAttribute('shorten') && origin === 0){
this.header.classList.add('color');
this.startHeader.style.display = 'none';
this.header.style.width = 'fit-content';
return 'bi-caret-up-fill';
}
else if(this.hasAttribute('shorten') && origin === 1){
this.header.classList.remove('color');
this.startHeader.style.display = 'flex';
this.header.style.width = '100%';
return 'bi-caret-down-fill';
}
if(actualIcon === 'bi-caret-down-fill' && origin === 0){ return 'bi-caret-up-fill'; }
else if(actualIcon === 'bi-caret-up-fill' && origin === 1) { return 'bi-caret-down-fill'; }
if(actualIcon === 'bi-arrow-down-right-square' && origin === 0){ return 'bi-arrow-up-square'; }
else if(actualIcon === 'bi-arrow-up-square' && origin === 1) { return 'bi-arrow-down-right-square'; }
else{ return actualIcon; }
}
set(configObj = 0){
if(configObj.hasOwnProperty('icon')){ this.startIcon.className = configObj.icon; }
if(configObj.hasOwnProperty('color')){
let boxShadow;
if(configObj.color === 'red'){
configObj.color = 'var(--color-red)';
boxShadow = 'var(--box-shadow-red)';
}
this.startIcon.style.color = `${configObj.color}`;
this.endIcon.style.color = `${configObj.color}`;
this.headerText.style = `--text-color: ${configObj.color}`;
// this.topic.style.boxShadow = boxShadow;
this.header.style.boxShadow = boxShadow;
}
else{
// Back to original colors
this.startIcon.style.color = 'var(--color-contrast)';
this.endIcon.style.color = 'var(--color-contrast)';
this.headerText.style = '--text-color: unset';
this.header.style.boxShadow = 'var(--box-shadow-0)';
}
}
}
customElements.define('s-topic', Topic);
Код: Выделить всё
Код: Выделить всё
draw(){
this.classList.remove('skeleton');
this.dispatchEvent(new Event('render'));
}
connectedCallback(){
this.render();
setTimeout(e =>{ requestAnimationFrame(e =>{ this.draw(); }); }, 0);
}
Еще одна вещь, которая снижает производительность рендеринга, — это загрузка нашего JS Chunks по требованию и их интеграция путем вызова этого шаблона
Код: Выделить всё
async function initConfigPOP(){
configPopupHTML = `
[i][/i]Sair
`.trim();
// Create a temporary div to hold all page HTML
let tempDIV = document.createElement('div');
tempDIV.style.display = 'none';
tempDIV.insertAdjacentHTML('beforeend', configPopupHTML);
// Append all Chunks into the fragment
insertDeviceConfigsConfigHTML(tempDIV);
insertUserConfigsConfigHTML(tempDIV);
Код: Выделить всё
function insertDeviceConfigsConfigHTML(tempDIV){
let deviceConfigsHTML = `
[i][/i]
Notificações
Modo Noturno
Ocultação das Barras
`.trim();
let deviceConfigsConfigTPC = tempDIV.querySelector('#deviceConfigsConfigTPC');
deviceConfigsConfigTPC.insertAdjacentHTML('beforeend', deviceConfigsHTML);
}
async function runDeviceConfigsConfig(){
// Get Elements
window.deviceInfoConfigDIV = document.getElementById('deviceInfoConfigDIV');
window.deviceInfoConfigIcon = document.getElementById('deviceInfoConfigIcon');
window.deviceInfoTypeConfigSPN = document.getElementById('deviceInfoTypeConfigSPN');
[...]
Код: Выделить всё
function insertUserInfoConfigHTML(tempDIV){
let userInfoConfigHTML = `
Mulher
Homem
Outro
Atualizar Informações
`.trim();
let userInfoConfigTPC = tempDIV.querySelector('#userInfoConfigTPC');
userInfoConfigTPC.insertAdjacentHTML('beforeend', userInfoConfigHTML);
}
async function runUserInfoConfig(){
console.log('Loading User Info Config');
userInfoConfigTPC.showLoading();
// Get elements
window.nameUserInfoConfigINP = document.getElementById('nameUserInfoConfigINP');
window.emailUserInfoConfigINP = document.getElementById('emailUserInfoConfigINP');
window.birthUserInfoConfigINP = document.getElementById('birthUserInfoConfigINP');
[...]
Код: Выделить всё
// Create a fragment to hold all HTML before appending to DOM
let fragment = document.createDocumentFragment();
// Add fragment to DOM
while(tempDIV.firstChild){ fragment.appendChild(tempDIV.firstChild); } // Move all nodes from the temporary div to the fragment
popupPG.appendChild(fragment);
Я ошибаюсь здесь что-то плохое, или я просто нарушаю текущее ограничение движка WebKit? Я действительно думаю, что это вторая возможность, поскольку я потратил 6 месяцев, безуспешно пытаясь решить эту проблему, в то время как движок v8 дает мне опыт PWA, неотличимый от опыта Native.
Подробнее здесь: https://stackoverflow.com/questions/787 ... ari-webkit
Мобильная версия