Project project = await Task.FromResult(db.Projects
.Include(p => p.ProjectOwner)
.Include(p => p.ChildProjects)
.ThenInclude(o => o.ProjectOwner)
.AsEnumerable().Where(p => p.Id == id)
.ToList().FirstOrDefault());
我尝试优化网站性能。我面临着三十个部分的代码对我的性能的巨大影响,我认为我所有的捆绑包的大小都比zendesk代码小。如何在不影响主线程的情况下加载它?我应该使用 <script
id="ze-snippet"
src="https://static.zdassets.com/ekr/snippet.js?key=some_zendesk_key"
/>
标签中的async
吗?或者哪种方法更适合这种情况?
答案 0 :(得分:1)
我最近遇到了这个问题,并使用仅在到达文档的特定点时才加载zendesk脚本的功能来进行此破解。我知道有点脏,但是可以用:
<script defer type="text/javascript">
(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i,el){
function visPx(){
var H = $(this).height(),
r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));
} visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
$('#trigger_div').inViewport(function(px){
if(px) {
//zopim code
}
});
答案 1 :(得分:0)
这似乎是一个困扰着许多人而没有明确解决方案的问题。
我设法通过添加此配置来减少阻止时间。
window.zESettings = {
webWidget: {
chat: {
connectOnPageLoad: false
}
}
};
ref https://developer.zendesk.com/embeddables/docs/widget/settings#connectonpageload
ps 我对zendesk服务台“ domain.zendesk.com”进行了性能测试,结果甚至更糟
答案 2 :(得分:0)
从这篇文章开始https://www.newmediacampaigns.com/blog/maintaining-great-site-performanc-using-zendesk-web-widget,我已经实施了一个解决方案,该解决方案将加载时间显着减少了至少 3 秒(在 Google Lighthouse 中)。
我在 HTML 中创建了一个假按钮,该按钮将加载 Zendesk 脚本并在单击时打开小部件。它还将加载一个 localStorage 项目,以防止在后续页面加载时发生这种情况。
代码在很大程度上依赖于小部件当前的实现方式(例如,它期望在页面上出现一个 #launcher
和一个 #webWidget
元素),因此它可能会在原始代码出现时立即中断更改,但至少在他们修复之前我们会改善加载时间。
这是代码中最重要的部分:
<button class="zendesk-button">
<span class="left-icon">
<!-- here you insert the icon -->
</span>
<span class="text">Chat</span>
</button>
// select the button
const zendeskButton = document.querySelector('.zendesk-button');
// add the script to the page
const loadZendeskScript = () => {
const zenDeskScript = document.createElement("script");
zenDeskScript.id = "ze-snippet";
zenDeskScript.src = "https://static.zdassets.com/ekr/snippet.js?key=HERE_YOU_INSERT_YOUR_KEY";
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] || document.getElementsByTagName('script')[0].parentNode).insertBefore(zenDeskScript, null);
};
// a poller that waits for a condition and executes a callback
const poller = (comparison, callback, timerStep = 250, maxTime = 5000) => {
// why setTimeout instead of setInterval
// https://stackoverflow.com/questions/8682622/using-setinterval-to-do-simplistic-continuous-polling
let currTime = 0;
const checkCondition = () => {
// `comparison` is a function so the condition is always up-to-date
if (comparison() === true) {
callback();
} else if (currTime <= maxTime) {
currTime += timerStep;
setTimeout(checkCondition, timerStep);
}
};
checkCondition(); // calling the function
};
// load the script and execute a callback if provided
const loadZendeskChat = callback => {
loadZendeskScript();
if (callback) {
callback();
}
};
// this function opens the chat
const openZendeskChat = () => {
poller(
() => {
// check that zendesk-related functions are available
return typeof zE !== 'undefined';
},
() => {
// open the widget
zE('webWidget', 'open');
poller(
() => {
// check that the elements exist and that the opacity is already set to "1"
const launcher = document.querySelector('#launcher');
const webWidget = document.querySelector('#webWidget');
return launcher !== null && webWidget !== null && webWidget.style.opacity === '1';
},
() => {
// hide the fake button
zendeskButton.style.opacity = '0';
// save in localStorage
localStorage.setItem('zd_hasOpened', 'true');
}
);
}
);
};
// zendesk management
if (localStorage.getItem('zd_hasOpened')) {
// load the zendesk widget if we find that it was opened
loadZendeskChat();
} else {
// show the fake button if it's the first time it shows
zendeskButton.style.opacity = '1';
}
// This will run when the .zendesk-button element is clicked
zendeskButton.addEventListener('click', () => {
// add a 'Loading' text to the button, as the widget will take some time to load (between 1 and 2 seconds on my laptop)
zendeskButton.querySelector('.text').innerHTML = 'Loading';
// load the zendesk widget
// open the widget and hide the fake button
loadZendeskChat(openZendeskChat);
});
关于样式,我几乎复制了原始小部件中的样式,将 em 转换为像素,但我想强调的部分是焦点样式,因为在我看来它有助于告诉用户正在发生某些事情.
.zendesk-button:focus {
outline: none;
box-shadow: inset 0 0 0 0.21429rem rgb(255 255 255 / 40%) !important;
}