This chapter is by @Maplor
Book connected to wen
In the last article I wrote code in cloud Habitat (ii) : 3D immersive Experience, we introduced the technical analysis of 3d immersive exhibition hall and the realization of transition animation. Today is the final article in the series, “Excelsior”, which introduces the experience of building seconds, embedding statistics, and optimizing social sharing.
>> Address of hybrid Cloud Experience Camp
Create a second on experience
A visitor’s first impression of a Web page must be how quickly it opens. With each additional second of waiting time, the attrition rate increases exponentially. So opening speed is the point we need to optimize the most.
User access to a site is divided into two processes: loading and rendering. Our page is hosted on aliyun unified external platform, and all static resources are placed on CDN. The loading speed of resources is fast enough, so we will focus on optimizing the rendering part.
measure
First of all, we need to measure the performance of the web page. There are actually a lot of data on the web. Here we use the following two:
- Largest Contentful Paint (LCP) The Largest part of the content has been rendered.
- TTI (Time to Interactive) Indicates the user interaction Time. The lower the value, the better.
This is the time from the beginning of the user’s access to the time when the user sees the content on the screen, and the time when the user can interact.
Look at the code
This project uses React rendering. The default Html has only an empty div, and everything is added dynamically in Js. This will result in increased white screen time, and content will not be rendered until the script is finished running. The LCP’s time has increased.
At the same time, a lot of pictures/videos are used in the project, and a complete content framework can be created only after the materials are loaded. Users can interact with each other for a long time.
In order to improve the above two indicators, we targeted the use of pre-rendering and responsive material two methods.
pre-rendered
SSR is known as a pre-rendering technology, but it requires server support. Due to platform constraints, we ended up using static pre-rendering, which is to write the content you want the user to see first directly into Html.
As the camp is a static display website, we only need one kind of pre-rendered content, namely the frame and loading prompt of the page:
<div id="container">
<! -- prerender -->
<div class="orientation-wrapper">
<div class="page-loading-container">
<div class="page-loading-box">
<img class="page-loading-cube" src="/ /...">Preparation for hybrid cloud experience camp<span><span class="dotting-1">.</span><span class="dotting-2">.</span><span class="dotting-3">.</span></span>
</div>
</div>
</div>
</div>
Copy the code
The end result:
The user can see the feedback of the page after the HTML and global CSS are loaded, reducing the white screen time (LCP). After the script loads, the ReactDom replaces the contents of div#container and completes the normal page rendering.
Responsive material
A responsive feed is one that loads different sizes of feed on different devices according to a set of rules to balance speed and experience.
The biggest material is video, so optimize for video. In chapter 1, we mentioned identifying the operating environment according to UA. Here, based on UA and combined with navigator.connection API, we try to determine whether the current wifi environment is in:
const isMobileRes = isMobile();
const ua = window.navigator.userAgent;
const con = window.navigator.connection;
let showFullVideo = true;
// If wifi connection can be detected on the mobile terminal, use hd version; otherwise, downgrade
if (isMobileRes.phone) {
showFullVideo = false;
// Some browser uAs have NetType attributes
if(/NetType/.test(ua)) {
const type = ua.match(/NetType/(\S*)/);
if (type && type[1] && type[1].toLowerCase() === 'wifi') {
showFullVideo = true; }}else if(con){
const network = con.type || con.effectiveType;
if (network === 'wifi' || network === '2') {
showFullVideo = true; }}}Copy the code
If the operating environment is PC or mobile terminal that can be judged to be wifi connected, hd video resources will be loaded. In other cases, compact video resources with smaller volume will be loaded:
<video src={`//domain/home_${showFullVideo ? 'pc' : 'mobile'}.mp4`} / >Copy the code
Corresponding to different definition of video:
You can see that loading thin video resources can save a lot of traffic and improve the loading speed.
The final result
Finally, we take a look at the load time chart of the whole site, LCP is about 1 second, the overall access speed is still very good.
Business buried point statistics
In order to be able to count the information users visit the site, we increase the business buried for the site. The choice here is the Web of friends. There are no react wrappers available on NPM, so we wrapped a uWeb utility function according to the official document:
// Initialize the alliance
function init() {
const script = document.createElement('script');
script.src = `https://s4.cnzz.com/z_stat.php?id=${siteId}&web_id=${siteId}`;
script.onload = () = > {
if (window._czc) {
// Turn off the default dot
window._czc.push(['_setAutoPageview'.false]); }};document.body.appendChild(script);
}
/ * * *@param {string} Content_url URL of the customized virtual PV page Enter the relative path starting with a slash (/). The system will automatically complete the domain name *@param {string} Referer_url Specifies the source URL of the interviewed page. You are advised to enter the parent page of the asynchronous loading page. If this parameter is not specified, the incoming path is calculated according to the incoming path of the parent page. Fill in "blank", i.e. "", the incoming path will be calculated as "Enter url or bookmark directly". * * /
function pv(content_url: string, referer_url? :string) {
const res = ['_trackPageview'.`${baseDomain}${content_url}`];
if(referer_url ! = =undefined) {
res.push(referer_url);
}
window._czc && window._czc.push(res);
}
/ * * *@param Categories indicate who the event happened to, such as "video," "novel," "wheel display," and so on. *@param Action represents the actions that visitors take to interact with elements, such as "play", "favorites", "flip", and so on. *@param Label is used to describe events in more detail, such as which video, which novel. *@param Value Indicates the score value, loading duration of the event, and price of the order event. *@param Nodeid Specifies the DIV element ID of the event element. * * /
export function event(
category: string,
action: string, label? :string, value? :number, nodeid? :string.) {
const res: any[] = ['_trackEvent', category, action];
if(label ! = =undefined) {
res.push(label);
}
if(value ! = =undefined) {
res.push(value);
}
if(nodeid ! = =undefined) {
res.push(nodeid);
}
window._czc && window._czc.push(res);
}
Copy the code
We simply call init when we apply initialization, pv when we switch routes, and event where we need to fire events:
// Listen for route hops
history.listen((location, action) = > {
pv(location.pathname);
});
// Click to trigger the event
<Link
to="/xxx"
onClick={()= >{event(' home ', 'start exploring '); }} > Open exploration</Link>
Copy the code
Social Sharing optimization
After the above optimization, our page has been relatively perfect, and we thought it could be successfully promoted online, but in the test, we found that the effect displayed in the chat software is very bad:
After a search, we found that social software can set the content of the card to be shared by the Open Graph Protocol:
The Open Graph Protocol itself is a set of Metatags specifications for annotating the types of pages and describing the content of pages. Announced by Facebook at its F8 2010 conference.
The OG tag is a new HTTP header. Adding this protocol to a page makes it a “rich media object”, indicating that content can be referenced by other social sites, etc.
Details can be found at ogp.me/
At present, most social software supports OGP when sharing (so far, wechat Android version does not support it), so we added the following content in THE HTML meta:
<! -- Open Graph data -->
<meta property="og:title" content="Make hybrid Cloud" Visible and tangible - Ali Cloud Hybrid Cloud Experience Camp" />
<meta property="og:url" content="https://apsara-stack.aliyun.com/digital-twin/experience" />
<meta property="og:image" content="https://..." />
<meta property="og:description" content="Online interactive experience camp of full product technical capabilities 25+ benchmark customer cases 20+ detailed product introduction 15+ real environment experience 10+ industry application scenarios 5 live dynamic demonstration 40+ full stack solutions to quickly understand Aliyun hybrid cloud" />
Copy the code
There are a few other environments where you can use the ItemProp property to set what to fetch:
<meta itemprop="name" content="Make hybrid Cloud" Visible and tangible - Ali Cloud Hybrid Cloud Experience Camp">
<meta itemprop="image" content="https://...">
Copy the code
Finally, wechat said that I would grab the content and picture of the first div on the page, and then combined with SEO processing, add this paragraph at the beginning of the body tag:
<! -- SEO -->
<div style="display: none;">
<h1>Alibaba Cloud Hybrid Cloud</h1>Alibaba Cloud Hybrid Cloud...<img src="https://..." />
</div>
Copy the code
Finally, social sharing cards are what we want
// 2021-12-31 test, the card shared in wechat is back to the bad state…
Write in the last
For a variety of reasons, this article was posted so long ago that it was released before the end of the year. I would like to wish you all a happy New Year, progress in school and success at work. We’ll see you next year at 🎉 🎉 🎉 ~
Like the article friends remember to continue to pay attention to us oh 👇 ~