Skip to content

Commit 1011343

Browse files
committed
博客全面优化:性能提升、UI美化、互动功能增强
1 parent b3c84d3 commit 1011343

14 files changed

+1089
-60
lines changed

_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ netease_comment: false
7272
# ba_track_id: [your track id]
7373

7474
# Google Analytics
75-
ga_track_id: # 如果需要Google分析,请填入你的GA追踪ID
75+
ga_track_id: G-XXXXXXXXXX # 请替换为实际的GA4追踪ID
7676
ga_domain: jasonrobertdestiny.github.io
7777

7878
# Sidebar settings

_includes/footer.html

Lines changed: 179 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,176 @@
1717
</div>
1818
</footer>
1919

20-
<!-- jQuery -->
20+
<!-- Critical JavaScript - Load Immediately -->
2121
<script src="{{ "/js/jquery.min.js " | prepend: site.baseurl }}"></script>
2222

23-
<!-- Bootstrap Core JavaScript -->
24-
<!-- Currently, only navbar scroll-down effect at desktop still depends on this -->
25-
<script src="{{ "/js/bootstrap.min.js " | prepend: site.baseurl }}"></script>
26-
27-
<!-- Custom Theme JavaScript -->
28-
<script src="{{ "/js/jason-blog.min.js " | prepend: site.baseurl }}"></script>
29-
30-
<!-- Simple Jekyll Search -->
31-
<script src="{{ "/js/simple-jekyll-search.min.js" | prepend: site.baseurl }}"></script>
23+
<!-- Non-Critical JavaScript - Load Asynchronously -->
24+
<script>
25+
// Async load non-critical scripts
26+
function loadScript(src, callback) {
27+
var script = document.createElement('script');
28+
script.src = src;
29+
script.async = true;
30+
if (callback) script.onload = callback;
31+
document.head.appendChild(script);
32+
}
33+
34+
// Load scripts after page load
35+
window.addEventListener('load', function() {
36+
loadScript('{{ "/js/bootstrap.min.js " | prepend: site.baseurl }}');
37+
loadScript('{{ "/js/jason-blog.min.js " | prepend: site.baseurl }}');
38+
loadScript('{{ "/js/simple-jekyll-search.min.js" | prepend: site.baseurl }}');
39+
40+
// Initialize all features when page loads
41+
initLazyLoading();
42+
initReadingProgress();
43+
initBackToTop();
44+
initSocialShare();
45+
});
46+
47+
// Reading Progress Bar
48+
function initReadingProgress() {
49+
const progressBar = document.getElementById('reading-progress');
50+
if (!progressBar) return;
51+
52+
function updateProgress() {
53+
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
54+
const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
55+
const progress = (scrollTop / scrollHeight) * 100;
56+
progressBar.style.width = Math.min(progress, 100) + '%';
57+
}
58+
59+
window.addEventListener('scroll', updateProgress);
60+
window.addEventListener('resize', updateProgress);
61+
updateProgress(); // Initial call
62+
}
63+
64+
// Back to Top functionality
65+
function initBackToTop() {
66+
const backToTopBtn = document.getElementById('back-to-top');
67+
if (!backToTopBtn) return;
68+
69+
window.addEventListener('scroll', function() {
70+
if (window.pageYOffset > 300) {
71+
backToTopBtn.classList.add('show');
72+
} else {
73+
backToTopBtn.classList.remove('show');
74+
}
75+
});
76+
}
77+
78+
function scrollToTop() {
79+
window.scrollTo({
80+
top: 0,
81+
behavior: 'smooth'
82+
});
83+
}
84+
85+
// Floating Menu functionality
86+
function toggleFloatingMenu() {
87+
const menu = document.getElementById('floating-menu');
88+
menu.classList.toggle('active');
89+
}
90+
91+
function openSearch() {
92+
const searchPage = document.querySelector('.search-page');
93+
if (searchPage) {
94+
searchPage.classList.add('show');
95+
const searchInput = document.getElementById('search-input');
96+
if (searchInput) {
97+
setTimeout(() => searchInput.focus(), 300);
98+
}
99+
}
100+
toggleFloatingMenu();
101+
}
102+
103+
function toggleDarkMode() {
104+
document.body.classList.toggle('dark-mode');
105+
localStorage.setItem('darkMode', document.body.classList.contains('dark-mode'));
106+
toggleFloatingMenu();
107+
}
108+
109+
function printPage() {
110+
window.print();
111+
toggleFloatingMenu();
112+
}
113+
114+
// Social Share functionality
115+
function initSocialShare() {
116+
// Close search when clicking outside
117+
document.addEventListener('click', function(e) {
118+
const searchPage = document.querySelector('.search-page');
119+
const floatingMenu = document.getElementById('floating-menu');
120+
121+
if (searchPage && searchPage.classList.contains('show') &&
122+
!e.target.closest('.search-main') && !e.target.closest('.search-icon-close')) {
123+
searchPage.classList.remove('show');
124+
}
125+
126+
if (floatingMenu && floatingMenu.classList.contains('active') &&
127+
!e.target.closest('.floating-menu')) {
128+
floatingMenu.classList.remove('active');
129+
}
130+
});
131+
132+
// Close search with close button
133+
const closeBtn = document.querySelector('.search-icon-close');
134+
if (closeBtn) {
135+
closeBtn.addEventListener('click', function() {
136+
document.querySelector('.search-page').classList.remove('show');
137+
});
138+
}
139+
}
140+
141+
function shareToTwitter() {
142+
const url = encodeURIComponent(window.location.href);
143+
const text = encodeURIComponent(document.title);
144+
window.open(`https://twitter.com/intent/tweet?url=${url}&text=${text}`, '_blank', 'width=600,height=400');
145+
}
146+
147+
function shareToFacebook() {
148+
const url = encodeURIComponent(window.location.href);
149+
window.open(`https://www.facebook.com/sharer/sharer.php?u=${url}`, '_blank', 'width=600,height=400');
150+
}
151+
152+
function shareToLinkedIn() {
153+
const url = encodeURIComponent(window.location.href);
154+
const title = encodeURIComponent(document.title);
155+
window.open(`https://www.linkedin.com/sharing/share-offsite/?url=${url}&title=${title}`, '_blank', 'width=600,height=400');
156+
}
157+
158+
function shareToWechat() {
159+
// Copy URL to clipboard for WeChat sharing
160+
navigator.clipboard.writeText(window.location.href).then(function() {
161+
alert('链接已复制到剪贴板,请在微信中粘贴分享!');
162+
}).catch(function() {
163+
prompt('请复制以下链接在微信中分享:', window.location.href);
164+
});
165+
}
166+
167+
function shareToWeibo() {
168+
const url = encodeURIComponent(window.location.href);
169+
const title = encodeURIComponent(document.title);
170+
window.open(`https://service.weibo.com/share/share.php?url=${url}&title=${title}`, '_blank', 'width=600,height=400');
171+
}
172+
173+
// Lazy loading implementation
174+
function initLazyLoading() {
175+
const images = document.querySelectorAll('img[data-src]');
176+
const imageObserver = new IntersectionObserver((entries, observer) => {
177+
entries.forEach(entry => {
178+
if (entry.isIntersecting) {
179+
const img = entry.target;
180+
img.src = img.dataset.src;
181+
img.classList.remove('lazy');
182+
imageObserver.unobserve(img);
183+
}
184+
});
185+
});
186+
187+
images.forEach(img => imageObserver.observe(img));
188+
}
189+
</script>
32190

33191
<!-- Service Worker -->
34192
{% if site.service-worker %}
@@ -112,23 +270,19 @@
112270
</script>
113271

114272

115-
<!-- Google Analytics -->
273+
<!-- Google Analytics (GA4) -->
116274
{% if site.ga_track_id %}
275+
<!-- Google tag (gtag.js) -->
276+
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.ga_track_id }}"></script>
117277
<script>
118-
// dynamic User by Jason
119-
var _gaId = '{{ site.ga_track_id }}';
120-
var _gaDomain = '{{ site.ga_domain }}';
121-
122-
// Originial
123-
(function (i, s, o, g, r, a, m) {
124-
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
125-
(i[r].q = i[r].q || []).push(arguments)
126-
}, i[r].l = 1 * new Date(); a = s.createElement(o),
127-
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
128-
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
129-
130-
ga('create', _gaId, _gaDomain);
131-
ga('send', 'pageview');
278+
window.dataLayer = window.dataLayer || [];
279+
function gtag(){dataLayer.push(arguments);}
280+
gtag('js', new Date());
281+
282+
gtag('config', '{{ site.ga_track_id }}', {
283+
'page_title': '{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}',
284+
'page_location': '{{ site.url }}{{ page.url }}'
285+
});
132286
</script>
133287
{% endif %}
134288

_includes/head.html

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,18 @@
33
<meta http-equiv="X-UA-Compatible" content="IE=edge">
44
<meta name="google-site-verification" content="iog9xrtHaMQ4pyqmT3spIMoVP37df47GEKtiIclzqL8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6-
<meta name="description" content="{{ site.description }}">
7-
<meta name="keywords" content="{{ site.keyword }}">
6+
<meta name="description" content="{% if page.description %}{{ page.description }}{% else %}{{ site.description }}{% endif %}">
7+
<meta name="keywords" content="{% if page.tags %}{% for tag in page.tags %}{{ tag }}{% unless forloop.last %}, {% endunless %}{% endfor %}{% else %}{{ site.keyword }}{% endif %}">
8+
<meta name="author" content="{% if page.author %}{{ page.author }}{% else %}{{ site.title }}{% endif %}">
9+
<meta name="robots" content="index, follow">
10+
<meta name="language" content="zh-CN">
811
<meta name="theme-color" content="{{ site.chrome-tab-theme-color }}">
12+
13+
<!-- Performance Optimization -->
14+
<link rel="preconnect" href="https://fonts.googleapis.com">
15+
<link rel="preconnect" href="https://www.googletagmanager.com">
16+
<link rel="dns-prefetch" href="//cdn.jsdelivr.net">
17+
<link rel="dns-prefetch" href="//cdnjs.cloudflare.com">
918

1019
<!-- Open Graph -->
1120
<meta property="og:title"
@@ -26,9 +35,16 @@
2635
{% else %}
2736
<meta property="og:type" content="website">
2837
<meta property="og:description"
29-
content="{% if page.description %}{{ page.description }}{% else %}{{ site.description }}{% endif %}">
38+
content="{% if page.description %}{{ page.description }}{% elsif page.excerpt %}{{ page.excerpt | strip_html | truncate:160 }}{% else %}{{ site.description }}{% endif %}">
3039
{% endcase %}
3140
<meta property="og:image" content="{{ site.url }}{{ site.sidebar-avatar }}">
41+
<meta property="og:site_name" content="{{ site.title }}">
42+
43+
<!-- Twitter Card -->
44+
<meta name="twitter:card" content="summary_large_image">
45+
<meta name="twitter:title" content="{% if page.title %}{{ page.title }} - {{ site.title }}{% else %}{{ site.title }}{% endif %}">
46+
<meta name="twitter:description" content="{% if page.description %}{{ page.description }}{% elsif page.excerpt %}{{ page.excerpt | strip_html | truncate:160 }}{% else %}{{ site.description }}{% endif %}">
47+
<meta name="twitter:image" content="{{ site.url }}{{ site.sidebar-avatar }}">
3248
<meta property="og:url" content="{{ site.url }}{{ page.url }}">
3349
<meta property="og:site_name" content="{{ site.SEOTitle }}">
3450

@@ -43,11 +59,20 @@
4359
<!-- Canonical URL -->
4460
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
4561

46-
<!-- Bootstrap Core CSS -->
47-
<link rel="stylesheet" href="{{ " /css/bootstrap.min.css" | prepend: site.baseurl }}">
48-
49-
<!-- Custom CSS -->
50-
<link rel="stylesheet" href="{{ "/css/jason-blog.min.css" | prepend: site.baseurl }}">
62+
<!-- Critical CSS Inline -->
63+
<style>
64+
body{background:linear-gradient(135deg,#f8fafc 0%,#e2e8f0 100%);min-height:100vh;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}
65+
.navbar-custom{background:#fff;border:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}
66+
.intro-header{background-attachment:scroll;background-position:center center;background-repeat:no-repeat;background-size:cover}
67+
.post-preview{margin-bottom:30px;padding:20px;background:#fff;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,.1)}
68+
</style>
69+
70+
<!-- Preload Critical Resources -->
71+
<link rel="preload" href="{{ "/css/bootstrap.min.css" | prepend: site.baseurl }}" as="style" onload="this.onload=null;this.rel='stylesheet'">
72+
<noscript><link rel="stylesheet" href="{{ "/css/bootstrap.min.css" | prepend: site.baseurl }}"></noscript>
73+
74+
<link rel="preload" href="{{ "/css/jason-blog.min.css" | prepend: site.baseurl }}" as="style" onload="this.onload=null;this.rel='stylesheet'">
75+
<noscript><link rel="stylesheet" href="{{ "/css/jason-blog.min.css" | prepend: site.baseurl }}"></noscript>
5176

5277
<!-- Custom Fonts -->
5378
<!-- <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> -->

_layouts/default.html

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,46 @@
1-
<!DOCTYPE html>
2-
<html lang="en">
3-
4-
{% include head.html %}
5-
6-
<!-- hack iOS CSS :active style -->
7-
<body ontouchstart="">
8-
9-
{% include nav.html %}
10-
{% include search.html %}
11-
12-
{{ content }}
13-
14-
{% include footer.html %}
15-
16-
17-
<!-- Image to hack wechat -->
18-
<img src="/img/icon_wechat.png" width="0" height="0" />
19-
<!-- Migrate from head to bottom, no longer block render and still work -->
20-
21-
</body>
22-
23-
</html>
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
{% include head.html %}
5+
6+
<!-- hack iOS CSS :active style -->
7+
<body ontouchstart="">
8+
9+
{% include nav.html %}
10+
{% include search.html %}
11+
12+
{{ content }}
13+
14+
{% include footer.html %}
15+
16+
<!-- Back to Top Button -->
17+
<div class="back-to-top" id="back-to-top" onclick="scrollToTop()">
18+
<i class="fa fa-chevron-up"></i>
19+
</div>
20+
21+
<!-- Floating Action Menu -->
22+
<div class="floating-menu" id="floating-menu">
23+
<div class="floating-menu-toggle" onclick="toggleFloatingMenu()">
24+
<i class="fa fa-plus"></i>
25+
</div>
26+
<div class="floating-menu-items">
27+
<div class="floating-menu-item" onclick="openSearch()" title="搜索">
28+
<i class="fa fa-search"></i>
29+
</div>
30+
<div class="floating-menu-item" onclick="toggleDarkMode()" title="切换主题">
31+
<i class="fa fa-moon-o"></i>
32+
</div>
33+
<div class="floating-menu-item" onclick="printPage()" title="打印页面">
34+
<i class="fa fa-print"></i>
35+
</div>
36+
</div>
37+
</div>
38+
39+
40+
<!-- Image to hack wechat -->
41+
<img src="/img/icon_wechat.png" width="0" height="0" />
42+
<!-- Migrate from head to bottom, no longer block render and still work -->
43+
44+
</body>
45+
46+
</html>

0 commit comments

Comments
 (0)