- Notifications
You must be signed in to change notification settings - Fork1
Testing mime type settings for .ttf files on GAE
License
mdxs/test-ttf-on-gae
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Usemime_type: font/ttf
for staticTrueType Font (.ttf) files in theapp.yaml
to benefit from lower bandwidth usage and faster load times.This project provides anexample to use and a detailedprocedure to test it.
Python based project to test the currentGoogle App Engine (GAE) serverimplementation when handling staticTrueType Font (.ttf) files. The defaultapproach of the SDK, to declare such files asapplication/octet-stream
on upload, may not provide the best results for app owners and users.
It appears that an explicit declaration of themime type for .ttf filesasfont/ttf
can reduce bandwidth usage (for the app owner) and decreaseload times (for users). With this mime type, and only this mime type itseems, the GAEwill use gzip compression on .ttf files.
Doing so also addresses"Could not guess mimetype for .ttf files" warningswhile uploading your application using the Python SDK basedappcfg.py
tool (at least on some platforms, as reported inIssue 6183).
While other mime types for .ttf are suggested on the internet, testingshows thatonly usingmime_type: font/ttf
in theapp.yaml
willproduce the gains in bandwidth usage and load times.
Interestingly enough, mime types starting withfont/
are not eventechnically valid, whileapplication/x-*
is the valid format fornon-standard mime types (as fonts have no standard).[1]
[1] | Comment #3 to Issue 6183 byjchu...@gmail.com |
BEWARE: These findings are subject to change; as this appears to bean implementation detail of the GAE servers. Your milage may vary, whichis why this project provides a detailed procedure; so that you can checkthis yourself. Status: at the time of writing, 10 April 2014, informationprovided here is still valid (and it also was in 2013-Q4).
Seecomment #3 to Issue 6183 for the very clear hint that helped developthis test project.
So, thank youjchu...@gmail.com
!
Furthermore, most of the source code and files in this project are fromGoogle'sgetting-started-with-flask example. Therefore, theirLICENSEapplies to the source code of this project (unless specified otherwise,as is the case for the "ubuntu.ttf" file which has a differentFONT_LICENSE).
Create a virtual machine (for example withVMware)and installXubuntu 13.10 Desktop i386 into it, using adownloadedxubuntu-13.10-desktop-i386.iso
fileas installation media and the following parameters:
- Name:
test
- With the following virtual hardware suggested:
- Memory: 1024 MB
- Virtual Processors: 1
- Hard Disk (SCSI 0:0): 10.0 GB
- CD/DVD (IDE 1:0): Auto-detect
- Ethernet: NAT
- USB Controller: Present
- Audio: Auto detect
- Printer: Present
- Display: Auto detect
- And an initial user like:
- Account:
test
- Password:
********
- Account:
Boot it up and update/upgrade to the latest packages:
sudo apt-get updatesudo apt-get upgrade
Wheregit
will be needed to get the project from GitHub,theapache2-utils
includeab
which is used to measure;andpython-dev
helps in the Python development environment.
sudo apt-get install gitsudo apt-get install apache2-utilssudo apt-get install python-dev
3. Installvirtualenvwrapper
This includespip
andvirtualenv
, which together willhelp you protect your configuration, by providing an isolateddevelopment environment for this test project.
sudo apt-get install virtualenvwrapper# note that use on Xubuntu (Debian) is slightly different# as compared to the docs... it is even easier for Xubuntuless /usr/share/doc/virtualenvwrapper/README.Debian
And upgrade it (in this order), to get latest versions.
sudo pip install virtualenvwrapper --upgrade
4. Get theGoogle App Engine SDK for Python
Modify the version number as needed to the latest release.
cd ~/Downloadscurl -O https://commondatastorage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.2.zipunzip google_appengine_1.9.2.zipmv google_appengine ~/
When you opt for a different structure, modify subsequentinstructions accordingly.
cd ~mkdir devmkdir dev/gh
Obtain the code and prepare the development environment.
cd ~/dev/gh# change "mdxs" to your GitHub account if you cloned the projectgit clone git@github.com:mdxs/test-ttf-on-gae.git# prepare a virtual environment (with an isolated Python)mkvirtualenv test-ttf-on-gaecdvirtualenv# the following will put the GAE SDK on the path in the virtualenvecho "export PATH=\$PATH:~/google_appengine:" >> bin/postactivateecho "cd ~/dev/gh/test-ttf-on-gae" >> bin/postactivate
Use one console window to run your app in the development web server:
# switch to the virtualenv (and cd into the project)workon test-ttf-on-gaedev_appserver.py main# keep this console window running...
Start another console window, and check local delivery of static files:
cd ~mkdir tempcd tempwget -S http://localhost:8080/p/FONT_LICENSEwget -S http://localhost:8080/p/ubuntu.ttfdu -b ubuntu.ttf# probably returns: "70220 ubuntu.ttf"
Note that the files thus obtained equal the same files foundinsidemain/lib/werkzeug/debug/shared/
folder of the project.
So far, this was to prepare the test project and to check that itworks locally; using the development application server... Whichwillnot attempt to compress any files.
You can confirm this usingab
, which should be provided someparameters to present itself as a browser/client that will acceptcompressed content from the server:
cd ~/tempab -n 1 \ -H "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0" \ -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ -H "Accept-Language: en-US,en;q=0.5" \ -H "Accept-Encoding: gzip, deflate" \ http://localhost:8080/p/ubuntu.ttf
Notice the"Document Length: 70220 bytes"
in the output, whichequals the"du -b"
output seen above... it isnot compressed locally.
First create your new test application using the formonhttps://appengine.google.com/start/createapp
Note in particular the"Application Identifier" (further:App ID)which will need to be unique; and you may want to use something witha"test" pre- or postfix to avoid spoiling good identifiers...
BEWARE: Once anApp ID is reserved, regardless of whether the appis deleted later, it cannot be taken for a new application.
Modify theapplication: test-ttf-on-gae
line inmain/app.yaml
to use theApp ID just created.
Note that you may need to authenticate and authorize (typically ina browser instance) when executing the following for the first time.
workon test-ttf-on-gaeappcfg.py --oauth2 update main
Finally we reach the point in which we can prove that static.ttf
filescan be compressed when hosted by the Google App Engine (GAE) servers.
cd ~/tempab -n 1 \ -H "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0" \ -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ -H "Accept-Language: en-US,en;q=0.5" \ -H "Accept-Encoding: gzip, deflate" \ http://YOUR-APP-ID.appspot.com/p/ubuntu.ttf
Notice the"Document Length: 42567 bytes"
in the output, which isalmost 40% smaller (namely 70220 - 42567 = 27653 bytes smaller) thanthe actual file; obviously due to compression by the GAE servers.
Also note the"Total transferred:"
bytes for comparison with furthertesting, indicating total bytes transferred in the whole process.
Change themain/app.yaml
file and repeat steps 9 and 10 above to seethe effect. The following changes are provided as examples:
Comment out the special case handling for
.ttf
files:...handlers:## Special case for .ttf files needing specific mime_type## to enjoy gzip encoding/compression from GAE hosting.## Order is important: this must precede "/p/" static_dir# - url: /p/(.*\.ttf)# static_files: static/\1# upload: static/(.*\.ttf)# mime_type: font/ttf# expiration: 1000d- url: /p/ static_dir: static/ expiration: 1000d- url: /.* script: main.app...
You probably notice some"Could not guess mimetype warnings for .ttf files"warnings/notifications while uploading. Though perhaps some Operating Systemsdetect and provide a mime type to the
appcfg.py
process; as some Mac OS Xusers reported they didn't see these messages.I have seen for example the following:
...04:27 PM Scanning files on local disk.Could not guess mimetype for static/FONT_LICENSE. Using application/octet-stream.Could not guess mimetype for static/ubuntu.ttf. Using application/octet-stream.Could not guess mimetype for static/FONT_LICENSE. Using application/octet-stream.Could not guess mimetype for static/ubuntu.ttf. Using application/octet-stream.04:27 PM Cloning 2 static files....
Which doesn't seem to hinder the actual deployment.
It does affect the result of step 10 above though, dropping any compression bythe GAE servers: with
ab
showing"Document Length: 70220 bytes"
and amuch higher"Total transferred:"
bytes count for theubuntu.ttf
file.Use another mime type for
.ttf
files:...handlers:# Special case for .ttf files needing specific mime_type# to enjoy gzip encoding/compression from GAE hosting.# Order is important: this must precede "/p/" static_dir- url: /p/(.*\.ttf) static_files: static/\1 upload: static/(.*\.ttf) mime_type: application/x-font-ttf expiration: 1000d- url: /p/ static_dir: static/ expiration: 1000d- url: /.* script: main.app...
Which will use
application/x-font-ttf
for theubuntu.ttf
file,suppressing the related warnings in the upload. But also (silently) droppingthe compression by GAE servers (as you can see in theab
output whenrepeating step 10).wget -S http://YOUR-APP-ID.appspot.com/p/ubuntu.ttf
Will show you that it is using
Content-Type: application/x-font-ttf
andthat there are more differences compared to awget
when usingfont/ttf
is being used (most notably the transfer rate and "Transfer-Encoding").Feel free to also try other variations, such as: "font/x-font-ttf","font/truetype", and "application/x-font-truetype".
In step 10, you can also try modifying the
ab
command toab -n 100 ...
andab -n 100 -c 10 ...
(for concurrency) to perform more request; andthus get better averages.