Author: Ren Jiale

This article is produced by a member of YFE, please respect the original, please contact the public account (ID: yuewen_YFE) for authorization to reprint, and indicate the author, source and link.

Difficult to use or posture?

The design guidelines for Google AMP are unabashedly indicative of its core beliefs, acknowledging that it’s not developer friendly from the start.

“Webnovel M station” as the first domestic AMP technology products “about AMP, what does Webnovel do? One, the conclusion created significantly improved performance figures, and in the process, as Google’s core point of view stated, the development experience was very poor. Recently, Webnovel’s new product “Ficool M Station” for African users has taken AMP to the Next level and found a new pose to use AMP – “Next. Js + AMP + Preact”.

Start the whitewash – start with new projects

Ficool m stand

As Webnovel’s African site, it not only covers web channels, but also preinstalls its lightweight APP packaged with The help of Google TWA technology on Android Go mobile phones, which has strict requirements on APP memory and CPU usage. It has been successfully stored. At present, most of the Ficool M site pages are not included in Google search engine. Please share with us the actual results and the advanced optimization we made on the server side.

Why AMP?

Rather than “What is Ficool M station?” “Again, Why AMP?

Inspired by a speech

One of the most impressive presentations at this year’s AMP Conf was given by an Iraqi boy.

“No Poser, No Internet, No support: How AMP Bridges the App Gap in Iraq and Other war-impacked Region”

In countries suffering from war and backward network conditions, they chose AMP and filled the gap in APP experience and compatibility step by step with a series of components and optimization schemes provided by AMP, thus establishing a bridge between APP and a group of backward users that they had voluntarily given up.

We at home enjoy 4G every day and may one day enjoy 5G, it’s hard to imagine what our brothers in Africa are enduring with the Internet conditions… Our product finally had the opportunity to go to Kenya in Africa, and brought back some “frontline” news: “The Internet speed there is not as bad as expected, but 3G network is widely used and the speed is limited, and the mobile network package is much more expensive than in China.”

  • “Bandwidth is expensive”
  • “Slow Connection”
  • “Webnovel M station” was a success on AMP

These three points were enough to advance the idea of a full AMP in Ficool M, but we also took a niche AMP route – “Next. Js + AMP + Preact”.

The best position for whitewashing

Next.js + AMP + Preact

Armed with the lessons of “Webnovel M Station”, we set aside time to do a lot of preliminary research and set some goals:

  1. The development process should be more efficient
  2. High maintainability of code later
  3. Focus on the developer mind: Try to use some of the existing mainstream technologies and move away from the old development model

Finally get Next. Js + AMP + Preact, sounds a little bit more cool than AMP + HTML? This is actually a very few people have tried the AMP development form, in the development of the oppression of the time to go wrong the next step will be lost! Its process mining pits countless, we might as well look at what we have experienced the course.

2 course mining pit

1, From HTML “hard” to React

Review the old way of developing AMP for “Webnovel M Stations” : introduce AMP components directly into HTML, and write AMP pages as you develop HTML – don’t stand it!

In fact, Next. Js has supported AMP development since version 8.1, which means that AMP pages can be developed directly in React.

Smoke components

The old method of “Figure 1” is difficult to extract components. Although EJS templates can extract parts of template and include them, it is difficult to extract parts of amP-list into components (the template part is uncertain). In React AMP, we can extract it into components and make the amP-list more flexible by adding failed “fallback”, loading “placeholder” and other features “Figure 3”.

“Figure 1: List page – HTML old way development”

“Figure 2: List page – React development”

“Figure 3: List pageamp-listComponent-react”

Also, it’s difficult to get the server-side render (straight out) and asynchronous render templates consistent in the old development model because the HTML straight out “EJS template” syntax is very different from the AMP “Mustache Template” syntax. However, in React AMP we can:

For example, the

component in “Figure 2”, where the straight out part is the normal props, and the template part of the AMp-list just needs to pass values using the mustache template syntax {{bookId}},

also achieves reuse in both scenarios.

Writing style

Going back to the old way of development: Styles must be inline within the

Under the new development process, we just need to expand the webpack configuration in next. Config. js: Incorporating the Sass-loader and the built-in soft-Jsx “Figure 4” of next.js, next.js will directly inline the compiled CSS to “Figure 5” in the

“Figure 4: Compiling CSS-related configurations in Next-config.js”

“Figure 5: Introducing styles into components”

Conclusion:

1. Use React to develop AMP pages, easier component extraction.

2. The logic of the page is more maintainable and consistent than verbose HTML code. “Single React style vs. HTML + EJS + Mustache”.

3. Styles are easier to write and development styles are in line with current trends.

2, AMP page wing –amp-script

In the first phase we implemented AMP development with React happily, but there were limitations: The React lifecycle functions didn’t work, and all custom JS interactions weren’t implemented (AMP didn’t allow us to introduce our own JavaScript).

Good news! AMP released amP-Script in mid-April this year, with which we can write our own scripts! Of course, it has some limitations: size limit (uncompressed 150KB), quantity limit (only 1 amp-script per page) and API limit… Regardless of the limitations, we need to use this capability in order to achieve more complex interactions.

amp-scriptUnconventional usage – Use Preact

The AMP AMP demo is mostly written in native Javascript. In our React AMP project, we didn’t want to maintain two styles of code, so we explored the possibility of developing AMP Script in React.

The first is to solve the size constraint:

“Each frame source code uncompressed size”

size ( uncompressed ) Amp-script remaining space
React 110kb 150 – 110 = 40kb
Preact 8.2 KB 150-8.2 = 141.8 KB

“Figure 6: React vs Preact in amp-script”

The React source code was 110kb, which would have been 40kb for our own script, so we opted for Preact, a lightweight version of React, which maintained the React development style and controlled the size of the amp script.

Webpack implementationamp-scriptCompile & package

The introduction method of the amp-script is different from that of the React component as shown in Figure 7 and Figure 8. The amp-script component must have a SRC attribute, whose value is the url (absolute address) of the script file you import. We need to make sure that the script is the final packaged script, at which point we will no doubt use WebPack for dependency analysis and packaging.

“Figure 8: How amP-script introduces scripts”

We rewrote a separate webpack configuration “webpack.amp. Config” for amp-Script packaging to make the compilation and packaging process more simple, and try not to confuse the configuration items of Next-config.js.

thiswebpack.amp.configTarget: Dependency analysis of the target script, which is eventually compiled and packaged by Babel into the ES5 script we need (which is the script ultimately referenced by AMP-Script).

This function is a basic function of Webpack and can be used as demo on webpack’s official website. See Figure 9 for key configuration items, where getAllAmpScriptEntries() obtains the paths of all amp-script scripts to be compiled. The resulting script is stored in the static resources folder hosted by next.js./static.

“Figure 9: Highlights of the AMP-script Webpack configuration item”

amp-scriptThe development approach is settled

At this point, we can enjoy the Preact version of amP-Script normally. For simple DOM manipulation, we can put the DOM to be manipulated in the AMp-script tag and fetch the element through the ID selector, but since we use Preact, we recommend: The DOM that needs to be manipulated is rendered solely by the Preact script referenced by amp-script.

For example, the blue bottom bar in “Figure 10” involves the following interactions: click to display confirm popup, request the back end to perform relevant operations (add/remove bookshelf), and display the front end after the interface returns successfully. The interaction of common pages is nothing more than this, and the specific implementation idea is as follows: The React AMP page creates an empty div container with an ID, uses Preact’s render method to render the bottom bar component, and performs events binding, setState updates, and UI updates directly in Preact.

“Figure 10: Details page bottom bar rendered with AMp-script script”

amp-scriptScript CDN is changed

CDN is a way to reduce the strain on the server and respond quickly to users, so all JavaScript resources should be on CDN, and amp-Script is no exception.

The packaging and compilation process of amp-script is independent of that of Next. Js, but when we package the Next script, the fusion of the two separate processes is inevitable. We hope that after executing the build command, the SRC address of amp-script will be replaced by the CDN domain name. At the same time, the amp-script file name will also add md5 code… Come on, next. Config.js!

Amp-script SRC path replacement + file name MD5, this requirement is basically the same as the introduction of most pictures, so with webpack file-loader can achieve “Figure 11”.

“Figure 11: File-loader replacing the amp-script path”

To avoid errors, it is recommended that test matches only the amp-script script. In addition, publicPath must be distinguished between local and online to ensure that the local can reference the amp-script script (the local can still access the scripts in the /static/ path). To facilitate the use of file-loader, the reference mode of the amp-script script should be replaced with the require() method reference in the AMP page.

A set of processes down, completely solve the amP-script script path replacement + file name plus MD5 requirements.

amp-scriptScript cross domain problem solved perfectly

At this point, seeing amP-Script get the CDN treatment and the Next service take some of the pressure off, the cross-domain error “Figure 12” pops up.

This cross-domain problem is an exception thrown by a set of security policies of amp-script itself. Please refer to “Figure 13” for official explanation. Roughly, it means that if the amp-script script quoted by us is different from the page URL domain name, it needs to be in the meta tag of each page. Add the hash code corresponding to amp-script-src, which is unique for each script based on the Content of the script and the Content Security Policy “CSP”.

“Figure 12: AmP-script cross-domain error”

“Figure 13: AMP-script Security Policy”

Fortunately, AMP official also provides the CSP hash code generation tool @ampProject/Toolboxer-script-Csp, so our initial thinking has been settled:

  1. Develop webPack custom plugin, specific function: get compiledamp-scriptScript to generate hash code files in the same directory.
  2. Add a meta tag to each AMP page, and its content is the hash code file introduced.
  3. Next, js configurationraw-loaderTo replace the content in the meta tag with the hash Code file content.

Step 1: Webpack a custom plugin

This plugin has a single function and is easy to write. Please refer to “Figure 14” below. The key point is to obtain the compiled amp-script content, generate hash code, and store it in the hash. TXT file in the same path. You can finally import and instantiate this plug-in in plugins in the WebPack configuration file.

“Figure 14: WebPack custom Plugin”

Step 2 & Step 3: next.config.jsconfigurationraw-loaderThe AMP page introduces hash code files

The changes on the page are as follows:

“Figure 15: Introducing hash code file and adding meta tags to AMP page”

You also need to configure the raw-loader in next. Config. js to replace the content in the meta tag.

“Figure 16: Raw-loader configuration in next-config. js”

Cross domain problem solved!

Conclusion: Achievedamp-scriptReact mode development process. With the ability to customize scripts, AMP page development is more flexible.

The last layer of blessing

At this point, the development process will inevitably face some forms of interaction that can not be implemented by AMP Script, such interaction really challenges the design principles of AMP, in other words, if the form of interaction can be made to follow the SPECIFICATION of AMP, the development experience will be smooth!

AMP Design Principles

The AMP design principles do not specify how you will design and implement it, but the core principle must be: only do what is good for the user experience! There are two principles that are instructive to us as developers. “Figure 17”

“Figure 17: AMP Design Principles 2”

4. Each level involved in development should have clear responsibilities and solve problems at the right level.

5. Only do things that make your web page faster.

Rear logic

“All aspects of development should be accountable and solve problems at the right level” – if the logic is user friendly on the back end, don’t put all the logic on the front end just because it’s easy to implement.

Here are some scenarios to consider:

  1. You need to useamp-mustacheComponent (weak logic template language, does not support operations, re and some complex judgment logic), a lot of logic should be tried to let the backend students implement, for example: search page keyword highlighting logic “Figure 18”, the backend can directly return HTML elements with highlighted style.
  2. For long list pages, pull-down loading can be usedamp-listComponent, but this requires a backend helper to add a field to return the request URL for the next page with parameters, and to make logical changes to determine if it is the last page. Of course the front end can also be usedamp-scriptImplement pull-down loading, but the effect is far less than a direct referenceamp-listOk, so logical postposition is necessary.

“Figure 18: Search page keywords highlighted in blue”

Embarrassing scenarios that AMP can’t implement

Only do things that make web pages faster – AMP does not recommend introducing any components or features that will slow animation frame rates or limit page loading speed.

My understanding is that if you can’t guarantee that you’re writing components that are AMP compliant, use the components that AMP provides. I have to throw cold water on the fact that amp-Script really has a lot of limitations. It doesn’t implement all of the interaction logic, it just opens a very small window for developers. There are only two options:

  1. Adjust requirements and design drafts.
  2. Compromise, don’t use AMP.

All departments of the project team follow consistent specifications

If you read this, it might not be so bad, because you can prevent it. Here’s how.

The design principles of AMP have a good intention:

“These design principles are meant to guide the ongoing design and development of AMP. They should help us make Internally consistent decisions.”

(Let’s reach a unanimous decision)

“We” refers not only to the front-end developers of THE AMP page, but also to everyone involved in the project. This is a very important starting point, which is also the main concept mentioned in the “AMP Core Mindset” of the AMP 2019 CONF.

Products need to understand the limitations of AMP and avoid arbitrary requirements design; Design also needs to understand AMP component specifications, thereby saving design costs, producing components that can be realized with AMP technology, and ultimately avoiding the increase in development costs. For example, the image rotation component AMP itself has been well implemented “Figure 19”, if there is no special design requirements, there is no need to design a new style.

“Figure 19: AMP-Carousel”

From the perspective of development, the front end can clearly see the AMP components that can be used on the page after getting the design draft. For the backend students, they can know what fields should be added and what logic adjustments should be made at the early stage of development.

conclusion

Js + AMP + Preact after a rough ride, Next. Js + AMP + Preact’s new AMP trial ended in Ficool M. While the combination of “Next. Js + AMP + Preact” is rarely used on other non-AMP projects, every pit mentioned in this article will be difficult for other teams to avoid, so hopefully this article will save you some of the detour.

Finally, the consensus of the team is very important. In addition to saving communication costs, we all know what to do and why to do it. We are achieving the same goal — better user experience.

For more sharing, please pay attention to the Official account of China Literature Front End Team:

To learn more about the team, check it outwebsiteOh ~ 😄